9285b6486e
git-svn-id: svn://10.65.10.50/trunk@1228 c028cbd2-c16b-5b4b-a496-9718f37d4682
1087 lines
24 KiB
C++
Executable File
1087 lines
24 KiB
C++
Executable File
extern "C"
|
|
{
|
|
#include <xvt.h>
|
|
#include <xvtcm.h>
|
|
}
|
|
|
|
#if XVT_OS != XVT_OS_WIN
|
|
#error "This file should be compiled for Windows only"
|
|
#endif
|
|
|
|
#include <colors.h>
|
|
#include <controls.h>
|
|
#include <urldefid.h>
|
|
#include <utility.h>
|
|
#include <window.h>
|
|
|
|
#include <windows.h>
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TPicture_array
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TPicture_array : public TArray
|
|
{
|
|
public:
|
|
TImage& add(short id, bool convert = FALSE);
|
|
|
|
//TImage& image(short id) { return (TImage&)operator[](id); }
|
|
const TImage& image(short id) const { return (const TImage&)operator[](id); }
|
|
bool exist(short id) const { return objptr(id) != NULL; }
|
|
|
|
TPicture_array() : TArray(128) {}
|
|
~TPicture_array() {}
|
|
};
|
|
|
|
TImage& TPicture_array::add(short id, bool convert)
|
|
{
|
|
TImage* i = (TImage*)objptr(id);
|
|
|
|
if (i == NULL)
|
|
{
|
|
i = new TImage(id);
|
|
TArray::add(i, id);
|
|
if (convert)
|
|
i->convert_to_default_colors();
|
|
}
|
|
|
|
return *i;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Static data and functions
|
|
///////////////////////////////////////////////////////////
|
|
|
|
HIDDEN TControl* creating = NULL;
|
|
HIDDEN long ctl_flags;
|
|
HIDDEN WINDOW _hdc;
|
|
HIDDEN RCT _client;
|
|
HIDDEN TPicture_array cpb;
|
|
|
|
HIDDEN void get_geometry(WINDOW win)
|
|
{
|
|
xvt_vobj_get_client_rect(win, &_client);
|
|
_client.right--; _client.bottom--;
|
|
_hdc = win;
|
|
}
|
|
|
|
HIDDEN void set_creation_args(WIN_CREATION_ARGS *a)
|
|
{
|
|
long& flags = a->win_flags;
|
|
if (ctl_flags & CTL_FLAG_DISABLED) flags |= WSF_DISABLED;
|
|
if (ctl_flags & CTL_FLAG_INVISIBLE) flags |= WSF_INVISIBLE;
|
|
|
|
switch(creating->id())
|
|
{
|
|
case -2:
|
|
flags |= WSF_DISABLED;
|
|
break;
|
|
default:break;
|
|
}
|
|
}
|
|
|
|
void xvt_draw_rect(WINDOW win, const RCT& rect, COLOR lt, COLOR rb, short depth)
|
|
{
|
|
RCT r = rect;
|
|
|
|
CPEN pen;
|
|
pen.width = 1;
|
|
pen.pat = PAT_SOLID;
|
|
pen.style = P_SOLID;
|
|
pen.color = lt;
|
|
|
|
for (short d = 0; d < depth;)
|
|
{
|
|
xvt_dwin_set_cpen(win, &pen);
|
|
|
|
PNT p; // Current vertex of the rectangle
|
|
|
|
bool drawed = FALSE;
|
|
if (lt != COLOR_LTGRAY)
|
|
{
|
|
p.h = r.left; p.v = r.bottom;
|
|
xvt_dwin_draw_set_pos(win, p);
|
|
|
|
p.v = r.top;
|
|
xvt_dwin_draw_line(win, p);
|
|
p.h = r.right;
|
|
xvt_dwin_draw_line(win, p);
|
|
drawed = TRUE;
|
|
}
|
|
|
|
if (rb != COLOR_LTGRAY)
|
|
{
|
|
if (pen.color != rb)
|
|
{
|
|
pen.color = rb;
|
|
xvt_dwin_set_cpen(win, &pen);
|
|
}
|
|
if (!drawed)
|
|
{
|
|
p.h = r.right; p.v = r.top;
|
|
xvt_dwin_draw_set_pos(win, p);
|
|
}
|
|
p.v = r.bottom;
|
|
xvt_dwin_draw_line(win, p);
|
|
p.h = r.left;
|
|
xvt_dwin_draw_line(win, p);
|
|
}
|
|
|
|
if (++d < depth)
|
|
{
|
|
r.left++; r.top++;
|
|
r.right--; r.bottom--;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void TControl::create(
|
|
short left, short top, short right, short bottom, const char* title,
|
|
WINDOW parent, long flags, long app_data, short id)
|
|
{
|
|
bool bold = FALSE;
|
|
_color = NORMAL_COLOR;
|
|
|
|
while (*title == '@' || *title == '$')
|
|
{
|
|
switch (*title++)
|
|
{
|
|
case '@':
|
|
if (toupper(*title) == 'B') bold = TRUE;
|
|
break;
|
|
case '$':
|
|
title++; // Skip [
|
|
if (isalpha(*title))
|
|
_color = trans_color(*title);
|
|
else
|
|
{
|
|
int r = 0, g = 0, b = 0;
|
|
sscanf(title, "%d,%d,%d", &r, &g, &b);
|
|
_color = MAKE_COLOR(r, g, b);
|
|
}
|
|
while (*title != ']') // Find ]
|
|
{
|
|
CHECK(*title, "Bad prompt format");
|
|
title++;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
title++;
|
|
}
|
|
|
|
const int prop_count = 1;
|
|
const char* prop_list[prop_count+1] = { title, NULL };
|
|
|
|
_id = id;
|
|
_disabled = (flags & CTL_FLAG_DISABLED) != 0;
|
|
_checked = (flags & CTL_FLAG_CHECKED) != 0;
|
|
_multiple = (flags & CTL_FLAG_MULTIPLE) != 0;
|
|
_focused = FALSE;
|
|
_caption = title; _caption.strip("~");
|
|
|
|
creating = this;
|
|
ctl_flags = flags;
|
|
_win = xvtcm_create(id, left, top, right, bottom,
|
|
prop_count, (char**)prop_list, parent,
|
|
0, 0, NULL, handler, set_creation_args);
|
|
CHECKD(_win, "Can't create control ", id);
|
|
|
|
creating = NULL;
|
|
xvt_vobj_set_data(_win, app_data);
|
|
xvt_set_font(_win, "", int(bold ? XVT_FS_BOLD : XVT_FS_NONE));
|
|
}
|
|
|
|
|
|
// Virtual destructor needed to make derived descrutors live!
|
|
TControl::~TControl()
|
|
{}
|
|
|
|
|
|
long XVT_CALLCONV1 TControl::handler(WINDOW win, EVENT* ep)
|
|
{
|
|
HIDDEN bool tracking = FALSE;
|
|
HIDDEN bool pressed = FALSE;
|
|
|
|
if (ep->type == E_CREATE)
|
|
xvtcm_eh_start(win, ep);
|
|
|
|
TControl** model = (TControl**)xvtcm_get_model(win, sizeof(TControl*));
|
|
CHECK(model, "Can't get the model");
|
|
|
|
TControl*& cc = *model;
|
|
if (ep->type == E_CREATE)
|
|
{
|
|
CHECK(creating, "Can't create a NULL control");
|
|
cc = creating;
|
|
}
|
|
CHECK(cc, "Can't handle a NULL control");
|
|
|
|
if (creating == NULL) switch(ep->type)
|
|
{
|
|
case E_FOCUS:
|
|
cc->focus((bool)ep->v.active);
|
|
case E_UPDATE:
|
|
cc->update();
|
|
break;
|
|
case E_MOUSE_DOWN:
|
|
xvt_win_trap_pointer(win);
|
|
tracking = pressed = TRUE;
|
|
cc->mouse_down(ep->v.mouse.where);
|
|
break;
|
|
case E_CHAR:
|
|
{
|
|
const KEY key = e_char_to_key(ep);
|
|
switch(key)
|
|
{
|
|
case K_SPACE:
|
|
cc->mouse_up();
|
|
break;
|
|
default:
|
|
dispatch_e_char(xvt_vobj_get_parent(win), key);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case E_MOUSE_MOVE:
|
|
if (tracking)
|
|
{
|
|
RCT r;
|
|
xvt_vobj_get_client_rect(win, &r);
|
|
if (xvt_rect_has_point(&r, ep->v.mouse.where))
|
|
{
|
|
if (!pressed)
|
|
{
|
|
cc->mouse_down(ep->v.mouse.where);
|
|
pressed = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pressed)
|
|
{
|
|
cc->update();
|
|
pressed = FALSE;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case E_MOUSE_UP:
|
|
if (tracking)
|
|
{
|
|
xvt_win_release_pointer();
|
|
tracking = FALSE;
|
|
if (pressed)
|
|
{
|
|
cc->mouse_up();
|
|
pressed = FALSE;
|
|
}
|
|
}
|
|
break;
|
|
case E_DESTROY:
|
|
delete *model;
|
|
*model = NULL;
|
|
xvtcm_eh_end(win, ep);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0L;
|
|
}
|
|
|
|
void TControl::enable(bool on)
|
|
{
|
|
if (on == disabled())
|
|
{
|
|
_disabled = !on;
|
|
update();
|
|
xvt_vobj_set_enabled(win(), on);
|
|
}
|
|
}
|
|
|
|
void TControl::check(bool on)
|
|
{
|
|
_checked = on;
|
|
}
|
|
|
|
void TControl::update() const
|
|
{
|
|
if (_win != _hdc)
|
|
get_geometry(_win);
|
|
xvt_dwin_clear(_hdc, MASK_BACK_COLOR);
|
|
xvt_dwin_set_fore_color(_hdc, disabled() ? DISABLED_COLOR : color());
|
|
}
|
|
|
|
void TControl::set_caption(const char* t)
|
|
{
|
|
_caption = t;
|
|
update();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TText
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TText : public TControl
|
|
{
|
|
protected:
|
|
virtual WIN_TYPE type() const { return WC_TEXT; }
|
|
virtual void update() const;
|
|
|
|
public:
|
|
TText(short left, short top, short right, short bottom,
|
|
const char* caption, WINDOW parent,
|
|
long flags, long app_data, short id);
|
|
};
|
|
|
|
TText::TText(short left, short top, short right, short bottom,
|
|
const char* caption, WINDOW parent,
|
|
long flags, long app_data, short id)
|
|
{
|
|
create(left, top+1, right, bottom-1, caption, parent, flags, app_data, id);
|
|
}
|
|
|
|
void TText::update() const
|
|
{
|
|
TControl::update();
|
|
xvt_dwin_set_fore_color(_hdc, color());
|
|
xvt_dwin_draw_text(_hdc, _client.left, _client.top+BASEY, (char*)caption(), -1);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TGroup
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TGroup : public TText
|
|
{
|
|
protected:
|
|
virtual WIN_TYPE type() const { return WC_GROUPBOX; }
|
|
virtual void update() const;
|
|
void draw_round_rect(const RCT& r, COLOR c) const;
|
|
|
|
public:
|
|
TGroup(short left, short top, short right, short bottom,
|
|
const char* caption, WINDOW parent,
|
|
long flags, long app_data, short id);
|
|
};
|
|
|
|
TGroup::TGroup(short left, short top, short right, short bottom,
|
|
const char* caption, WINDOW parent,
|
|
long flags, long app_data, short id)
|
|
: TText(left, top, right, bottom, caption, parent, flags | CTL_FLAG_DISABLED, app_data,
|
|
(id < 0) ? -2 : id)
|
|
{}
|
|
|
|
void TGroup::draw_round_rect(const RCT& r, COLOR c) const
|
|
{
|
|
CPEN pen;
|
|
pen.width = 2;
|
|
pen.pat = PAT_SOLID;
|
|
pen.style = P_SOLID;
|
|
pen.color = c;
|
|
xvt_dwin_set_cpen(_hdc, &pen);
|
|
|
|
CBRUSH brush = { PAT_HOLLOW, MASK_BACK_COLOR };
|
|
xvt_dwin_set_cbrush(_hdc, &brush);
|
|
xvt_dwin_draw_roundrect(_hdc, (RCT*)&r, ROWY, ROWY);
|
|
}
|
|
|
|
void TGroup::update() const
|
|
{
|
|
TText::update();
|
|
|
|
RCT r = _client;
|
|
r.top += CHARY;
|
|
r.right-=4; r.bottom-=ROWY/2;
|
|
if (multiple())
|
|
{
|
|
r.left++; r.top++; r.right--; r.bottom--;
|
|
draw_round_rect(r, MASK_LIGHT_COLOR);
|
|
}
|
|
else
|
|
{
|
|
xvt_draw_rect(_hdc, r, MASK_DARK_COLOR, MASK_LIGHT_COLOR);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Button
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TButton : public TControl
|
|
{
|
|
protected:
|
|
enum { DEPTH = 2 };
|
|
|
|
virtual WIN_TYPE type() const { return WC_PUSHBUTTON; }
|
|
virtual void update() const;
|
|
virtual void mouse_down(PNT where);
|
|
virtual void mouse_up();
|
|
virtual void check(bool on);
|
|
virtual void draw_pressed(bool pressed) const;
|
|
|
|
public:
|
|
TButton(short left, short top, short right, short bottom,
|
|
const char* caption,WINDOW parent,
|
|
long flags, long app_data, short id);
|
|
};
|
|
|
|
|
|
TButton::TButton(short left, short top, short right, short bottom,
|
|
const char* caption, WINDOW parent,
|
|
long flags, long app_data, short id)
|
|
{
|
|
create(left, top, right, bottom, caption, parent, flags, app_data, id);
|
|
}
|
|
|
|
|
|
void TButton::draw_pressed(bool pressed) const
|
|
{
|
|
get_geometry(win());
|
|
|
|
xvt_dwin_clear(_hdc, COLOR_LTGRAY);
|
|
RCT r = _client;
|
|
xvt_draw_rect(_hdc, r, COLOR_BLACK, COLOR_BLACK);
|
|
|
|
COLOR lt = pressed ? COLOR_GRAY : COLOR_WHITE;
|
|
COLOR rb = pressed ? COLOR_LTGRAY : COLOR_GRAY;
|
|
|
|
for (int i = DEPTH; i--;)
|
|
{
|
|
r.left++; r.top++; r.right--; r.bottom--;
|
|
xvt_draw_rect(_hdc, r, lt, rb);
|
|
if (i == 1) lt = COLOR_LTGRAY;
|
|
}
|
|
}
|
|
|
|
|
|
void TButton::update() const
|
|
{
|
|
TControl::update();
|
|
draw_pressed(checked());
|
|
}
|
|
|
|
void TButton::mouse_down(PNT)
|
|
{
|
|
draw_pressed(!checked());
|
|
}
|
|
|
|
void TButton::mouse_up()
|
|
{
|
|
draw_pressed(checked());
|
|
|
|
EVENT e; // Notification message
|
|
e.type = E_CONTROL;
|
|
e.v.ctl.id = id();
|
|
e.v.ctl.ci.type = type();
|
|
e.v.ctl.ci.win = win();
|
|
xvt_win_dispatch_event(xvt_vobj_get_parent(win()), &e);
|
|
}
|
|
|
|
void TButton::check(bool on)
|
|
{
|
|
TControl::check(on);
|
|
draw_pressed(on);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TPush button
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TPush_button : public TButton
|
|
{
|
|
short _picup, _picdn;
|
|
short _accel, _dx, _dy;
|
|
|
|
protected:
|
|
void draw_pressed(bool pressed) const;
|
|
void update() const;
|
|
|
|
public:
|
|
TPush_button(short left, short top, short right, short bottom,
|
|
const char* caption, WINDOW parent,
|
|
long flags, long app_data, short id);
|
|
virtual ~TPush_button();
|
|
};
|
|
|
|
TPush_button::TPush_button(short left, short top, short right, short bottom,
|
|
const char* capt, WINDOW parent,
|
|
long flags, long app_data, short id)
|
|
: TButton(left-(id == DLG_F9), top, right, bottom,
|
|
capt, parent, flags, app_data, id),
|
|
_picup(0), _picdn(0)
|
|
{
|
|
switch(id)
|
|
{
|
|
|
|
case DLG_OK:
|
|
if (strcmp("Conferma", caption()) == 0)
|
|
capt = format("#%d", BMP_OK);
|
|
break;
|
|
case DLG_CANCEL:
|
|
if (strcmp("Annulla", caption()) == 0)
|
|
capt = format("#%d", BMP_CANCEL);
|
|
break;
|
|
case DLG_QUIT:
|
|
capt = format("#%d#%d", BMP_QUIT, BMP_QUITDN);
|
|
break;
|
|
case DLG_SELECT:
|
|
capt = format("#%d", BMP_SELECT);
|
|
break;
|
|
case DLG_DELREC:
|
|
capt = format("#%d#%d", BMP_DELREC, BMP_DELRECDN);
|
|
break;
|
|
case DLG_NEWREC:
|
|
if (strcmp("Nuovo", caption()) == 0) // Puo' essere Gestione
|
|
capt = format("#%d#%d", BMP_NEWREC, BMP_NEWRECDN);
|
|
break;
|
|
case DLG_STOPREC:
|
|
capt = format("#%d", BMP_STOPREC);
|
|
break;
|
|
/*
|
|
case DLG_FIRSTREC:
|
|
capt = format("#%d", BMP_FIRSTREC);
|
|
break;
|
|
case DLG_PREVREC:
|
|
capt = format("#%d", BMP_PREVREC);
|
|
break;
|
|
case DLG_NEXTREC:
|
|
capt = format("#%d", BMP_NEXTREC);
|
|
break;
|
|
case DLG_LASTREC:
|
|
capt = format("#%d", BMP_LASTREC);
|
|
break;
|
|
*/
|
|
case DLG_SAVEREC:
|
|
capt = format("#%d#%d", BMP_SAVEREC, BMP_SAVERECDN);
|
|
break;
|
|
case DLG_FINDREC:
|
|
capt = format("#%d", BMP_FINDREC);
|
|
break;
|
|
case DLG_F9:
|
|
capt = format("#%d", BMP_SEARCH);
|
|
break;
|
|
case DLG_LINK:
|
|
capt = format("#%d", BMP_LINK);
|
|
break;
|
|
case DLG_EDIT:
|
|
capt = format("#%d", BMP_EDIT);
|
|
break;
|
|
case DLG_PRINT:
|
|
capt = format("#%d", BMP_PRINT);
|
|
break;
|
|
case DLG_SETPRINT:
|
|
capt = format("#%d", BMP_SETPRINT);
|
|
break;
|
|
case DLG_RECALC:
|
|
capt = format("#%d", BMP_RECALC);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
const int height = bottom-top;
|
|
const int width = right-left;
|
|
|
|
const char* diesis = strchr(capt, '#');
|
|
if (diesis != NULL)
|
|
{
|
|
_picup = atoi(++diesis);
|
|
const TImage& pic = cpb.add(_picup);
|
|
diesis = strchr(diesis, '#');
|
|
if (diesis != NULL)
|
|
{
|
|
_picdn = atoi(++diesis);
|
|
cpb.add(_picdn);
|
|
}
|
|
|
|
_dx = (width - pic.width()) >> 1;
|
|
_dy = (height - pic.height()) >> 1;
|
|
|
|
_accel = -1;
|
|
}
|
|
else
|
|
{
|
|
TFixed_string c(capt);
|
|
_accel = c.find('~');
|
|
if (_accel > 0)
|
|
_accel *= CHARX;
|
|
|
|
_dx = (width - xvt_dwin_get_text_width(win(), (char*)caption(), -1)) >> 1;
|
|
_dy = (height-CHARY)/2 + BASEY - DEPTH;
|
|
}
|
|
}
|
|
|
|
TPush_button::~TPush_button()
|
|
{
|
|
}
|
|
|
|
void TPush_button::draw_pressed(bool pressed) const
|
|
{
|
|
TButton::draw_pressed(pressed);
|
|
|
|
if (_picup)
|
|
{
|
|
const short pic = (pressed && _picdn) ? _picdn : _picup;
|
|
if (cpb.exist(pic))
|
|
{
|
|
const TImage& i = cpb.image(pic);
|
|
RCT dst = i.rect();
|
|
if (pressed)
|
|
xvt_rect_offset(&dst, _dx+DEPTH, _dy+DEPTH);
|
|
else
|
|
xvt_rect_offset(&dst, _dx, _dy);
|
|
i.draw(_hdc, dst);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const char* t = caption();
|
|
|
|
const short x = _dx + DEPTH*pressed;
|
|
const short y = _dy + DEPTH*pressed;
|
|
|
|
xvt_dwin_set_fore_color(_hdc, COLOR_WHITE);
|
|
xvt_dwin_draw_text(_hdc, x+1, y+1, (char*)t, -1);
|
|
if (_accel >= 0)
|
|
xvt_dwin_draw_text(_hdc, x+_accel+1, y+1, "_", 1);
|
|
|
|
const COLOR c = disabled() ? DISABLED_COLOR : color();
|
|
xvt_dwin_set_fore_color(_hdc, c);
|
|
xvt_dwin_draw_text(_hdc, x, y, (char*)t, -1);
|
|
if (_accel >= 0)
|
|
xvt_dwin_draw_text(_hdc, x+_accel, y+0, "_", 1);
|
|
}
|
|
}
|
|
|
|
void TPush_button::update() const
|
|
{
|
|
draw_pressed(FALSE);
|
|
if (focused() && id() != DLG_F9)
|
|
{
|
|
CPEN pen;
|
|
pen.width = 1;
|
|
pen.pat = PAT_SOLID;
|
|
pen.style = P_SOLID;
|
|
pen.color = COLOR_RED;
|
|
xvt_dwin_set_cpen(_hdc, &pen);
|
|
CBRUSH brush = { PAT_HOLLOW, COLOR_WHITE };
|
|
xvt_dwin_set_cbrush(_hdc, &brush);
|
|
xvt_dwin_draw_rect(_hdc, &_client);
|
|
} else
|
|
if (disabled() && _picup)
|
|
{
|
|
CPEN pen;
|
|
pen.width = 1;
|
|
pen.pat = PAT_SOLID;
|
|
pen.style = P_SOLID;
|
|
pen.color = COLOR_LTGRAY;
|
|
xvt_dwin_set_cpen(_hdc, &pen);
|
|
|
|
const int sx = _client.left+DEPTH+1;
|
|
const int sy = _client.top+DEPTH+1;
|
|
const int ex = _client.right-DEPTH-1;
|
|
const int ey = _client.bottom-DEPTH-1;
|
|
|
|
for (int i = sx; i < ex; i += 2)
|
|
{
|
|
PNT p = { sy, i };
|
|
xvt_dwin_draw_set_pos(_hdc, p);
|
|
p.v = ey;
|
|
xvt_dwin_draw_line(_hdc, p);
|
|
}
|
|
for (i = sy; i < ey; i += 2)
|
|
{
|
|
PNT p = { i, sx };
|
|
xvt_dwin_draw_set_pos(_hdc, p);
|
|
p.h = ex;
|
|
xvt_dwin_draw_line(_hdc, p);
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TPage_button
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TPage_button : public TControl
|
|
{
|
|
enum { height = 19, width2 = 16, width = 32 };
|
|
byte _flag;
|
|
|
|
protected:
|
|
virtual void update() const;
|
|
virtual void mouse_down(PNT where);
|
|
virtual void mouse_up();
|
|
|
|
public:
|
|
TPage_button(WINDOW parent, byte flag);
|
|
byte get_flag() const { return _flag; }
|
|
void set_flag(byte f);
|
|
};
|
|
|
|
TPage_button::TPage_button(WINDOW parent, byte flag) : _flag(flag)
|
|
{
|
|
RCT r; xvt_vobj_get_client_rect(parent, &r);
|
|
const int w = (flag == 3) ? width : width2;
|
|
if (flag == 2) r.right -= w;
|
|
|
|
create(r.right-w, r.bottom-height, r.right, r.bottom,
|
|
"", parent, 0L, 0L, DLG_PAGE);
|
|
cpb.add(BMP_BOOK1 + flag -1, flag == 3);
|
|
}
|
|
|
|
void TPage_button::mouse_down(PNT where)
|
|
{
|
|
bool p;
|
|
switch (_flag)
|
|
{
|
|
case 1:
|
|
p = FALSE; break;
|
|
case 2:
|
|
p = TRUE;
|
|
default:
|
|
p = where.h < (width2); break;
|
|
}
|
|
check(p);
|
|
}
|
|
|
|
void TPage_button::mouse_up()
|
|
{
|
|
dispatch_e_char(xvt_vobj_get_parent(win()), checked() ? K_PREV : K_NEXT);
|
|
}
|
|
|
|
void TPage_button::update() const
|
|
{
|
|
TControl::update();
|
|
if (_flag)
|
|
cpb.image(BMP_BOOK1 + _flag -1).draw(_hdc);
|
|
}
|
|
|
|
void TPage_button::set_flag(byte f)
|
|
{
|
|
_flag = f;
|
|
update();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TTag_button
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TTag_button : public TControl
|
|
{
|
|
enum { height = 12, width = 32 };
|
|
byte _curr;
|
|
byte _page;
|
|
byte _pages;
|
|
|
|
WINDOW _parent;
|
|
|
|
protected:
|
|
virtual void update() const;
|
|
virtual void mouse_down(PNT where);
|
|
virtual void mouse_up();
|
|
|
|
public:
|
|
TTag_button(WINDOW parent, byte p, byte tot);
|
|
byte get_pages() const { return _pages; }
|
|
void set_pages(byte p);
|
|
};
|
|
|
|
TTag_button::TTag_button(WINDOW parent, byte p, byte tot)
|
|
: _parent(parent), _page(p), _pages(tot), _curr(p)
|
|
{
|
|
RCT r; xvt_vobj_get_client_rect(parent, &r);
|
|
create(0, 0, r.right, CHARY, "", parent,0L,0L, DLG_PAGETAGS);
|
|
}
|
|
|
|
void TTag_button::update() const
|
|
{
|
|
get_geometry(win());
|
|
xvt_dwin_clear(_hdc, MASK_DARK_COLOR);
|
|
|
|
for (int i = 0; i < _pages; i++)
|
|
{
|
|
RCT r; xvt_rect_set(&r, width*i, 0, width*(i+1), _client.bottom+4);
|
|
CBRUSH b = { PAT_SOLID, (i == _page) ? MASK_BACK_COLOR : MASK_DARK_COLOR};
|
|
xvt_dwin_set_cbrush(_hdc, &b);
|
|
xvt_dwin_set_std_cpen(_hdc, TL_PEN_BLACK);
|
|
xvt_dwin_draw_rect(_hdc, &r);
|
|
|
|
if (i == _page)
|
|
xvt_draw_rect(_hdc, r, MASK_LIGHT_COLOR, MASK_BACK_COLOR);
|
|
|
|
char n[4]; sprintf(n, "%d", i+1);
|
|
xvt_dwin_set_fore_color(_hdc, color());
|
|
xvt_dwin_draw_text(_hdc, (width-CHARX)/2 + i*width, BASEY, n, -1);
|
|
}
|
|
|
|
CPEN pen;
|
|
pen.width = 1;
|
|
pen.pat = PAT_SOLID;
|
|
pen.style = P_SOLID;
|
|
pen.color = MASK_LIGHT_COLOR;
|
|
xvt_dwin_set_cpen(_hdc, &pen);
|
|
|
|
PNT p = { _client.bottom, 0 };
|
|
xvt_dwin_draw_set_pos(_hdc, p);
|
|
p.h = width*_page;
|
|
xvt_dwin_draw_line(_hdc, p);
|
|
p.h += width+1;
|
|
xvt_dwin_draw_set_pos(_hdc, p);
|
|
p.h = _client.right;
|
|
xvt_dwin_draw_line(_hdc, p);
|
|
}
|
|
|
|
void TTag_button::mouse_down(PNT where)
|
|
{
|
|
_curr = where.h / width;
|
|
if (_curr >= _pages) _curr = _pages-1; else
|
|
if (_curr < 0) _curr = 0;
|
|
}
|
|
|
|
void TTag_button::mouse_up()
|
|
{
|
|
if (_curr != _page)
|
|
dispatch_e_char(_parent, K_CTRL + K_F1 + _curr);
|
|
}
|
|
|
|
void TTag_button::set_pages(byte p)
|
|
{
|
|
_pages = p;
|
|
update();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Checkbox
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TCheckbox : public TButton
|
|
{
|
|
protected:
|
|
virtual WIN_TYPE type() const;
|
|
virtual void draw_pressed(bool pressed) const;
|
|
virtual void update() const;
|
|
|
|
int radio() const { return multiple() ? 1 : 0; }
|
|
|
|
public:
|
|
TCheckbox(short left, short top, short right, short bottom,
|
|
const char* caption, WINDOW parent,
|
|
long flags, long app_data, short id);
|
|
virtual ~TCheckbox();
|
|
};
|
|
|
|
TCheckbox::TCheckbox(
|
|
short left, short top, short right, short bottom,
|
|
const char* caption, WINDOW parent,
|
|
long flags, long app_data, short id)
|
|
: TButton(left, top, right, bottom,
|
|
caption, parent, flags, app_data, id)
|
|
{
|
|
if (!cpb.exist(BMP_CHECK_ON))
|
|
{
|
|
TImage& i = cpb.add(BMP_CHECK_ON, TRUE);
|
|
|
|
const short dx = 0;
|
|
const short dy = BASEY - i.height() + 2;
|
|
i.set_pos(dx, dy);
|
|
|
|
cpb.add(BMP_CHECK_OFF, TRUE).set_pos(dx, dy);
|
|
cpb.add(BMP_RADIO_ON, TRUE).set_pos(dx, dy);
|
|
cpb.add(BMP_RADIO_OFF, TRUE).set_pos(dx, dy);
|
|
}
|
|
}
|
|
|
|
|
|
TCheckbox::~TCheckbox()
|
|
{
|
|
}
|
|
|
|
|
|
WIN_TYPE TCheckbox::type() const
|
|
{
|
|
return multiple() ? WC_RADIOBUTTON : WC_CHECKBOX;
|
|
}
|
|
|
|
|
|
void TCheckbox::draw_pressed(bool pressed) const
|
|
{
|
|
get_geometry(win());
|
|
short pic;
|
|
if (radio())
|
|
pic = pressed ? BMP_RADIO_ON : BMP_RADIO_OFF;
|
|
else
|
|
pic = pressed ? BMP_CHECK_ON : BMP_CHECK_OFF;
|
|
|
|
if (cpb.exist(pic))
|
|
cpb.image(pic).draw(_hdc);
|
|
}
|
|
|
|
|
|
void TCheckbox::update() const
|
|
{
|
|
TButton::update();
|
|
|
|
const int x = _client.left+20;
|
|
const int y = _client.top + BASEY;
|
|
|
|
if (focused())
|
|
{
|
|
#if XVT_OS == XVT_OS_WIN
|
|
RECT r;
|
|
r.left = x-2; r.top = _client.top;
|
|
r.right = _client.right-CHARX; r.bottom = y+3;
|
|
|
|
HWND hwnd = (HWND)xvt_vobj_get_attr(_hdc, ATTR_NATIVE_WINDOW);
|
|
HDC hdc = GetDC(hwnd);
|
|
DrawFocusRect(hdc, &r);
|
|
ReleaseDC(hwnd, hdc);
|
|
#endif
|
|
}
|
|
|
|
xvt_dwin_draw_text(_hdc, x, y, (char*)caption(), -1);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// User functions
|
|
///////////////////////////////////////////////////////////
|
|
|
|
WINDOW xvt_create_checkbox(
|
|
short left, short top, short right, short bottom,
|
|
const char* caption,
|
|
WINDOW parent,
|
|
long flags,
|
|
long app_data,
|
|
int id)
|
|
{
|
|
TCheckbox* cb = new TCheckbox(left, top, right, bottom,
|
|
caption, parent,
|
|
flags, app_data, id);
|
|
|
|
// It'll destroy itself automagically :-)
|
|
|
|
return cb->win();
|
|
}
|
|
|
|
WINDOW xvt_create_radiobutton(
|
|
short left, short top, short right, short bottom,
|
|
const char* caption,
|
|
WINDOW parent,
|
|
long flags,
|
|
long app_data,
|
|
int id)
|
|
{
|
|
flags |= CTL_FLAG_MULTIPLE;
|
|
TCheckbox* cb = new TCheckbox(left, top, right, bottom,
|
|
caption, parent,
|
|
flags, app_data, id);
|
|
|
|
// It'll destroy itself automagically :-)
|
|
return cb->win();
|
|
}
|
|
|
|
|
|
WINDOW xvt_create_pushbutton(
|
|
short left, short top, short right, short bottom,
|
|
const char* caption,
|
|
WINDOW parent,
|
|
long flags,
|
|
long app_data,
|
|
int id)
|
|
{
|
|
TControl* pb;
|
|
|
|
switch (id)
|
|
{
|
|
case DLG_PAGE:
|
|
pb = new TPage_button(parent, (byte)flags);
|
|
break;
|
|
case DLG_PAGETAGS:
|
|
pb = new TTag_button(parent, (byte)flags, (byte)app_data);
|
|
break;
|
|
default:
|
|
if (bottom-top > (CHARY<<1))
|
|
{
|
|
top += BASEY>>1;
|
|
bottom -= BASEY>>1;
|
|
}
|
|
pb = new TPush_button(left, top, right, bottom,
|
|
caption, parent,
|
|
flags, app_data, id);
|
|
}
|
|
|
|
// It'll destroy itself automagically :-)
|
|
return pb->win();
|
|
}
|
|
|
|
|
|
WINDOW xvt_create_text(
|
|
short left, short top, short right, short bottom,
|
|
const char* caption,
|
|
WINDOW parent,
|
|
long flags,
|
|
long app_data,
|
|
int id)
|
|
{
|
|
TText* cb = new TText(left, top, right, bottom,
|
|
caption, parent,
|
|
flags, app_data, id);
|
|
// It'll destroy itself automagically :-)
|
|
return cb->win();
|
|
}
|
|
|
|
|
|
WINDOW xvt_create_groupbox(
|
|
short left, short top, short right, short bottom,
|
|
const char* caption,
|
|
WINDOW parent,
|
|
long flags,
|
|
long app_data,
|
|
int id)
|
|
{
|
|
TGroup* cb = new TGroup(left, top, right, bottom,
|
|
caption, parent,
|
|
flags, app_data, id);
|
|
// It'll destroy itself automagically :-)
|
|
return cb->win();
|
|
}
|
|
|
|
|
|
void free_controls_bmp()
|
|
{
|
|
cpb.destroy();
|
|
}
|
|
|
|
|
|
TControl* TControl::WINDOW2TControl(WINDOW win)
|
|
{
|
|
CHECK(win, "Can't get the control model from a NULL window");
|
|
TControl** model = (TControl**)xvtcm_get_model(win, 0);
|
|
CHECK(model && *model, "Can't get the control model from a window");
|
|
return *model;
|
|
}
|
|
|
|
void xvt_change_page_tags(WINDOW pag, bool on, WINDOW tag, byte p)
|
|
{
|
|
if (pag != NULL_WIN)
|
|
{
|
|
TPage_button* pb = (TPage_button*)TControl::WINDOW2TControl(pag);
|
|
byte f = pb->get_flag();
|
|
if (on) f |= 0x1;
|
|
else f &= 0x2;
|
|
pb->set_flag(f);
|
|
}
|
|
|
|
if (tag != NULL_WIN)
|
|
{
|
|
TTag_button* pt = (TTag_button*)TControl::WINDOW2TControl(tag);
|
|
pt->set_pages(p);
|
|
}
|
|
}
|
|
|
|
|