campo-sirio/include/controls.cpp
alex c40612059d Aggiunto XVT_CALLCONV1 e supporto per WATCOM C++
git-svn-id: svn://10.65.10.50/trunk@1142 c028cbd2-c16b-5b4b-a496-9718f37d4682
1995-03-16 13:44:11 +00:00

1164 lines
25 KiB
C++
Executable File

extern "C"
{
#include <xvt.h>
#include <xvtcm.h>
#include <cpb.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 <xvtility.h>
#include <windows.h>
///////////////////////////////////////////////////////////
// TPicture_array
///////////////////////////////////////////////////////////
class TPicture_array
{
enum { MAXPIC = 128 };
PICTURE _picture[MAXPIC];
public:
PICTURE getbmp(short id, bool convert = FALSE);
PICTURE operator[](short id) { return _picture[id-BMP_OK]; }
void reset();
TPicture_array();
~TPicture_array() { reset(); }
};
HIDDEN byte COLOR2PIC(COLOR c)
{
static unsigned long color[16][2] =
{
0x000000, 0x00, // BLACK
0x0000FF, 0x04, // BLUE
0x000080, 0x0C, // LTBLUE
0x008000, 0x02, // DKGREEN
0x008080, 0x06, // DKCYAN
0x00FF00, 0xFA, // GREEN
0x00FFFF, 0xFE, // CYAN
0x800000, 0x01, // DKRED
0x800080, 0xFD, // DKMAGENTA
0x808000, 0x03, // DKYELLOW
0x808080, 0xF8, // GRAY
0xC0C0C0, 0x07, // LTGRAY
0xFF0000, 0xF9, // RED
0xFF00FF, 0x05, // MAGENTA
0xFFFF00, 0xFB, // YELLOW
0xFFFFFF, 0xFF, // WHITE
};
int idx, f = 0, l = 15;
c &= 0x00FFFFFF;
while (TRUE)
{
idx = (f+l)>>1;
if (c == color[idx][0]) break;
if (c > color[idx][0]) f = idx+1;
else l = idx-1;
if (f > l)
{
break;
}
}
const byte b = (byte)color[idx][1];
return b;
}
PICTURE xvt_picture_load(short id, bool convert)
{
static bool _can_convert = 2;
if (_can_convert == 2)
{
HWND hwnd = (HWND)get_value(TASK_WIN, ATTR_NATIVE_WINDOW);
HDC hdc = GetDC(hwnd);
const int bits = GetDeviceCaps(hdc, BITSPIXEL);
_can_convert = bits == 8;
ReleaseDC(hwnd, hdc);
}
PICTURE cpb = cpb_picture_load(id);
CHECKD(cpb, "Can't load picture ", id);
if (convert && _can_convert && MASK_BACK_COLOR != COLOR_DKCYAN)
{
long size;
char huge * buf = picture_lock(cpb, &size);
if (buf != NULL)
{
RCT r; cpb_get_picture_size(cpb, &r);
const byte newba = COLOR2PIC(MASK_BACK_COLOR);
const byte newlt = COLOR2PIC(MASK_LIGHT_COLOR);
const byte newdk = COLOR2PIC(MASK_DARK_COLOR);
const long first = 14;
const long last = first + (long)r.right*r.bottom;
for (long i = first; i < last; i++) switch((byte)buf[i])
{
case 0x06:
buf[i] = newba; break;
case 0xF8:
buf[i] = newdk; break;
case 0xFE:
buf[i] = newlt; break;
default:
break;
}
const PICTURE old = cpb;
cpb = picture_make(buf, size, &r);
picture_unlock(old);
picture_free(old);
}
}
return cpb;
}
PICTURE TPicture_array::getbmp(short id, bool convert)
{
const int i = id-BMP_OK;
CHECKD(i >= 0 && i < MAXPIC, "Control ID out of range", id);
if (_picture[i] != NULL)
{
if (i < 100) return _picture[i];
picture_free(_picture[i]);
}
_picture[i] = xvt_picture_load(id, convert);
if (_picture[i] == NULL)
error_box("Can't load picture %d", id);
return _picture[i];
}
TPicture_array::TPicture_array()
{
memset(_picture, 0, sizeof(_picture));
}
void TPicture_array::reset()
{
for (int i = 0; i < MAXPIC; i++)
if (_picture[i] != NULL)
{
picture_free(_picture[i]);
_picture[i] = NULL;
}
}
///////////////////////////////////////////////////////////
// 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)
{
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;)
{
win_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;
win_move_to(win, p);
p.v = r.top;
win_draw_line(win, p);
p.h = r.right;
win_draw_line(win, p);
drawed = TRUE;
}
if (rb != COLOR_LTGRAY)
{
if (pen.color != rb)
{
pen.color = rb;
win_set_cpen(win, &pen);
}
if (!drawed)
{
p.h = r.right; p.v = r.top;
win_move_to(win, p);
}
p.v = r.bottom;
win_draw_line(win, p);
p.h = r.left;
win_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 = *title == '@';
if (bold) title += 2;
const int prop_count = 1;
const char* prop_list[prop_count+1] = { title, NULL };
_id = id;
_caption = title; _caption.strip("~");
_disabled = (flags & CTL_FLAG_DISABLED) != 0;
_checked = (flags & CTL_FLAG_CHECKED) != 0;
_multiple = (flags & CTL_FLAG_MULTIPLE) != 0;
_focused = FALSE;
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;
set_app_data(_win, app_data);
xvt_set_font(_win, FF_FIXED, bold ? FS_BOLD : 0);
}
// Virtual destructor needed to make derived descrutors live!
TControl::~TControl()
{}
long XVT_CALLCONV1 TControl::handler(WINDOW win, EVENT* ep)
{
static bool tracking = FALSE;
static 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:
trap_mouse(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(get_parent(win), key);
break;
}
}
break;
case E_MOUSE_MOVE:
if (tracking)
{
RCT r;
get_client_rect(win, &r);
if (pt_in_rect(&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)
{
release_mouse();
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();
enable_window(win(), on);
}
}
void TControl::check(bool on)
{
_checked = on;
}
void TControl::update() const
{
if (_win != _hdc)
get_geometry(_win);
clear_window(_hdc, MASK_BACK_COLOR);
win_set_fore_color(_hdc, disabled() ? DISABLED_COLOR : NORMAL_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();
win_set_fore_color(_hdc, NORMAL_COLOR);
win_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;
win_set_cpen(_hdc, &pen);
CBRUSH brush = { PAT_HOLLOW, MASK_BACK_COLOR };
win_set_cbrush(_hdc, &brush);
win_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());
clear_window(_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();
dispatch_event(get_parent(win()), &e);
}
void TButton::check(bool on)
{
TControl::check(on);
draw_pressed(on);
}
///////////////////////////////////////////////////////////
// TPush button
///////////////////////////////////////////////////////////
class TPush_button : public TButton
{
PICTURE _picup, _picdn;
byte _dx, _dy;
int _accel;
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(0L), _picdn(0L)
{
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)
{
int pid = atoi(++diesis);
_picup = cpb.getbmp(pid);
diesis = strchr(diesis, '#');
if (diesis != NULL)
{
pid = atoi(++diesis);
_picdn = cpb.getbmp(pid);
}
RCT r;
cpb_get_picture_size(_picup, &r);
_dx = byte((width-r.right+1) >> 1);
_dy = byte((height-r.bottom) >> 1);
_accel = -1;
}
else
{
TFixed_string c(capt);
_accel = c.find('~');
if (_accel > 0)
_accel *= CHARX;
_dx = (width - win_get_text_width(win(), (char*)caption(), -1)) >> 1;
_dy = byte((height-CHARY)/2 + BASEY - DEPTH);
}
}
TPush_button::~TPush_button()
{
}
void TPush_button::draw_pressed(bool pressed) const
{
TButton::draw_pressed(pressed);
const int p = pressed ? DEPTH : 0;
if (_picup)
{
const PICTURE pic = (pressed && _picdn) ? _picdn : _picup;
cpb_win_picture_draw_at(_hdc, pic, _dx+p, _dy+p);
}
else
{
const char* t = caption();
win_set_fore_color(_hdc, COLOR_WHITE);
win_draw_text(_hdc, _dx+p+1, _dy+p+1, (char*)t, -1);
if (_accel >= 0)
win_draw_text(_hdc, _dx+_accel+p+1, _dy+p+3, "_", 1);
const COLOR c = disabled() ? DISABLED_COLOR : NORMAL_COLOR;
win_set_fore_color(_hdc, c);
win_draw_text(_hdc, _dx+p, _dy+p, (char*)t, -1);
if (_accel >= 0)
win_draw_text(_hdc, _dx+_accel+p, _dy+p+2, "_", 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;
win_set_cpen(_hdc, &pen);
CBRUSH brush = { PAT_HOLLOW, COLOR_WHITE };
win_set_cbrush(_hdc, &brush);
win_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;
win_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 };
win_move_to(_hdc, p);
p.v = ey;
win_draw_line(_hdc, p);
}
for (i = sy; i < ey; i += 2)
{
PNT p = { i, sx };
win_move_to(_hdc, p);
p.h = ex;
win_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; 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.getbmp(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(get_parent(win()), checked() ? K_PREV : K_NEXT);
}
void TPage_button::update() const
{
TControl::update();
if (_flag)
cpb_win_picture_draw_at(_hdc, cpb[BMP_BOOK1 + _flag -1], 0, 0);
}
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; get_client_rect(parent, &r);
create(0, 0, r.right, CHARY, "", parent,0L,0L, DLG_PAGETAGS);
}
void TTag_button::update() const
{
get_geometry(win());
clear_window(_hdc, MASK_DARK_COLOR);
for (int i = 0; i < _pages; i++)
{
RCT r; set_rect(&r, width*i, 0, width*(i+1), _client.bottom+4);
CBRUSH b = { PAT_SOLID, (i == _page) ? MASK_BACK_COLOR : MASK_DARK_COLOR};
win_set_cbrush(_hdc, &b);
win_set_std_cpen(_hdc, TL_PEN_BLACK);
win_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);
win_set_fore_color(_hdc, NORMAL_COLOR);
win_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;
win_set_cpen(_hdc, &pen);
PNT p = { _client.bottom, 0 };
win_move_to(_hdc, p);
p.h = width*_page;
win_draw_line(_hdc, p);
p.h += width+1;
win_move_to(_hdc, p);
p.h = _client.right;
win_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
{
static int _dy;
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();
};
int TCheckbox::_dy = -1;
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 (_dy < 0)
{
cpb.getbmp(BMP_CHECK_ON, TRUE);
cpb.getbmp(BMP_CHECK_OFF, TRUE);
cpb.getbmp(BMP_RADIO_ON, TRUE);
PICTURE p = cpb.getbmp(BMP_RADIO_OFF, TRUE);
RCT r;
cpb_get_picture_size(p, &r);
_dy = BASEY - r.bottom + 2;
}
}
TCheckbox::~TCheckbox()
{
}
WIN_TYPE TCheckbox::type() const
{
return multiple() ? WC_RADIOBUTTON : WC_CHECKBOX;
}
void TCheckbox::draw_pressed(bool pressed) const
{
get_geometry(win());
PICTURE pic;
if (radio())
pic = pressed ? cpb[BMP_RADIO_ON] : cpb[BMP_RADIO_OFF];
else
pic = pressed ? cpb[BMP_CHECK_ON] : cpb[BMP_CHECK_OFF];
cpb_win_picture_draw_at(_hdc, pic, _client.left, _client.top+_dy);
}
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)get_value(_hdc, ATTR_NATIVE_WINDOW);
HDC hdc = GetDC(hwnd);
DrawFocusRect(hdc, &r);
ReleaseDC(hwnd, hdc);
#endif
}
win_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.reset();
}
TControl* TControl::WINDOW2TControl(WINDOW win)
{
TControl** model = (TControl**)xvtcm_get_model(win, 0);
CHECK(model && *model, "Can't get the 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);
}
}