home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-02-01 | 25.3 KB | 1,052 lines |
- // **************************************************************************
- // Copyright 1996 David Allison
- //
- // VV VV IIIIII SSSSS TTTTTT AA
- // VV VV II SS TT AA AA
- // VV VV II SSSS TT AA AA
- // VV VV II SS TT AAAAAAAA
- // VV IIIIII SSSS TT AA AA
- //
- // MULTI-THREADED C++ WIMP CLASS LIBRARY
- // for RISC OS
- // **************************************************************************
- //
- // P U B L I C D O M A I N L I C E N C E
- // -------------------------------------------
- //
- // This library is copyright. You may not sell the library for
- // profit, but you may sell products which use it providing
- // those products are presented as executable code and are not
- // libraries themselves. The library is supplied without any
- // warranty and the copyright owner cannot be held responsible for
- // damage resulting from failure of any part of this library.
- //
- // See the User Manual for details of the licence.
- //
- // *************************************************************************
-
- #include "Vista:task.h"
- #include "Vista:wins.h"
- #include <kernel.h>
- #include <swis.h>
- #include "icon.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdarg.h>
-
- #ifndef __EASY_C
- #include "Vista:myargs.h"
- #endif
-
- //
- // An IconGrid
- //
-
- // this has a window with a vertical scroll bar and can be resized.
- // It traps the open event from the Wimp and checks the current size
- // of the window. If it can rearrange the icons it will.
- //
-
- IconGrid::IconGrid (Task *task, char *tname, int ticon, char *menu)
- : Window (task, tname, menu)
- {
- init (ticon) ;
- }
-
- IconGrid::IconGrid (Window *w, char *tname, int ticon, char *menu)
- : Window (w, tname, 0, menu)
- {
- init (ticon) ;
- }
-
-
- IconGrid::~IconGrid()
- {
- }
-
- void IconGrid::init (int ticon)
- {
- _kernel_swi_regs r ;
- _kernel_oserror *e ;
- int block[40] ;
-
- template_icon = new Icon (this, ticon) ;
- template_icon->move_to (-1000,1000) ; // move the icon out of sight
- block[0] = handle ;
- block[1] = ticon ;
- r.r[1] = (int)block ;
- if ((e = _kernel_swi (Wimp_GetIconState, &r, &r)) != NULL)
- throw (e) ;
- template_button_type = (Icon::buttontype)((block[6] & 0xf000) >> 12) ;
- Box *box = (Box*)&block[2] ;
- icon_height = box->y1 - box->y0 ;
- icon_width = box->x1 - box->x0 ;
- num_rows = 0 ;
- num_icons = 0 ;
- current_column = 0 ;
- current_row = 0 ;
- num_columns = (x1 - x0 - ICONGRID_LEFT_MARGIN) / (icon_width + ICONGRID_HOR_GAP) ;
- if (num_columns == 0)
- num_columns = 1 ;
- flag_set = NONE ;
- Window::Info *inf = info() ;
- min_height = inf->extent.y1 - inf->extent.y0 ;
- }
-
-
- void IconGrid::set_flag (flags flag)
- {
- #ifndef __EASY_C
- int f = (int)flag_set ;
- f |= (int)flag ;
- flag_set = (flags)f ;
- #else
- flag_set |= (flags)flag ;
- #endif
- }
-
- void IconGrid::clear_flag (flags flag)
- {
- #ifndef __EASY_C
- int f = (int)flag_set ;
- f &= ~(int)flag ;
- flag_set = (flags)f ;
- #else
- flag_set |= (flags)flag ;
- #endif
- }
-
- //
- // add a new icon into the window. This will fill up the window from
- // left to right taking a new row when a row is full.
- //
-
- Icon *IconGrid::insert_icon(char *text, void *ref)
- {
- int x, y ;
-
- x = current_column * (icon_width + ICONGRID_HOR_GAP) + ICONGRID_LEFT_MARGIN ;
- y = current_row * (icon_height + ICONGRID_VERT_GAP) + icon_height +ICONGRID_TOP_MARGIN ;
-
- Icon *icon = new Icon (this, template_icon, x, -y, ref) ;
- Box pos ;
- icon->read_position (pos) ;
- do_redraw (pos.x0, pos.y0, pos.x1, pos.y1) ; // redraw the window
- icon->print (text) ;
- num_icons++ ;
- current_column++ ;
- if (current_column == num_columns)
- {
- current_column = 0 ;
- current_row++ ;
- int new_height = current_row * (icon_height + ICONGRID_VERT_GAP) + icon_height +ICONGRID_TOP_MARGIN ;
- if (new_height > min_height)
- set_height (new_height) ;
- }
- if (flag_set & SORTED)
- sort() ;
- return icon ;
- }
-
- Icon *IconGrid::insert_icon(char *text, char *sprite, void *ref)
- {
- int x, y ;
-
- x = current_column * (icon_width + ICONGRID_HOR_GAP) + ICONGRID_LEFT_MARGIN ;
- y = current_row * (icon_height + ICONGRID_VERT_GAP) + icon_height +ICONGRID_TOP_MARGIN ;
-
- Icon *icon = new Icon (this, template_icon, x, -y, ref) ;
- Box pos ;
- icon->read_position (pos) ;
- do_redraw (pos.x0, pos.y0, pos.x1, pos.y1) ; // redraw the window
- icon->print (text) ;
- icon->change_sprite (sprite) ;
- num_icons++ ;
- current_column++ ;
- if (current_column == num_columns)
- {
- current_column = 0 ;
- current_row++ ;
- int new_height = current_row * (icon_height + ICONGRID_VERT_GAP) + icon_height +ICONGRID_TOP_MARGIN ;
- if (new_height > min_height)
- set_height (new_height) ;
- }
- if (flag_set & SORTED)
- sort() ;
- return icon ;
- }
-
-
- void IconGrid::remove_icon(Icon *icon)
- {
- Window::remove_icon (icon) ;
- if (!deleting)
- {
- num_icons-- ;
- if (flag_set & SORTED)
- sort() ;
- }
- }
-
- void IconGrid::delete_icon (void *ref)
- {
- for (Icon *icon = icons ; icon != NULL ; icon = icon->next)
- if (ref == icon->user_ref)
- {
- delete icon ;
- break ;
- }
- }
-
- //
- // sort the icons in the grid using qsort
- //
-
-
- static int sort_compare (const void *i1, const void *i2)
- {
- const Icon **x = (const Icon**)i1 ;
- const Icon **y = (const Icon**)i2 ;
- #ifdef __EASY_C
- return (*x)->compare(*y) ;
- #else
- Icon *i = (Icon*)*x ;
- Icon *j = (Icon*)*y ;
- return i->compare(j) ;
- #endif
- }
-
-
- void IconGrid::sort()
- {
- int i ;
- Icon *icon ;
- Icon **buffer = new Icon *[num_icons] ;
- for (icon = icons, i = 0 ; icon != NULL ; icon = icon->next)
- if (icon != template_icon)
- buffer[i++] = icon ;
- qsort (buffer, num_icons, sizeof (Icon *), sort_compare) ;
- icons = NULL ; // reset icons list
- add_icon (template_icon) ; // add the template again
- for (i = 0 ; i < num_icons ; i++) // put all the icons back
- add_icon (buffer[i]) ;
- rearrange() ;
- delete [] buffer ;
- }
-
-
- void IconGrid::open(int x0, int y0, int x1, int y1, int scx, int scy, int behind)
- {
- Window::open (x0,y0,x1,y1,scx,scy,behind) ; // open the window
- int nc = (x1 - x0 - ICONGRID_LEFT_MARGIN) / (icon_width + ICONGRID_HOR_GAP) ;
- if (nc == 0)
- nc = 1 ;
- if (num_icons != 0 && nc != num_columns)
- {
- num_columns = nc ;
- rearrange() ;
- }
- num_columns = nc ;
- }
-
-
- void IconGrid::click(int mx, int my, int buttons, int icon)
- {
- int click_factor ;
- int double_factor ;
- int drag_factor ;
- switch (template_button_type)
- {
- case Icon::BCLICKDEBOUNCE:
- click_factor = 1 ;
- double_factor = 0 ;
- drag_factor = 0 ;
- break ;
- case Icon::BDEBOUNCEDRAG:
- default:
- click_factor = 1 ;
- double_factor = 0 ;
- drag_factor = 16 ;
- break ;
- case Icon::BCLICKDRAGDOUBLE:
- click_factor = 256 ;
- double_factor = 1 ;
- drag_factor = 16 ;
- break ;
- }
- if (icon >= 0)
- {
- Icon *ic = Window::find_icon (icon) ;
- if (buttons & (4 * drag_factor))
- {
- int count = 0 ;
- int minx = 30000, maxx = 0, miny = 0, maxy = -30000;
- Box pos ;
- for (Icon *i = icons ; i != NULL ; i = i->next)
- if (i->is_selected())
- {
- count++ ;
- i->read_position(pos) ;
- if (pos.x0 < minx) minx = pos.x0 ;
- if (pos.x1 > maxx) maxx = pos.x1 ;
- if (pos.y0 < miny) miny = pos.y0 ;
- if (pos.y1 > maxy) maxy = pos.y1 ;
- }
- minx += x0 ;
- miny += y1 ;
- maxx += x0 ;
- maxy += y1 ;
- if (count > 1)
- drag_selection (mx, my, buttons, minx, miny, maxx, maxy) ;
- else
- drag_icon (mx, my, buttons, ic) ;
- return ;
- }
- if (buttons & (4 * double_factor))
- {
- double_click (mx, my, buttons, ic) ;
- if (!(flag_set & NODESELECT))
- {
- if (ic->is_selected())
- ic->unselect() ;
- }
- return ;
- }
- if (flag_set & NOSELECT)
- return ;
- if (buttons & (4 * click_factor))
- {
- if (!ic->is_selected())
- {
- clear_selection() ;
- ic->select() ;
- }
- }
- else
- if (buttons & (1 | 256))
- if (ic->is_selected())
- ic->unselect() ;
- else
- ic->select() ;
- }
- else
- if (flag_set & NOSELECT)
- return ;
- else if (buttons & (4 * 16))
- {
- int block[16] ;
- _kernel_swi_regs r ;
- _kernel_oserror *e ;
-
- block[0] = handle ;
- block[1] = 6 ; // user rotating dash box
- block[2] = mx ;
- block[3] = my ;
- block[4] = mx + 1 ;
- block[5] = my + 1 ;
- if (parent == NULL)
- {
- block[6] = x0 ;
- block[7] = y0 ;
- block[8] = x1 ;
- block[9] = y1 ;
- }
- else
- {
- block[6] = parent->x0 + x0 ;
- block[7] = parent->y0 + y0 ;
- block[8] = parent->x1 + x1 ;
- block[9] = parent->y1 + y1 ;
- }
- r.r[1] = (int)block ;
- if ((e = _kernel_swi (Wimp_DragBox, &r, &r)) != NULL)
- throw (e) ;
- task->register_drag (this,0) ;
- clear_selection() ;
- }
- else
- if (buttons & (4 * click_factor)) // click outside icons
- clear_selection() ;
- }
-
-
- void IconGrid::double_click(int mx, int my, int buttons, Icon *icon)
- {
- }
-
- void IconGrid::drag_icon(int mx, int my, int buttons, Icon *icon)
- {
- }
-
- void IconGrid::drag_selection(int mx, int my, int buttons, int x0, int y0, int x1, int y1)
- {
- }
-
- void IconGrid::drag (int dx0, int dy0, int dx1, int dy1, int id)
- {
- Icon *icon ;
- Box box ;
- // ::print ("dx0:%d dy0:%d Dx1:%d dy1:%d x0:%d y0:%d x1:%d y1:%d",dx0,dy0,dx1,dy1,x0,y0,x1,y1) ;
- int tmp ;
- int xdiff, ydiff ;
- if (dx0 > dx1) // strange - shouldn't have to do this surely
- {
- tmp = dx0 ;
- dx0 = dx1 ;
- dx1 = tmp ;
- }
- if (dy0 > dy1)
- {
- tmp = dy0 ;
- dy0 = dy1 ;
- dy1 = tmp ;
- }
- xdiff = x0 - scx ;
- ydiff = y1 - scy ;
- if (parent == NULL)
- {
- dx0 -= xdiff ;
- dx1 -= xdiff ;
- dy0 -= ydiff ;
- dy1 -= ydiff ;
- }
- else
- {
- dx0 -= parent->x0 + xdiff ;
- dx1 -= parent->x0 + xdiff ;
- dy0 -= parent->y0 + ydiff ;
- dy1 -= parent->y0 + ydiff ;
- }
- // ::print ("%d %d %d %d", dx0, dy0, dx1, dy1) ;
- for (icon = icons ; icon != NULL ; icon = icon->next)
- if (icon != template_icon)
- {
- icon->read_position(box) ;
- // ::print ("%d %d %d %d",box.x0, box.y0, box.x1, box.y1) ;
- if (dx0 <= box.x1 && dx1 >= box.x0 && dy1 >= box.y0 && dy0 <= box.y1)
- icon->select() ;
- }
-
- }
-
-
- Icon *IconGrid::find_icon (int icon)
- {
- return NULL ; // want window to deal with icon clicks
- }
-
-
- void IconGrid::select_all()
- {
- Icon *icon ;
- for (icon = icons ; icon != NULL ; icon = icon->next)
- if (icon != template_icon)
- if (!icon->is_selected())
- icon->select() ;
- }
-
- void IconGrid::clear_selection()
- {
- Icon *icon ;
- for (icon = icons ; icon != NULL ; icon = icon->next)
- if (icon != template_icon)
- if (icon->is_selected())
- icon->unselect() ;
- }
-
-
- void IconGrid::rearrange()
- {
- Icon *icon ;
-
- current_column = 0 ;
- current_row = 0 ;
- for (icon = icons ; icon != NULL ; icon = icon->next)
- {
- if (icon != template_icon)
- {
- int x = current_column * (icon_width + ICONGRID_HOR_GAP) + ICONGRID_LEFT_MARGIN ;
- int y = current_row * (icon_height + ICONGRID_VERT_GAP) + icon_height + ICONGRID_TOP_MARGIN ;
- icon->move_to (x,-y) ;
- current_column++ ;
- if (current_column == num_columns)
- {
- current_column = 0 ;
- current_row++ ;
- }
- }
- }
- Window::Info *inf = info() ;
- min_height = inf->extent.y1 - inf->extent.y0 ;
- int new_height = current_row * (icon_height + ICONGRID_VERT_GAP) + icon_height + ICONGRID_TOP_MARGIN ;
- if (new_height > min_height)
- set_height (new_height) ;
- do_redraw() ; // whole window
- }
-
-
- //
- // a dialogue box
- //
-
-
- DialogueBox::DialogueBox (Task *t, char *tname, int cancel, int ok, char *menu)
- : Window (t, tname, menu), Thread (tname)
- {
- attributes = NULL ;
- cancel_icon = NULL ;
- ok_icon = NULL ;
- cancelled = false ;
- if (cancel != -1)
- cancel_icon = new CancelButton (this, cancel) ;
- if (ok != -1)
- ok_icon = new OKButton (this, ok) ;
- waiting = new ThreadSemaphore ;
- }
-
- DialogueBox::~DialogueBox ()
- {
- if (cancel_icon != NULL)
- delete cancel_icon ;
- if (ok_icon != NULL)
- delete ok_icon ;
- delete waiting ;
- Attribute *a, *nexta ;
- for (a = attributes ; a != NULL ; a = nexta)
- {
- nexta = a->next ;
- delete a ;
- }
- }
-
- void DialogueBox::show()
- {
- ok_or_cancel_pressed = false ;
- for (Attribute *attr = attributes ; attr != NULL ; attr = attr->next)
- attr->set() ;
- from_menu = false ;
- if (task->last_event == Task::ESEND && task->last_event_data[4] == Task::Message_MenuWarning)
- {
- from_menu = true ;
- _kernel_swi_regs r ;
- _kernel_oserror *e ;
- r.r[1] = handle ;
- r.r[2] = task->last_event_data[6] ;
- r.r[3] = task->last_event_data[7] ;
- if ((e = _kernel_swi (Wimp_CreateSubMenu, &r, &r)) != NULL)
- throw (e) ;
- }
- else
- do_open() ;
- if (attributes != NULL)
- {
- Attribute *attr = attributes ;
- while (attr != NULL && !attr->is_writeable())
- attr = attr->next ;
- if (attr != NULL)
- attr->set_caret() ;
- }
- start() ; // start the thread running
- }
-
- //
- // this is complicated by the fact that the WIMP doesn't tell the task anything
- // when a window is opened from a menu (menu warning) and the mouse is moved
- // back onto the menu thus closing the window. In this case we
- // loop reading the window state until the WOPEN flag is clear signifying
- // that the window has been closed.
- //
- // If we are not from a menu then we just sleep until the 'waiting' semaphore is
- // set.
- //
-
- void DialogueBox::run()
- {
- if (from_menu) // are we from a menu?
- {
- Window::State *s = Window::state() ;
- while (s->flags & WOPEN) // wait until we are not open
- {
- yield() ;
- s = Window::state() ;
- }
- }
- else
- sleep (waiting) ; // sleep until no longer waiting
- }
-
- void DialogueBox::hide()
- {
- if (from_menu)
- {
- _kernel_swi_regs r ;
- _kernel_oserror *e ;
- r.r[1] = -1 ;
- r.r[2] = 0 ;
- r.r[3] = 0 ;
- if ((e = _kernel_swi (Wimp_CreateMenu, &r, &r)) != NULL)
- throw (e) ;
- }
- else
- close() ;
- }
-
- void DialogueBox::next_attribute(int icon)
- {
- Attribute *attr ;
- for (attr = attributes ; attr != NULL ; attr = attr->next)
- if (attr->icon->handle == icon)
- {
- if (attr->next == NULL)
- attr = attributes ;
- else
- attr = attr->next ;
- while (!attr->is_writeable())
- {
- attr = attr->next ;
- if (attr == NULL)
- attr = attributes ;
- }
- attr->set_caret() ;
- break ;
- }
- }
-
- void DialogueBox::prev_attribute(int icon)
- {
- Attribute *attr ;
- for (attr = attributes ; attr != NULL ; attr = attr->next)
- if (attr->icon->handle == icon)
- {
- if (attr->prev == NULL)
- attr = last_attribute ;
- else
- attr = attr->prev ;
- while (!attr->is_writeable())
- {
- attr = attr->prev ;
- if (attr == NULL)
- attr = last_attribute ;
- }
- attr->set_caret() ;
- break ;
- }
- }
-
- void DialogueBox::click (int mx, int my, int buttons, int icon)
- {
- Icon *i = Window::find_icon (icon) ;
- if (i != NULL)
- i->click (mx, my, buttons, icon) ;
- }
-
- void DialogueBox::key (int icon, int x, int y, int height, int index, int code)
- {
- // ::print ("key %d",code) ;
- switch (code)
- {
- case 13: // cr
- ok(4) ;
- break ;
- case 27: // esc
- cancel(4) ;
- break ;
- case 394: // tab
- case 398: // down arrow
- next_attribute (icon) ;
- break ;
- case 399: // up arrow
- case 410: // shift-tab
- prev_attribute(icon) ;
- break ;
- }
- }
-
- // if the window is closed without the user pressing OK or cancel, the
- // cancelled flag is set.
-
- void DialogueBox::close()
- {
- if (!ok_or_cancel_pressed) // was the OK or cancel buttons pressed?
- cancelled = true ; // no, so must have been closed by close button etc.
- waiting->set() ;
- if (from_menu)
- {
- _kernel_swi_regs r ;
- _kernel_oserror *e ;
- r.r[1] = -1 ;
- r.r[2] = 0 ;
- r.r[3] = 0 ;
- if ((e = _kernel_swi (Wimp_CreateMenu, &r, &r)) != NULL)
- throw (e) ;
- }
- Window::do_close() ;
- }
-
-
- void DialogueBox::cancel(int button)
- {
- waiting->set() ;
- cancelled = true ;
- ok_or_cancel_pressed = true ;
- hide() ;
- }
-
- void DialogueBox::ok(int button)
- {
- waiting->set() ;
- ok_or_cancel_pressed = true ;
- cancelled = false ;
- for (Attribute *attr = attributes ; attr != NULL ; attr = attr->next)
- attr->get() ;
- hide() ;
- }
-
- void DialogueBox::add_attribute (Attribute *attr)
- {
- if (attributes == NULL)
- attributes = last_attribute = attr ;
- else
- {
- attr->prev = last_attribute ;
- last_attribute->next = attr ;
- last_attribute = attr ;
- }
- }
-
- void DialogueBox::create_attribute (int iconnum, char *str)
- {
- StringAttribute *attr = new StringAttribute (this, str, iconnum) ;
- }
-
- void DialogueBox::create_attribute (int iconnum, int &number)
- {
- IntegerAttribute *attr = new IntegerAttribute (this, number, iconnum) ;
- }
-
- void DialogueBox::create_attribute (int iconnum, bool &value)
- {
- BoolAttribute *attr = new BoolAttribute (this, value, iconnum) ;
- }
-
- void DialogueBox::create_attribute (int num_values, bool *values ...)
- {
- va_list ap ;
- va_start (ap, values) ;
- SetAttribute *attr = new SetAttribute (this, values, num_values, ap) ;
- va_end (ap) ;
- }
-
- void DialogueBox::create_attribute (Icon *icon, int &value)
- {
- IntegerAttribute *attr = new IntegerAttribute (this, value, icon) ;
- }
-
- void DialogueBox::create_attribute (Icon *icon, char *value)
- {
- StringAttribute *attr = new StringAttribute (this, value, icon) ;
- }
-
- void DialogueBox::create_attribute (Icon *icon, bool &value)
- {
- BoolAttribute *attr = new BoolAttribute (this, value, icon) ;
- }
-
-
- Attribute::Attribute (DialogueBox *d, int iconnum, char *menu)
- {
- icon = new Icon (d, iconnum) ;
- next = NULL ;
- prev = NULL ;
- default_menu = menu ;
- d->add_attribute (this) ;
- my_icon = 1 ;
- }
-
- Attribute::Attribute (DialogueBox *d, Icon *icon, char *menu)
- {
- this->icon = icon ;
- next = NULL ;
- prev = NULL ;
- default_menu = menu ;
- d->add_attribute (this) ;
- my_icon = 0 ;
- }
-
- Attribute::Attribute (DialogueBox *d)
- {
- this->icon = NULL ;
- next = NULL ;
- prev = NULL ;
- default_menu = NULL ;
- d->add_attribute (this) ;
- my_icon = 0 ;
- }
-
- Attribute::~Attribute()
- {
- if (my_icon)
- delete icon ;
- }
-
- void Attribute::set_caret()
- {
- icon->set_caret() ;
- }
-
- int Attribute::is_writeable()
- {
- if (icon == NULL)
- return 0 ;
- return icon->is_writeable() ;
- }
-
- StringAttribute::StringAttribute (DialogueBox *d, char *str, int iconnum, char *menu)
- : Attribute (d, iconnum, menu)
- {
- string = str ;
- }
-
- StringAttribute::StringAttribute (DialogueBox *d, char *str, Icon *icon, char *menu)
- : Attribute (d, icon, menu)
- {
- string = str ;
- }
-
- StringAttribute::~StringAttribute()
- {
- }
-
- void StringAttribute::get()
- {
- icon->read (string) ;
- }
-
- void StringAttribute::set()
- {
- icon->write (string) ;
- }
-
-
- IntegerAttribute::IntegerAttribute (DialogueBox *d, int &number, int iconnum, char *menu)
- : Attribute (d, iconnum, menu)
- {
- num = &number ;
- }
-
- IntegerAttribute::IntegerAttribute (DialogueBox *d, int &number, Icon *icon, char *menu)
- : Attribute (d, icon, menu)
- {
- num = &number ;
- }
-
- IntegerAttribute::~IntegerAttribute()
- {
- }
-
- void IntegerAttribute::get()
- {
- icon->read (*num) ;
- }
-
- void IntegerAttribute::set()
- {
- icon->write (*num) ;
- }
-
-
- BoolAttribute::BoolAttribute (DialogueBox *d, bool &value, int iconnum, char *menu)
- : Attribute (d, iconnum, menu)
- {
- this->value = &value ;
- }
-
- BoolAttribute::BoolAttribute (DialogueBox *d, bool &value, Icon *icon, char *menu)
- : Attribute (d, icon, menu)
- {
- this->value = &value ;
- }
-
- BoolAttribute::~BoolAttribute()
- {
- }
-
- void BoolAttribute::get()
- {
- *value = icon->is_selected() ? true : false ;
- }
-
- void BoolAttribute::set()
- {
- if (*value)
- icon->select() ;
- else
- icon->unselect() ;
- }
-
-
- SetAttribute::SetAttribute (DialogueBox *d, bool *values, int num_values, int iconnum ...)
- : Attribute (d)
- {
- va_list arg ;
- this->values = values ;
- this->num_values = num_values ;
- va_start (arg, iconnum) ;
- icons = new Icon* [num_values] ;
- for (int i = 0 ; i < num_values ; i++)
- icons[i] = new Icon (d, va_arg (arg, int)) ;
- va_end (arg) ;
- }
-
- SetAttribute::SetAttribute (DialogueBox *d, bool *values, int num_values, Icon *icon ...)
- : Attribute (d)
- {
- va_list arg ;
- this->values = values ;
- this->num_values = num_values ;
- va_start (arg, icon) ;
- icons = new Icon* [num_values] ;
- for (int i = 0 ; i < num_values ; i++)
- icons[i] = va_arg (arg, Icon *) ;
- va_end (arg) ;
- }
-
- SetAttribute::SetAttribute (DialogueBox *d, bool *values, int num_values, va_list arg)
- : Attribute (d)
- {
- this->values = values ;
- this->num_values = num_values ;
- icons = new Icon* [num_values] ;
- for (int i = 0 ; i < num_values ; i++)
- icons[i] = new Icon (d, va_arg (arg, int)) ;
- }
-
-
- SetAttribute::~SetAttribute()
- {
- for (int i = 0 ; i < num_values ; i++)
- delete icons[i] ;
- delete icons ;
- }
-
- void SetAttribute::get()
- {
- for (int i = 0 ; i < num_values ; i++)
- values[i] = icons[i]->is_selected() ? true : false ;
- }
-
- void SetAttribute::set()
- {
- for (int i = 0 ; i < num_values ; i++)
- {
- if (values[i])
- icons[i]->select() ;
- else
- icons[i]->unselect() ;
- }
- }
-
-
- SaveBox::SaveBox (Task *t, char *tname, char *path, char *leafname, int type, DataSave *saver)
- : DialogueBox (t, tname, 3, 0)
- {
- if (leafname[0] == 0)
- throw ("Supply leaf name for save box") ;
- this->saver = saver ;
- if (path[0] == 0)
- strcpy (this->path, leafname) ;
- else
- strcpy (this->path, path) ;
- file_icon = new SaverFile (this, type) ;
- name = new StringAttribute (this, this->path, 1) ;
- }
-
-
- SaveBox::~SaveBox()
- {
- delete file_icon ;
- delete name ;
- }
-
- void SaveBox::drag (int x0, int y0, int x1, int y1, int id)
- {
- char *leafname ;
- name->get() ; // read name typed by user
- if ((leafname = strrchr (path, '.')) != NULL)
- leafname++ ;
- else
- leafname = path ;
- int block[5] ;
- _kernel_swi_regs r ;
- _kernel_oserror *e ;
- r.r[1] = (int)block ;
- if ((e = _kernel_swi (Wimp_GetPointerInfo, &r, &r)) != NULL)
- throw (e) ;
- hide() ;
- saver->save (block[3], block[4], block[0], block[1], leafname) ;
- }
-
- void SaveBox::ok(int button)
- {
- name->get() ; // read path typed in by user
- if (strchr (path, '.') == NULL)
- #ifdef __EASY_C
- throw "To save, drag icon to a window" ;
- #else
- werr (0,"To save, drag icon to a window") ;
- #endif
- else
- {
- waiting->set() ;
- hide() ;
- saver->save (path) ;
- }
- }
-
- SaverFile::SaverFile (SaveBox *box, int type)
- : Icon (box, 2)
- {
- sprite = new char [32] ;
- sprintf (sprite, "file_%x",type) ;
- change_sprite (sprite) ;
- save_box = box ;
- }
-
- SaverFile::~SaverFile()
- {
- delete [] sprite ;
- }
-
- void SaverFile::click (int mx, int my, int button, int icon)
- {
- _kernel_swi_regs r ;
- if (button & (4 * 16)) // drag?
- {
- save_box->read_position() ; // may have moved, so reread position
- r.r[0] = 161 ;
- r.r[1] = 28 ;
- _kernel_swi (OS_Byte, &r, &r) ; // does user want sprite dragged?
- save_box->task->register_drag (save_box, 0, (r.r[2] & 2)? true : false) ;
- drag (mx, my, button) ;
- }
-
- }
-
- //
- // ProgramInfo dialogue box
- //
-
- ProgramInfo::ProgramInfo (Task *t, int vicon, char *v)
- : DialogueBox (t, "ProgInfo")
- {
- version = new Icon (this, vicon) ;
- version->print (v) ;
- }
-
- ProgramInfo::~ProgramInfo()
- {
- delete version ;
- }
-
-