home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / v / vista / c / window < prev    next >
Text File  |  1996-02-01  |  25KB  |  1,083 lines

  1. // **************************************************************************
  2. //                     Copyright 1996 David Allison
  3. //
  4. //             VV    VV    IIIIII     SSSSS     TTTTTT       AA
  5. //             VV    VV      II      SS           TT       AA  AA
  6. //             VV    VV      II        SSSS       TT      AA    AA
  7. //              VV  VV       II           SS      TT      AAAAAAAA
  8. //                VV       IIIIII     SSSS        TT      AA    AA
  9. //
  10. //                    MULTI-THREADED C++ WIMP CLASS LIBRARY
  11. //                                for RISC OS
  12. // **************************************************************************
  13. //
  14. //             P U B L I C    D O M A I N    L I C E N C E
  15. //             -------------------------------------------
  16. //
  17. //     This library is copyright. You may not sell the library for
  18. //     profit, but you may sell products which use it providing
  19. //     those products are presented as executable code and are not
  20. //     libraries themselves.  The library is supplied without any
  21. //     warranty and the copyright owner cannot be held responsible for
  22. //     damage resulting from failure of any part of this library.
  23. //
  24. //          See the User Manual for details of the licence.
  25. //
  26. // *************************************************************************
  27.  
  28. //
  29. // c.window
  30. //
  31.  
  32. #include "Vista:task.h"
  33. #include "Vista:window.h"
  34. #include <swis.h>
  35. #include <kernel.h>
  36. #include <stdarg.h>
  37. #include <stdio.h>
  38.  
  39. Window::Window (Task *tsk, char *tname, char *m)
  40.    {
  41.    void *defn ;
  42.    _kernel_swi_regs r ;
  43.    _kernel_oserror *e ;
  44.    int block[9] ;
  45.  
  46.    task = tsk ;
  47.    //t->print ("creating window, tsk = %x, name = %s\n",tsk,tname) ;
  48.    if ((defn = tsk->find_template (tname)) == NULL)
  49.       throw ("No such Template") ;
  50.    r.r[1] = (int)defn ;
  51.    if ((e = _kernel_swi (Wimp_CreateWindow, &r, &r)) != NULL)
  52.       throw (e) ;
  53.    handle = r.r[0] ;
  54.    template_data = defn ;
  55.    block[0] = handle ;
  56.    r.r[1] = (int)block ;
  57.    if ((e = _kernel_swi (Wimp_GetWindowState, &r, &r)) != NULL)
  58.       throw (e) ;
  59.    x0 = block[1] ;
  60.    y0 = block[2] ;
  61.    x1 = block[3] ;
  62.    y1 = block[4] ;
  63.    scx = block[5] ;
  64.    scy = block[6] ;
  65.    prev = NULL ;
  66.    next = NULL ;
  67.    //::print ("window handle = %x",handle) ;
  68.    tsk->add_window(this) ;            // add the window to the task
  69.    is_open = FALSE ;
  70.    icons = NULL ;
  71.    last_icon = NULL ;
  72.    objects = NULL ;
  73.    last_object = NULL ;
  74.    if (m == NULL)
  75.       default_menu = NULL ;
  76.    else
  77.       {
  78.       default_menu = tsk->find_menu (m) ;
  79.       if (default_menu == NULL)
  80.       throw ("Unknown menu") ;
  81.       }
  82.    sub_windows = NULL ;           // no subwindows
  83.    parent = NULL ;                // no parent
  84.    tracker = NULL ;
  85.    deleting = false ;
  86.    }
  87.  
  88. Window::Window (Window *w, char *tname, int anchor, char *m)
  89.    {
  90.    void *defn ;
  91.    _kernel_swi_regs r ;
  92.    _kernel_oserror *e ;
  93.    int block[9] ;
  94.  
  95. //   ::print ("creating sub window, name = %s\n",tname) ;
  96.    this->anchor = anchor ;
  97.    task = w->task ;
  98.    if ((defn = task->find_template (tname)) == NULL)
  99.       throw ("No such Template") ;
  100.    r.r[1] = (int)defn ;
  101.    if ((e = _kernel_swi (Wimp_CreateWindow, &r, &r)) != NULL)
  102.       throw (e) ;
  103.    handle = r.r[0] ;
  104.    template_data = defn ;
  105.    block[0] = handle ;
  106.    r.r[1] = (int)block ;
  107.    if ((e = _kernel_swi (Wimp_GetWindowState, &r, &r)) != NULL)
  108.       throw (e) ;
  109. // if the window is anchored then the coords are relative to the top of the parent
  110. // window, otherwise they are relative to the bottom
  111.    switch (anchor)
  112.       {
  113.       case A_NONE:
  114.       case A_BOTTOM:
  115.          x0 = block[1] - w->x0 ;
  116.          y0 = block[2] - w->y0 ;
  117.          x1 = block[3] - w->x0 ;
  118.          y1 = block[4] - w->y0 ;
  119.          break ;
  120.       case A_LEFT:
  121.       case A_TOP:
  122.          x0 = block[1] - w->x0 ;
  123.          y0 = block[2] - w->y1 ;
  124.          x1 = block[3] - w->x0 ;
  125.          y1 = block[4] - w->y1 ;
  126.          break ;
  127.       case A_RIGHT:
  128.          x0 = block[1] - w->x1 ;
  129.          y0 = block[2] - w->y1 ;
  130.          x1 = block[3] - w->x1 ;
  131.          y1 = block[4] - w->y1 ;
  132.          break ;
  133.       }
  134.  
  135.    scx = block[5] ;
  136.    scy = block[6] ;
  137.  
  138.  
  139.    //::print ("window handle = %x",handle) ;
  140.    prev = NULL ;
  141.    next = NULL ;
  142.    w->add_sub_window(this) ;            // add the window to the task
  143.    is_open = FALSE ;
  144.    icons = NULL ;
  145.    last_icon = NULL ;
  146.    objects = NULL ;
  147.    last_object = NULL ;
  148.    if (m == NULL)
  149.       default_menu = NULL ;
  150.    else
  151.       {
  152.       default_menu = task->find_menu (m) ;
  153.       if (default_menu == NULL)
  154.       throw ("Unknown menu") ;
  155.       }
  156.    sub_windows = NULL ;           // no subwindows
  157.    tracker = NULL ;
  158.    deleting = false ;
  159.    }
  160.  
  161. Window::~Window()
  162.    {
  163.    Icon *ni ;
  164.    Window *nw ;
  165.    Object *no ;
  166.  
  167.    deleting = true ;
  168.    if (is_open)
  169.       do_close() ;
  170.    for (Icon *i = icons ; i != NULL ; i = ni)
  171.       {
  172.       ni = i->next ;
  173.       delete i ;
  174.       }
  175.    for (Window *w = sub_windows ; w != NULL ; w = nw)
  176.       {
  177.       nw = w->next ;
  178.       delete w ;
  179.       }
  180.    for (Object *o = objects ; o != NULL ; o = no)
  181.       {
  182.       no = o->next ;
  183.       delete o ;
  184.       }
  185.    task->remove_window (this) ;
  186.    if (parent != NULL)
  187.       parent->remove_sub_window (this) ;
  188.    if (tracker != NULL)
  189.       delete tracker ;
  190.    task->free_template(template_data) ;         // free up the definition data
  191.    }
  192.  
  193. //
  194. // get a sub window's x0 coordinate in screen coordinates
  195. //
  196.  
  197. int Window::subx0(Window *sub)
  198.    {
  199.    int myx0 ;                 // my x0 coord
  200.    if (parent != NULL)
  201.       myx0 = parent->subx0(this) ;
  202.    else
  203.       myx0 = x0 ;
  204.    switch (sub->anchor)
  205.       {
  206.       case A_NONE:
  207.       case A_BOTTOM:
  208.       default:
  209.          return myx0 + sub->x0 ;
  210.       case A_LEFT:
  211.       case A_TOP:
  212.          return myx0 + sub->x0 ;
  213.       case A_RIGHT:
  214.          return myx0 + (x1-x0) + sub->x0 ;  // == myx1 + sub->x0
  215.       }
  216.    }
  217.  
  218. //
  219. // get the y1 coordinate for a sub window in screen coordinates
  220. //
  221.  
  222.  
  223. int Window::suby1(Window *sub)
  224.    {
  225.    int myy1 ;                 // my y1 coord
  226.    if (parent != NULL)
  227.       myy1 = parent->suby1(this) ;
  228.    else
  229.       myy1 = y1 ;
  230.    switch (sub->anchor)
  231.       {
  232.       case A_NONE:
  233.       case A_BOTTOM:
  234.       default:
  235.          return myy1 - (y1-y0) + sub->y1 ;   // == myy0 + sub->y1
  236.       case A_LEFT:
  237.       case A_TOP:
  238.          return myy1 + sub->y1 ;
  239.       case A_RIGHT:
  240.          return myy1 + sub->y1 ;
  241.       }
  242.    }
  243.  
  244.  
  245. void Window::add_icon(Icon *i)
  246.    {
  247.    i->next = NULL ;
  248.    if (icons == NULL)
  249.       icons = last_icon = i ;
  250.    else
  251.       {
  252.       last_icon->next = i ;
  253.       i->prev = last_icon ;
  254.       last_icon = i ;
  255.       }
  256.    }
  257.  
  258. void Window::remove_icon (Icon *i)
  259.    {
  260.    if (i->prev == NULL)
  261.       icons = i->next ;
  262.    else
  263.       i->prev->next = i->next ;
  264.    if (i->next == NULL)
  265.       last_icon = i->prev ;
  266.    else
  267.       i->next->prev = i->prev ;
  268.    }
  269.  
  270. void Window::add_object(Object *o)
  271.    {
  272.    Object *obj = objects ;
  273.    while (obj != NULL && obj->priority < o->priority)  // find position
  274.       obj = obj->next ;
  275.    o->next = obj ;
  276.    if (obj == NULL)              // at end of queue
  277.       o->prev = last_object ;
  278.    else
  279.       o->prev = obj->prev ;
  280.    if (o->prev == NULL)
  281.       objects = o ;
  282.    else
  283.       o->prev->next = o ;
  284.    if (o->next == NULL)
  285.       last_object = o ;
  286.    else
  287.       o->next->prev = o ;
  288.    }
  289.  
  290. void Window::remove_object (Object *o)
  291.    {
  292.    if (o->prev == NULL)
  293.       objects = o->next ;
  294.    else
  295.       o->prev->next = o->next ;
  296.    if (o->next == NULL)
  297.       last_object = o->prev ;
  298.    else
  299.       o->next->prev = o->prev ;
  300.    }
  301.  
  302. void Window::add_sub_window (Window *w)
  303.    {
  304.    if (sub_windows == NULL)
  305.       sub_windows = last_sub_window = w ;
  306.    else
  307.       {
  308.       last_sub_window->next = w ;
  309.       w->prev = last_sub_window ;
  310.       last_sub_window = w ;
  311.       }
  312.    w->parent = this ;
  313.    }
  314.  
  315. void Window::remove_sub_window (Window *w)
  316.    {
  317.    if (w->prev == NULL)
  318.       sub_windows = w->next ;
  319.    else
  320.       w->prev->next = w->next ;
  321.    if (w->next == NULL)
  322.       last_sub_window = w->prev ;
  323.    else
  324.       w->next->prev = w->prev ;
  325.    w->parent = NULL ;
  326.    }
  327.  
  328. void Window::do_open(int x0, int y0, int x1, int y1, int scx, int scy, int behind)
  329.    {
  330.    int block[8] ;
  331.    _kernel_swi_regs r ;
  332.    _kernel_oserror *