campo-sirio/include/treectrl.cpp
guy 5706e80edf Patch level : 10.0
Files correlati     : ve1.exe
Ricompilazione Demo : [ ]
Commento            :
Corretta anteprima di stampa di vecchi frm con immagini


git-svn-id: svn://10.65.10.50/trunk@18876 c028cbd2-c16b-5b4b-a496-9718f37d4682
2009-05-15 09:19:11 +00:00

1110 lines
28 KiB
C++
Executable File

#define XI_INTERNAL
#include <xinclude.h>
#include <colors.h>
#include <controls.h>
#include <diction.h>
#include <image.h>
#include <mask.h>
#include <tree.h>
#include <treectrl.h>
///////////////////////////////////////////////////////////
// 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)
{ }