#define XI_INTERNAL #include #include #include #include #include #include #include #include /////////////////////////////////////////////////////////// // TField_window /////////////////////////////////////////////////////////// #ifndef INCL_XI extern "C" { void xi_draw_3d_rect( WINDOW win, RCT* rctp, BOOLEAN well, int height, COLOR color_light, COLOR color_ctrl, COLOR color_dark ); } #endif void TField_window::handler(WINDOW win, EVENT* ep) { switch (ep->type) { case E_FOCUS: if (ep->v.active) { WINDOW parent = xvt_vobj_get_parent(win); XI_OBJ* itf = xi_get_itf((XinWindow)parent); xi_set_focus(itf); } break; case E_MOUSE_DOWN: if (ep->v.mouse.button == 1 && _owner != NULL) { _owner->on_key(K_F11); return; } break; default: break; } TScroll_window::handler(win, ep); } bool TField_window::on_key(KEY k) { if (k == K_TAB || k == K_BTAB || k == K_F3 || k == K_F4) { const TMask& m = _owner->mask(); const short id = _owner->dlg(); const int start = m.id2pos(id); const int dir = (k == K_TAB || k == K_F3) ? +1 : -1; int pos = start; while (TRUE) { pos += dir; if (pos < 0) pos = m.fields()-1; if (pos >= m.fields()) pos = 0; if (pos == start) break; TMask_field& f = m.fld(pos); if (f.is_operable()) { f.set_focus(); return TRUE; } } } return TScroll_window::on_key(k); } void TField_window::update() { const WINDOW me = win(); if (CAMPI_SCAVATI) { const WINDOW pa = parent(); RCT rct; xvt_vobj_get_outer_rect(me, &rct); rct.left -= 2; rct.top -= 2; rct.right += 2; rct.bottom += 2; xi_draw_3d_rect((XinWindow)pa, (XinRect *) &rct, TRUE, 2, MASK_LIGHT_COLOR, MASK_BACK_COLOR, MASK_DARK_COLOR); } xvt_dwin_clear(me, NORMAL_BACK_COLOR); set_font(); } // Serve quando si chiama il costruttore senza owner void TField_window::set_owner(TWindowed_field* o) { _owner = o; } TField_window::TField_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner) : _owner(owner) { if (owner != NULL) { CHECK(parent, "Null control parent"); create(x, y, dx, dy, "", WSF_HSCROLL | WSF_VSCROLL, W_PLAIN, parent); activate(owner->enabled()); if (owner->shown()) open(); } } /////////////////////////////////////////////////////////// // TWindowed field /////////////////////////////////////////////////////////// void TWindowed_field::enable(bool on) { TOperable_field::enable(on); if (_win) _win->activate(on); } void TWindowed_field::show(bool on) { TOperable_field::show(on); if (_win && _win->is_open() != on) { if (on) _win->open(); else _win->close(); } } void TWindowed_field::highlight() const { if (_win && active()) _win->set_focus(); } RCT& TWindowed_field::get_rect(RCT& r) const { if (_win) xvt_vobj_get_outer_rect(_win->win(), &r); else xvt_rect_set_empty(&r); return r; } void TWindowed_field::set_rect(const RCT& r) { if (_win) xvt_vobj_move(_win->win(), (RCT*)&r); } word TWindowed_field::class_id() const { return CLASS_WINDOWED_FIELD; } bool TWindowed_field::is_kind_of(word id) const { return id == CLASS_WINDOWED_FIELD || TOperable_field::is_kind_of(id); } const char* TWindowed_field::class_name() const { return "WINDOWED"; } short TWindowed_field::dlg() const { return _dlg ? _dlg : _ctl_data._dlg; } void TWindowed_field::parse_head(TScanner& scanner) { _ctl_data._width = scanner.integer(); _ctl_data._height = scanner.integer(); } TField_window* TWindowed_field::create_window(int x, int y, int dx, int dy, WINDOW parent) { // Must be always overridden and look like this return new TField_window(x, y, dx, dy, parent, this); } void TWindowed_field::create(short id, int x, int y, int dx, int dy, WINDOW parent) { if (parent == NULL_WIN) parent = mask().win(); _dlg = id; _win = create_window(x, y, dx, dy, parent); } void TWindowed_field::create(WINDOW parent) { create(_ctl_data._dlg, _ctl_data._x, _ctl_data._y, _ctl_data._width, _ctl_data._height, parent); } TWindowed_field::TWindowed_field(TMask* m) : TOperable_field(m), _dlg(0), _win(NULL) { } TWindowed_field::~TWindowed_field() { if (_win) delete _win; } /////////////////////////////////////////////////////////// // TControl_host_window /////////////////////////////////////////////////////////// void TControl_host_window::handler(WINDOW win, EVENT* ep) { switch (ep->type) { case E_SIZE: if (_ctrl != NULL_WIN) { RCT rct; xvt_rect_set(&rct, 0, 0, ep->v.size.width, ep->v.size.height); xvt_vobj_move(_ctrl, &rct); } break; case E_UPDATE: if (_ctrl != NULL_WIN) return; // Inutile disegnare: _ctrl occupa tutta la client area break; default: break; } TField_window::handler(win, ep); } TControl_host_window::TControl_host_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner) : TField_window(x, y, dx, dy, parent, owner), _ctrl(NULL_WIN) { set_scroll_max(0, 0); // Get rid of that useless scrollbars } /////////////////////////////////////////////////////////// // TTree_window /////////////////////////////////////////////////////////// class TTree_window : public TControl_host_window { TTree* _tree; bool _hide_leaves; TAuto_token_string _header; private: void create_children(XVT_TREEVIEW_NODE node); void handle_tree_event(EVENT* ep); bool add_child(XVT_TREEVIEW_NODE parent); protected: // TWindow virtual void update(); virtual void handler(WINDOW win, EVENT* ep); virtual void force_update(); public: TTree* tree() const { return _tree; } void set_tree(TTree* tree); void hide_leaves(bool yes) { _hide_leaves = yes; } bool select_current(); bool goto_selected(); void set_header(const char* head); void set_row_height(int rh); TTree_window(int x, int y, int dx, int dy, WINDOW parent, TTree_field* owner); virtual ~TTree_window() { } }; bool TTree_window::add_child(XVT_TREEVIEW_NODE parent) { XVT_TREEVIEW_NODE_TYPE type = _tree->has_son() ? XVT_TREEVIEW_NODE_NONTERMINAL : XVT_TREEVIEW_NODE_TERMINAL; if (_hide_leaves && type == XVT_TREEVIEW_NODE_TERMINAL) return false; TString id; _tree->curr_id(id); TString desc; _tree->get_description(desc); XVT_IMAGE ii = NULL, ic = NULL, ie = NULL; TImage* im_nor = _tree->image(false); if (im_nor != NULL) { if (type == XVT_TREEVIEW_NODE_NONTERMINAL) { TImage* im_sel = _tree->image(true); ic = im_nor->xvt_image(); ie = im_sel->xvt_image(); } else ii = im_nor->xvt_image(); } XVT_TREEVIEW_NODE child = xvt_treeview_add_child_node(_ctrl, parent, type, ii, ic, ie, desc, NULL, id); if (child != NULL && type == XVT_TREEVIEW_NODE_NONTERMINAL && _tree->expanded()) { for (bool ok = _tree->goto_firstson(); ok; ok = _tree->goto_rbrother()) add_child(child); xvt_treeview_expand_node(_ctrl, child, FALSE); } _tree->goto_node(id); return true; } void TTree_window::create_children(XVT_TREEVIEW_NODE node) { bool ok = false; TString id; if (_tree != NULL) { if (node != NULL) id = xvt_treeview_get_node_data(_ctrl, node); if (id.empty()) // Sono sulla radice { node = xvt_treeview_get_root_node(_ctrl); ok = _tree->goto_root(); } else { _tree->goto_node(id); ok = _tree->goto_firstson(); } } xvt_treeview_remove_node_children(_ctrl, node); for (; ok; ok = _tree->goto_rbrother()) add_child(node); // Riposiziona per benino l'alberello if (id.empty()) _tree->goto_root(); else _tree->goto_node(id); } void TTree_window::set_tree(TTree* tree) { _tree = tree; if (_tree != NULL) { // Memorizza la posizione dell'albero per dopo ... TString curr; tree->curr_id(curr); create_children(NULL); // Rigenera i figli della radice tree->goto_node(curr); // Riporta la selezione sul nodo memorizzato } } void TTree_window::handle_tree_event(EVENT* ep) { XVT_TREEVIEW_NODE node = ep->v.ctl.ci.v.treeview.node; const TString id = (const char*)xvt_treeview_get_node_data(_ctrl, node); if (_tree->goto_node(id)) { if (ep->v.ctl.ci.v.treeview.sgl_click || ep->v.ctl.ci.v.treeview.dbl_click) { KEY key = K_SPACE; // Single click selection if (ep->v.ctl.ci.v.treeview.dbl_click) key += K_CTRL; // Double click selection if (owner().on_key(key) && _tree->goto_node(id)) { // Aggiorna testo ed immagini che possono essere cambiate XVT_IMAGE ii = NULL, ic = NULL, ie = NULL; TImage* im_nor = _tree->image(false); if (_tree->has_son()) { TImage* im_sel = _tree->image(true); ic = im_nor->xvt_image(); ie = im_sel->xvt_image(); } else ii = im_nor->xvt_image(); xvt_treeview_set_node_images(_ctrl, node, ii, ic, ie); TString desc; _tree->get_description(desc); xvt_treeview_set_node_string(_ctrl, node, desc); } } else { int nWhat = 0; if (ep->v.ctl.ci.v.treeview.expanded) nWhat |= 0x1; if (ep->v.ctl.ci.v.treeview.collapsed) nWhat |= 0x2; switch (nWhat) { case 0x1: // Expanded _tree->expand(); owner().on_key(K_SHIFT + K_SPACE); break; case 0x2: // Collapsed _tree->shrink(); break; case 0x3: // Expanding _tree->expand(); create_children(node); owner().on_key(K_SHIFT + K_SPACE); owner().on_key(K_SPACE); break; default : break; } } } } void TTree_window::update() { if (_header.full()) { clear(MASK_BACK_COLOR); short x = 3, y = 0; FOR_EACH_TOKEN(_header, row) stringat(x, y++, row); } } void TTree_window::handler(WINDOW win, EVENT* ep) { switch (ep->type) { case E_CONTROL: if (ep->v.ctl.ci.type == WC_TREE && _tree != NULL) handle_tree_event(ep); break; case E_UPDATE: update(); // TControl_host_window non lo fa return; default: break; } TControl_host_window::handler(win, ep); } bool TTree_window::select_current() { XVT_TREEVIEW_NODE nextsel = NULL; // Nodo da selezionare (se mai lo trovero') if (_tree != NULL) { TString id; _tree->curr_id(id); // id del nodo corrente dell'albero // Controllo se il tree control e' gia' posizionato bene XVT_TREEVIEW_NODE cursel = xvt_treeview_get_selected_node(_ctrl); nextsel = xvt_treeview_find_node_string(_ctrl, id); if (nextsel != NULL && cursel == nextsel) return true; if (nextsel == NULL) { xvt_treeview_suspend(_ctrl); // Sospendo le notifiche degli eventi TString_array a; a.add(id); // Creo la lista dei progenitori while (_tree->goto_father()) { const int i = a.add(EMPTY_STRING); _tree->curr_id(a.row(i)); _tree->expand(); // Nel caso non fosse gia' espanso } // Scandisco i progenitori partendo dalla radice XVT_TREEVIEW_NODE parent = NULL; // was xvt_treeview_get_root_node(_ctrl); bool killed = false; // Ho interrotto "bruscamente" la ricerca? FOR_EACH_ARRAY_ROW_BACK(a, r, row) { if (killed) break; for (int i = 0; ; i++) { XVT_TREEVIEW_NODE child = xvt_treeview_get_child_node(_ctrl, parent, i); if (child == NULL && i == 0) // Forse non c'e' nessun figlio ... { create_children(parent); // ... sara' vero? child = xvt_treeview_get_child_node(_ctrl, parent, i); } if (child == NULL) // Certamente non ci sono piu' figli { //killed = true; // Non ho trovato quello che cercavo: esco subito break; } const char* data = xvt_treeview_get_node_data(_ctrl, child); if (*row == data) { nextsel = child; if (*row == id) // Ho finito killed = true; else { parent = child; xvt_treeview_expand_node(_ctrl, child, FALSE); } break; } } } xvt_treeview_resume(_ctrl); // Riattivo le notifiche degli eventi _tree->goto_node(id); // Riposiziono l'albero } if (nextsel != NULL) { xvt_treeview_select_node(_ctrl, nextsel, TRUE); if (_tree->expanded()) xvt_treeview_expand_node(_ctrl, nextsel, FALSE); } } return nextsel != NULL; } bool TTree_window::goto_selected() { bool ok = false; XVT_TREEVIEW_NODE child = xvt_treeview_get_selected_node(_ctrl); if (child != NULL) { const char* data = (const char*)xvt_treeview_get_node_data(_ctrl, child); ok = _tree->goto_node(data); } return ok; } void TTree_window::set_header(const char* head) { if (_header != head) { const int old_headlines = _header.items(); _header = head; const int new_headlines = _header.items(); if (new_headlines != old_headlines) { RCT rctree; xvt_vobj_get_client_rect(win(), &rctree); rctree.top += new_headlines * CHARY; xvt_vobj_move(_ctrl, &rctree); } force_update(); } } void TTree_window::set_row_height(int rh) { } TTree_window::TTree_window(int x, int y, int dx, int dy, WINDOW parent, TTree_field* owner) : TControl_host_window(x, y, dx, dy, parent, owner), _tree(NULL), _hide_leaves(false) { RCT rct; xvt_vobj_get_client_rect(win(), &rct); _ctrl = xvt_treeview_create(win(), &rct, "", 0, (long)this, owner->dlg(), NULL, NULL, NULL, 0, CHARY+2); XVT_COLOR_COMPONENT xcc[8]; memset(xcc, 0, sizeof(xcc)); xcc[0].type = XVT_COLOR_BACKGROUND; xcc[0].color = NORMAL_BACK_COLOR; xcc[1].type = XVT_COLOR_FOREGROUND; xcc[1].color = NORMAL_COLOR; xcc[2].type = XVT_COLOR_HIGHLIGHT; xcc[2].color = FOCUS_BACK_COLOR; xcc[3].type = XVT_COLOR_SELECT; xcc[3].color = FOCUS_COLOR; xcc[4].type = XVT_COLOR_BLEND; xcc[4].color = MASK_BACK_COLOR; xvt_ctl_set_colors(_ctrl, xcc, XVT_COLOR_ACTION_SET); } /////////////////////////////////////////////////////////// // TTree_field /////////////////////////////////////////////////////////// word TTree_field::class_id() const { return CLASS_TREE_FIELD; } bool TTree_field::is_kind_of(word cid) const { return cid == CLASS_TREE_FIELD || TWindowed_field::is_kind_of(cid); } #define tree_win() ((TTree_window&)win()) TTree* TTree_field::tree() const { return tree_win().tree(); } void TTree_field::set_tree(TTree* tree) { TTree_window& tv = tree_win(); tv.set_tree(tree); tv.select_current(); } void TTree_window::force_update() { set_tree(tree()); } void TTree_field::hide_leaves(bool yes) { tree_win().hide_leaves(yes); } bool TTree_field::select_current() { return tree_win().select_current(); } bool TTree_field::goto_selected() { return tree_win().goto_selected(); } void TTree_field::set_header(const char* head) { tree_win().set_header(head); } void TTree_field::set_row_height(int rh) { tree_win().set_row_height(rh); } TField_window* TTree_field::create_window(int x, int y, int dx, int dy, WINDOW parent) { return new TTree_window(x, y, dx, dy, parent, this); } /////////////////////////////////////////////////////////// // TOutlook_field /////////////////////////////////////////////////////////// class TOutlook_window : public TControl_host_window { public: virtual void handler(WINDOW win, EVENT* ep); public: int add_item(short icon, const char* text, int flags); bool select(int item, bool on); int selected() const; int items() const; void clear(); TOutlook_window(int x, int y, int dx, int dy, WINDOW parent, TOutlook_field* owner); }; void TOutlook_window::handler(WINDOW win, EVENT* ep) { switch (ep->type) { case E_CONTROL: if (ep->v.ctl.ci.type == WC_OUTLOOKBAR) { owner().on_key(K_SPACE); return; } break; default: break; } TControl_host_window::handler(win, ep); } int TOutlook_window::add_item(short icon, const char* text, int flags) { return xvt_list_add_item(_ctrl, icon, text, flags); } bool TOutlook_window::select(int item, bool on) { return xvt_list_set_sel(_ctrl, item, on) != FALSE; } int TOutlook_window::selected() const { return xvt_list_get_sel_index(_ctrl); } int TOutlook_window::items() const { return xvt_list_count(_ctrl); } void TOutlook_window::clear() { xvt_list_clear(_ctrl); } TOutlook_window::TOutlook_window(int x, int y, int dx, int dy, WINDOW parent, TOutlook_field* owner) : TControl_host_window(x, y, dx, dy, parent, owner) { XVT_COLOR_COMPONENT xcc[4]; memset(xcc, 0, sizeof(xcc)); xcc[0].type = XVT_COLOR_BACKGROUND; xcc[0].color = BTN_BACK_COLOR; xcc[1].type = XVT_COLOR_FOREGROUND; xcc[1].color = NORMAL_COLOR; WIN_DEF wd; memset(&wd, 0, sizeof(wd)); wd.wtype = WC_OUTLOOKBAR; wd.v.ctl.ctrl_id = owner->dlg(); wd.v.ctl.font_id = xvtil_default_font(true); // Fat font wd.rct = resize_rect(x, y, dx, dy, wd.wtype, parent); wd.ctlcolors = xcc; _ctrl = xvt_ctl_create_def(&wd, win(), 0); } word TOutlook_field::class_id() const { return CLASS_OUTLOOK_FIELD; } bool TOutlook_field::is_kind_of(word cid) const { return cid == CLASS_OUTLOOK_FIELD || TWindowed_field::is_kind_of(cid); } TField_window* TOutlook_field::create_window(int x, int y, int dx, int dy, WINDOW parent) { return new TOutlook_window(x, y, dx, dy, parent, this); } void TOutlook_field::create(short dlg, int x, int y, int dx, int dy, WINDOW parent) { construct(dlg, "", x, y, dy, parent, "", dx); } void TOutlook_field::clear() { TOutlook_window& ow = (TOutlook_window&)win(); ow.clear(); } int TOutlook_field::items() const { TOutlook_window& ow = (TOutlook_window&)win(); return ow.items(); } int TOutlook_field::add_item(short icon, const char* text, int flags) { TOutlook_window& ow = (TOutlook_window&)win(); return ow.add_item(icon, text, flags); } void TOutlook_field::set_window_data(const char* data) { TOutlook_window& ow = (TOutlook_window&)win(); const int sel = atoi(data); _str.cut(0) << sel; ow.select(sel, true); } const TString& TOutlook_field::get_window_data() { TOutlook_window& ow = (TOutlook_window&)win(); _str.cut(0) << ow.selected(); return _str; } void TOutlook_field::set(const char* data) { set_window_data(data); set_dirty(); } const TString& TOutlook_field::get() const { return _str; } bool TOutlook_field::on_key(KEY key) { if (key == K_SPACE) { get_window_data(); set_dirty(); on_hit(); return true; } return TWindowed_field::on_key(key); } /////////////////////////////////////////////////////////// // TSlider_window /////////////////////////////////////////////////////////// class TSlider_window : public TField_window { public: void set(int pos); int get() const; void set_range(int mi, int ma); TSlider_window(int x, int y, int dx, int dy, WINDOW parent, TSlider_field* owner); }; void TSlider_window::set_range(int mi, int ma) { if (mi != 0) { ma -= mi; mi = 0; } if (ma < mi) ma = 100; xvt_sbar_set_range(win(), HVSLIDER, mi, ma); } void TSlider_window::set(int pos) { xvt_sbar_set_pos(win(), HVSLIDER, pos); } int TSlider_window::get() const { return xvt_sbar_get_pos(win(), HVSLIDER); } TSlider_window::TSlider_window(int x, int y, int dx, int dy, WINDOW parent, TSlider_field* owner) : TField_window(0, 0, 0, 0, NULL, NULL) { XVT_COLOR_COMPONENT xcc[2]; memset(xcc, 0, sizeof(xcc)); xcc[0].type = XVT_COLOR_BLEND; xcc[0].color = MASK_BACK_COLOR; set_owner(owner); WIN_DEF wd; memset(&wd, 0, sizeof(wd)); wd.rct = resize_rect(x, y, dx, dy, wd.wtype, parent); wd.wtype = (wd.rct.right-wd.rct.left) > (wd.rct.bottom-wd.rct.top) ? WC_HSLIDER : WC_VSLIDER; wd.ctlcolors = xcc; wd.v.ctl.ctrl_id = owner->dlg(); real mi, ma; owner->range(mi, ma); const long limit = ma.integer() - mi.integer(); set_win(xvt_ctl_create_def(&wd, parent, limit)); } /////////////////////////////////////////////////////////// // TSlider_field /////////////////////////////////////////////////////////// void TSlider_field::set_window_data(const char* data) { TSlider_window& sw = (TSlider_window&)win(); const int sel = atoi(data); sw.set(sel); } const TString& TSlider_field::get_window_data() { TSlider_window& sw = (TSlider_window&)win(); TString& tmp = get_tmp_string(); tmp << sw.get(); return tmp; } void TSlider_field::set(const char* data) { if (!_range_min.is_zero()) { real n(data); n -= _range_min; data = n.string(); } set_window_data(data); set_dirty(); } const TString& TSlider_field::get() const { TString& str = (TString&)((TSlider_field*)this)->get_window_data(); if (!_range_min.is_zero()) { real n(str); n += _range_min; str = n.string(); } return str; } const char* TSlider_field::get_buddy() const { if (_buddy > 0) { const int pos = mask().id2pos(_buddy); if (pos > 0) { real n = mask().fld(pos).get(); if (n < _range_min) n = _range_min; if (n > _range_max) n = _range_max; return n.string(); } } return EMPTY_STRING; } void TSlider_field::set_buddy(const char* b) const { if (_buddy > 0) { const int pos = mask().id2pos(_buddy); if (pos > 0) mask().fld(pos).set(b); } } bool TSlider_field::on_hit() { if (!mask().is_running()) { set_range(_range_min, _range_max); // Imposto range dello slider const char* b = get_buddy(); if (b && *b) set(b); } return TWindowed_field::on_hit(); } word TSlider_field::class_id() const { return CLASS_SLIDER_FIELD; } bool TSlider_field::is_kind_of(word cid) const { return cid == CLASS_SLIDER_FIELD || TWindowed_field::is_kind_of(cid); } TField_window* TSlider_field::create_window(int x, int y, int dx, int dy, WINDOW parent) { return new TSlider_window(x, y, dx, dy, parent, this); } void TSlider_field::set_range(const real& mi, const real& ma) { _range_min = mi; _range_max = ma; set_range(mi.integer(), ma.integer()); } void TSlider_field::set_range(int mi, int ma) { _range_min = mi; _range_max = ma; if (_win != NULL_WIN) { TSlider_window& sw = (TSlider_window&)win(); sw.set_range(mi, ma); } } void TSlider_field::range(real& mi, real& ma) { mi = _range_min; ma = _range_max; } bool TSlider_field::parse_item(TScanner& scanner) { if (scanner.key() == "DR") // DRIVENBY id { _buddy = scanner.integer(); return true; } if (scanner.key() == "RA") // RANGE min max { const int mi = scanner.integer(); const int ma = scanner.integer(); set_range(mi, ma); return true; } return TWindowed_field::parse_item(scanner); } TSlider_field::TSlider_field(TMask* m) : TWindowed_field(m), _buddy(0), _range_min(ZERO), _range_max(CENTO) { } /////////////////////////////////////////////////////////// // TProp_window /////////////////////////////////////////////////////////// class TProp_window : public TField_window { public: TProp_window(int x, int y, int dx, int dy, WINDOW parent, TProp_field* owner); }; TProp_window::TProp_window(int x, int y, int dx, int dy, WINDOW parent, TProp_field* owner) : TField_window(0, 0, 0, 0, NULL, NULL) { XVT_COLOR_COMPONENT xcc[8]; memset(xcc, 0, sizeof(xcc)); xcc[0].type = XVT_COLOR_BACKGROUND; xcc[0].color = NORMAL_BACK_COLOR; xcc[1].type = XVT_COLOR_FOREGROUND; xcc[1].color = NORMAL_COLOR; xcc[2].type = XVT_COLOR_HIGHLIGHT; xcc[2].color = FOCUS_BACK_COLOR; xcc[3].type = XVT_COLOR_SELECT; xcc[3].color = FOCUS_COLOR; xcc[4].type = XVT_COLOR_BLEND; xcc[4].color = MASK_BACK_COLOR; xcc[5].type = XVT_COLOR_TROUGH; xcc[5].color = DISABLED_BACK_COLOR; set_owner(owner); WIN_DEF wd; memset(&wd, 0, sizeof(wd)); wd.rct = resize_rect(x, y, dx, dy, wd.wtype, parent); wd.wtype = WC_PROPGRID; wd.ctlcolors = xcc; wd.v.ctl.ctrl_id = owner->dlg(); set_win(xvt_ctl_create_def(&wd, parent, 0L)); } word TProp_field::class_id() const { return CLASS_PROP_FIELD; } bool TProp_field::is_kind_of(word cid) const { return cid == CLASS_PROP_FIELD || TWindowed_field::is_kind_of(cid); } void TProp_field::freeze(bool on) { WINDOW pg = win().win(); if (on) xvt_prop_suspend(pg); else xvt_prop_restart(pg); } bool TProp_field::set_property(const char* name, const char* value, const char* label) { XVT_TREEVIEW_NODE node = NULL; WINDOW pg = win().win(); if (pg != NULL_WIN) { if (name != NULL && value == NULL && label != NULL) node = xvt_prop_add(pg, NULL, name, NULL, label); // Category! else { if (label && *label) node = xvt_prop_add(pg, "string", name, value, label); // Add property else { node = xvt_prop_find(win().win(), name); if (node) xvt_prop_set_data(pg, node, value); // Set property } } } return node != NULL; } bool TProp_field::set_property(const char* name, long value, const char* label) { bool done = false; TString16 str; str << value; if (label && *label) done = xvt_prop_add(win().win(), "long", name, str, label) != NULL; else done = set_property(name, str, label); return done; } bool TProp_field::set_property(const char* name, COLOR c, const char* label) { bool done = false; TString16 str; str.format("%d,%d,%d", XVT_COLOR_GET_RED(c), XVT_COLOR_GET_GREEN(c), XVT_COLOR_GET_BLUE(c)); if (label && *label) done = xvt_prop_add(win().win(), "color", name, str, label) != NULL; else done = set_property(name, str, label); return done; } const TString& TProp_field::get_property(const char* name) const { WINDOW pg = win().win(); XVT_TREEVIEW_NODE node = xvt_prop_find(pg, name); if (node) { TString& tmp = get_tmp_string(); const int len = xvt_prop_get_data(pg, node, tmp.get_buffer(), tmp.size()); if (len > tmp.size()) xvt_prop_get_data(pg, node, tmp.get_buffer(len), len); return tmp; } return EMPTY_STRING; } long TProp_field::get_long_property(const char* name) const { return atol(get_property(name)); } COLOR TProp_field::get_color_property(const char* name) const { COLOR col = COLOR_INVALID; const TString& tmp = get_property(name); if (tmp.full()) { int r = 0, g = 0, b = 0; if (sscanf(tmp, "%d,%d,%d", &r, &g, &b) == 3) col = RGB2COLOR(r,g,b); else col = r ? r : COLOR_BLACK; } return col; } static TString_array _items; bool TProp_field::parse_item(TScanner& scanner) { if (scanner.key() == "IT") { const TString80 label = dictionary_translate(scanner.string()); TString16 type = scanner.pop(); TString80 name, value; if (type.starts_with("IT")) { type.cut(0); scanner.push(); } else { const TString& line = scanner.line(); int equal = line.find('='); if (equal < 0) equal = line.find(' '); if (equal > 0) { name = line.left(equal); name.trim(); value = line.mid(equal+1); value.trim(); if (value[0] == '"') { value.rtrim(1); value.ltrim(1); } } else { name.trim(); value.cut(0); } type.cut(2); } TToken_string* item = new TToken_string; item->add(type); item->add(name); item->add(value); item->add(label,3); _items.add(item); return true; } return TWindowed_field::parse_item(scanner); } TField_window* TProp_field::create_window(int x, int y, int dx, int dy, WINDOW parent) { TProp_window* pw = new TProp_window(x, y, dx, dy, parent, this); if (!_items.empty()) { WINDOW pg = pw->win(); xvt_prop_suspend(pg); TString8 type; TString80 name, value, label; FOR_EACH_ARRAY_ROW(_items, i, row) { row->get(0, type); row->get(1, name); row->get(2, value); row->get(3, label); if (type.full()) { if (type == "CO") xvt_prop_add(pg, "color", name, value, label); else if (type == "NU" || type == "CU") xvt_prop_add(pg, "long", name, value, label); else xvt_prop_add(pg, "string", name, value, label); } else xvt_prop_add(pg, "", "", "", label); } xvt_prop_restart(pg); _items.destroy(); } return pw; } TProp_field::TProp_field(TMask* m) : TWindowed_field(m) { }