diff --git a/include/applicat.cpp b/include/applicat.cpp index 3f0f1adf9..520528ce5 100755 --- a/include/applicat.cpp +++ b/include/applicat.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -53,12 +54,7 @@ bool xvt_running() { return _application != NULL; } HIDDEN long backdrop_eh( WINDOW win, EVENT* ep) { -#if XVT_OS == XVT_OS_WIN - clear_window( win, COLOR_GRAY ); -#else - clear_window( win, COLOR_BLUE ); -#endif - + clear_window(win, MASK_DARK_COLOR); return 0L; } @@ -648,6 +644,27 @@ bool TApplication::config() return ok; } +void TApplication::set_cursor(bool w) +{ + static _count = 0; + if (w) + { + _count++; + if (_count == 1) + ::set_cursor(TASK_WIN, CURSOR_WAIT); + } + else + { + _count--; +#ifdef DBG + if (_count >= 0) + yesnofatal_box("end_wait without matching begin_wait"); +#endif + if (_count == 0) + ::set_cursor(TASK_WIN, CURSOR_ARROW); + } +} + void TApplication::on_firm_change() {} diff --git a/include/applicat.h b/include/applicat.h index 02c92f1cb..795d795e7 100755 --- a/include/applicat.h +++ b/include/applicat.h @@ -37,7 +37,12 @@ class TApplication word _waiting; static TString16 _user; - + + void terminate(); // End of application + void set_cursor(bool w); // Change mouse cursor + bool config(); // Change parameters + void about() const; // About box + protected: const char* get_module_name() const; static long task_eh(WINDOW win, EVENT* ep); @@ -58,10 +63,6 @@ protected: void set_user(const char * user) { _user = user; } void set_perms(); - void terminate(); - bool config(); - void about() const; - public: // @FPUB @@ -101,6 +102,9 @@ public: void wait_for(word taskid) { _waiting = taskid; } void wake_up() { _waiting = 0; } word waiting() const { return _waiting; } + + void begin_wait() { set_cursor(TRUE); } // Set CURSOR_WAIT + void end_wait() { set_cursor(FALSE); } // Set CURSOR_ARROW TApplication(); virtual ~TApplication(); diff --git a/include/bagn001a.uml b/include/bagn001a.uml index 2fb7fe1be..d954cb679 100755 --- a/include/bagn001a.uml +++ b/include/bagn001a.uml @@ -94,13 +94,7 @@ END BOOLEAN MSK_1_ISGRAPHICS BEGIN - PROMPT 4 8 "Salva configurazione" - HELP "Indicare se stampare elementi grafici (linee, box, logo) quando la stampante lo consente" -END - -BOOLEAN MSK_1_ISGRAPHICS -BEGIN - PROMPT 4 9 "Stampa elementi grafici" + PROMPT 4 8 "Stampa elementi grafici" HELP "Indicare se stampare elementi grafici (linee, box, logo) quando la stampante lo consente" END diff --git a/include/colors.h b/include/colors.h index e5bffc494..0c2354870 100755 --- a/include/colors.h +++ b/include/colors.h @@ -5,8 +5,9 @@ #include #endif -extern COLOR MASK_COLOR; extern COLOR MASK_BACK_COLOR; +extern COLOR MASK_LIGHT_COLOR; +extern COLOR MASK_DARK_COLOR; extern COLOR NORMAL_COLOR; extern COLOR NORMAL_BACK_COLOR; extern COLOR DISABLED_COLOR; @@ -16,6 +17,10 @@ extern COLOR FOCUS_BACK_COLOR; const COLOR COLOR_DKCYAN = MAKE_COLOR(0,128,128); const COLOR COLOR_DKYELLOW = MAKE_COLOR(128,128, 0); +const COLOR COLOR_DKGREEN = MAKE_COLOR(0,128, 0); +const COLOR COLOR_DKBLUE = MAKE_COLOR(0,0,128); +const COLOR COLOR_DKRED = MAKE_COLOR(128,0, 0); +const COLOR COLOR_DKMAGENTA = MAKE_COLOR(128,0,128); #endif diff --git a/include/controls.cpp b/include/controls.cpp index 288b91c20..aeececad8 100755 --- a/include/controls.cpp +++ b/include/controls.cpp @@ -1,1114 +1,1139 @@ -extern "C" -{ -#include -#include -#include -} - -#if XVT_OS != XVT_OS_WIN -#error "This file should be compiled for Windows only" -#endif - -#include -#include -#include -#include -#include - -#include - -/////////////////////////////////////////////////////////// -// 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) -{ - byte b; - switch (c) - { - case COLOR_DKYELLOW: - b = 0x03; break; - case COLOR_DKCYAN: - b = 0x06; break; - case COLOR_CYAN: - b = 0xF8; break; - case COLOR_YELLOW: - b = 0xFB; break; - default: - b = 0x00; break; - } - return b; -} - - -PICTURE xvt_picture_load(short id, bool convert) -{ - PICTURE cpb = cpb_picture_load(id); - - if (convert && MASK_BACK_COLOR != COLOR_DKCYAN) - { - const byte newdk = COLOR2PIC(MASK_BACK_COLOR); - const byte newlt = COLOR2PIC(MASK_COLOR); - const PICTURE old = cpb; - RCT r; cpb_get_picture_size(old, &r); - long size; - char* buf = picture_lock(old, &size); - CHECK(buf, "Out of memory in picture_load"); - cpb = picture_make(buf, size, &r); - const int first = 14; - const int last = first + r.right*r.bottom; - for (int i = first; i < last; i++) switch(buf[i]) - { - case 0x06: - buf[i] = newdk; break; - case 0xF8: - buf[i] = newlt; break; - default: - break; - } - 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 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() ? COLOR_GRAY : COLOR_BLACK); -} - -/////////////////////////////////////////////////////////// -// 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, COLOR_BLACK); - 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, COLOR_BLUE); - } - else - { - xvt_draw_rect(_hdc, r, COLOR_GRAY, MASK_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; - 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, COLOR_GRAY); - - 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 : COLOR_GRAY }; - 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_COLOR, COLOR_GRAY); - - char n[4]; sprintf(n, "%d", i+1); - 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_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); - } -} - - +extern "C" +{ +#include +#include +#include +} + +#if XVT_OS != XVT_OS_WIN +#error "This file should be compiled for Windows only" +#endif + +#include +#include +#include +#include +#include + +#include + +/////////////////////////////////////////////////////////// +// 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) +{ + PICTURE cpb = cpb_picture_load(id); + + if (convert && MASK_BACK_COLOR != COLOR_DKCYAN) + { + const byte newba = COLOR2PIC(MASK_BACK_COLOR); + const byte newlt = COLOR2PIC(MASK_LIGHT_COLOR); + const byte newdk = COLOR2PIC(MASK_DARK_COLOR); + const PICTURE old = cpb; + RCT r; cpb_get_picture_size(old, &r); + long size; + char huge * buf = picture_lock(old, &size); + CHECK(buf, "Out of memory in picture_load"); + 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; + } + 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 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); +} + +/////////////////////////////////////////////////////////// +// 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; + 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); + } +} + + diff --git a/include/form.cpp b/include/form.cpp index 7bfdbacad..555e57fe7 100755 --- a/include/form.cpp +++ b/include/form.cpp @@ -452,6 +452,7 @@ protected: virtual void read_from(const TMask& m); virtual bool parse_item(TScanner&); + virtual bool read(); virtual bool update(); const char* get() const; @@ -462,8 +463,6 @@ protected: TFieldref& field(int i) const { return (TFieldref&)_field[i]; } void put_paragraph(const char* s); - bool read(); - public: TForm_string(TPrint_section* section) : TForm_item(section) {} virtual ~TForm_string() {} @@ -569,6 +568,7 @@ void TForm_string::put_paragraph(const char* s) bool TForm_string::update() { TForm_item::update(); + if (read()) { if (_picture.not_empty()) @@ -579,7 +579,8 @@ bool TForm_string::update() } else put_paragraph(get()); - } + } + return TRUE; } @@ -632,7 +633,9 @@ class TForm_date : public TForm_string { protected: virtual const char* class_name() const { return "DATA"; } + virtual bool read(); virtual bool set(const char*); + bool set(const TDate& d); public: TForm_date(TPrint_section* section); @@ -642,24 +645,30 @@ public: TForm_date::TForm_date(TPrint_section* section) : TForm_string(section) -{ - if (automagic()) - { - TDate oggi(TODAY); - set(oggi.string()); - } -} +{} +bool TForm_date::read() +{ + bool ok = TForm_string::read(); + if ((!ok || !get()[0]) && automagic()) + { + set(main_app().printer().getdate()); + ok = TRUE; + } + return ok; +} bool TForm_date::set(const char* s) { const TDate d(s); TForm_string::set(d.string((width() == 8) ? 2 : 4)); -#ifdef DBG - return d.ok(); -#else return TRUE; -#endif +} + +bool TForm_date::set(const TDate& d) +{ + TForm_string::set(d.string((width() == 8) ? 2 : 4)); + return TRUE; } /////////////////////////////////////////////////////////// diff --git a/include/mask.cpp b/include/mask.cpp index c427c25e4..75e0762fd 100755 --- a/include/mask.cpp +++ b/include/mask.cpp @@ -118,10 +118,10 @@ void TMask::handler(WINDOW win, EVENT* ep) if (win != toolwin()) { clear_window(win, MASK_BACK_COLOR); - RCT r; get_client_rect(win, &r); - xvt_draw_rect(win, r, MASK_COLOR, COLOR_GRAY, 1); + RCT r; get_client_rect(win, &r); r.right--; r.bottom--; + xvt_draw_rect(win, r, MASK_LIGHT_COLOR, MASK_DARK_COLOR, 1); } - else clear_window(win, COLOR_GRAY); + else clear_window(win, MASK_DARK_COLOR); #else clear_window(win, MASK_BACK_COLOR); #endif diff --git a/include/printer.h b/include/printer.h index 8d85a0659..3494369ca 100755 --- a/include/printer.h +++ b/include/printer.h @@ -258,6 +258,7 @@ public: bool print (TPrintrow& rowtoprint); bool isopen() { return _isopen; } void setdate(const TDate& d) { _date = d; } + const TDate& getdate() const { return _date; } TPrtype printtype() { return _printertype; } void set_printtype(TPrtype dest) { _printertype=dest; } void set_printerfile(const char * ffile) { _printerfile=ffile; } diff --git a/include/sheet.cpp b/include/sheet.cpp index b5243b897..2dd6c236d 100755 --- a/include/sheet.cpp +++ b/include/sheet.cpp @@ -462,11 +462,11 @@ bool TSheet::update_row(long n) if (chk) { changed = TRUE; - set_color(MASK_BACK_COLOR, COLOR_LTGRAY); + set_color(MASK_BACK_COLOR, NORMAL_BACK_COLOR); } else if (_disabled[n]) { - set_color(COLOR_GRAY, COLOR_LTGRAY); + set_color(DISABLED_COLOR, NORMAL_BACK_COLOR); changed = TRUE; } @@ -497,7 +497,7 @@ bool TSheet::update_row(long n) stringat(x1, y, s); } if (changed) - set_color(COLOR_BLACK, COLOR_LTGRAY); + set_color(NORMAL_COLOR, NORMAL_BACK_COLOR); return TRUE; } @@ -520,9 +520,9 @@ void TSheet::update() { if (_last_update < 0) { - set_color(COLOR_BLACK, COLOR_WHITE); - set_brush(COLOR_WHITE); - set_pen(COLOR_BLACK); + set_color(NORMAL_COLOR, NORMAL_BACK_COLOR); + set_pen(NORMAL_COLOR); + set_brush(NORMAL_BACK_COLOR); set_font(FF_FIXED); _visible_rows = rows() - reserved_rows() - head_on(); } diff --git a/include/tabapp.cpp b/include/tabapp.cpp new file mode 100755 index 000000000..623a90228 --- /dev/null +++ b/include/tabapp.cpp @@ -0,0 +1,75 @@ + +#include +#include +#include +#include +#include +#include + +void Tab_application::print() +{ +#if XVT_OS == XVT_OS_WIN + TExternal_app stampa(format("ba3a -1 %s", (const char *) _tabname)); +#else + TExternal_app stampa(format("ba3 -1 %s", (const char *) _tabname)); +#endif + stampa.run(); +} + +void Tab_application::init_query_mode(TMask& m) +{ + m.send_key(K_SHIFT + K_CTRL + 'e', -GR_MODIFY_PROTECTED); + m.send_key(K_SHIFT + K_CTRL + 'e', -GR_RECORD_PROTECTED); +} + +void Tab_application::init_modify_mode(TMask& m) +{ + m.send_key(K_SHIFT + K_CTRL + 'd', -GR_MODIFY_PROTECTED); + const bool enable = !(_rel->curr().get_bool(FPC)); + + m.send_key(K_SHIFT + K_CTRL + 'd' + enable, -GR_RECORD_PROTECTED); +} + +bool Tab_application::protected_record(TRectype& rec) +{ + return rec.get_bool(FPC); +} + +bool Tab_application::user_create() +{ + if (argc() < 3) + return FALSE; + + _tabname = argv(2); + + if (_tabname.empty()) + return FALSE; + + _tabname.upper(); + TString16 m, t(_tabname); + + if (t[0] == '%') t.ltrim(1); + + m << "BATB" << t; + _msk = new TMask(m) ; + + for (int i = 0; i < _msk->fields(); i++) + if (_msk->fld(i).in_group(GR_SEARCH)) + { + set_search_field(_msk->fld(i).dlg()); + break; + } + + _rel = new TRelation(_tabname); + set_title(_msk->get_caption()); + + return TRUE; +} + +bool Tab_application::user_destroy() +{ + if (_msk) delete _msk; + if (_rel) delete _rel; + return TRUE; +} + diff --git a/include/tabapp.h b/include/tabapp.h new file mode 100755 index 000000000..b8adb5ed7 --- /dev/null +++ b/include/tabapp.h @@ -0,0 +1,38 @@ +#ifndef __TABAPP_H +#define __TABAPP_H + +#ifndef __RELAPP_H +#include +#endif + +#define GR_SEARCH 29 +#define GR_MODIFY_PROTECTED 30 +#define GR_RECORD_PROTECTED 31 + +#define FPC "FPC" + +class Tab_application : public TRelation_application +{ + TMask* _msk; + TRelation* _rel; + TString16 _tabname; + +protected: + virtual bool protected_record(TRectype& rec); + virtual TMask* get_mask(int mode = NO_MODE) { return _msk;} + virtual bool changing_mask(int mode) { return FALSE;} + virtual TRelation* get_relation() const { return _rel;} + virtual void init_query_mode(TMask& m); + virtual void init_modify_mode(TMask& m); + virtual bool user_create() ; + virtual bool user_destroy() ; + virtual void print(); + +public: + Tab_application() : _msk(NULL), _rel(NULL) {} + virtual ~Tab_application() {} + const TString& get_tabname() const { return _tabname; } +}; + +#endif + diff --git a/include/xvtility.cpp b/include/xvtility.cpp index 5b609de78..3d1f0cb58 100755 --- a/include/xvtility.cpp +++ b/include/xvtility.cpp @@ -26,6 +26,7 @@ short BASEY = 8; short ROWY = 8; COLOR MASK_BACK_COLOR = COLOR_WHITE; +COLOR MASK_DARK_COLOR = COLOR_BLUE; COLOR NORMAL_COLOR = COLOR_BLACK; COLOR NORMAL_BACK_COLOR = COLOR_WHITE; COLOR DISABLED_COLOR = COLOR_GRAY; @@ -75,8 +76,9 @@ HIDDEN LOGFONT LogFont; HIDDEN int FontWeight; -COLOR MASK_COLOR = COLOR_CYAN; COLOR MASK_BACK_COLOR = COLOR_DKCYAN; +COLOR MASK_LIGHT_COLOR = COLOR_CYAN; +COLOR MASK_DARK_COLOR = COLOR_GRAY; COLOR NORMAL_COLOR = COLOR_BLACK; COLOR NORMAL_BACK_COLOR = COLOR_LTGRAY; COLOR DISABLED_COLOR = COLOR_GRAY; @@ -490,8 +492,9 @@ void customize_controls(bool on) { TConfig colors(CONFIG_GENERAL, "Colors"); - MASK_COLOR = colors.get_color("Mask", NULL, -1, MASK_COLOR); MASK_BACK_COLOR = colors.get_color("MaskBack", NULL, -1, MASK_BACK_COLOR); + MASK_LIGHT_COLOR = colors.get_color("MaskLight", NULL, -1, MASK_LIGHT_COLOR); + MASK_DARK_COLOR = colors.get_color("MaskDark", NULL, -1, MASK_DARK_COLOR); NORMAL_COLOR = colors.get_color("Normal", NULL, -1, NORMAL_COLOR); NORMAL_BACK_COLOR = colors.get_color("NormalBack", NULL, -1, NORMAL_BACK_COLOR); DISABLED_COLOR = colors.get_color("Disabled", NULL, -1, DISABLED_COLOR);