home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Acorn User 2
/
AUCD2.iso
/
program
/
vista.arc
/
c
/
wins
< prev
Wrap
Text File
|
1996-02-01
|
26KB
|
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 ;
}