Files correlati : tutti Ricompilazione Demo : [ ] Commento : 0001213: mappa di login, fuoco Lla mappa di login si apre ma per poter digitare la password bisogna cliccare sul campo col mouse. Stesso problema richiamando le ricerche, per esempio quella clienti. git-svn-id: svn://10.65.10.50/trunk@18591 c028cbd2-c16b-5b4b-a496-9718f37d4682
1117 lines
28 KiB
C++
Executable File
1117 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)
|
|
{
|
|
if (on)
|
|
xvt_prop_suspend(win().win());
|
|
else
|
|
xvt_prop_restart(win().win());
|
|
}
|
|
|
|
bool TProp_field::set_property(const char* name, const char* value, const char* label)
|
|
{
|
|
WINDOW pg = win().win();
|
|
XVT_TREEVIEW_NODE node = NULL;
|
|
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 value, const char* label)
|
|
{
|
|
bool done = false;
|
|
TString16 str; str << long(value & 0xFFFFFF);
|
|
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())
|
|
{
|
|
col = atol(tmp);
|
|
if (col == 0)
|
|
col = 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)
|
|
{ }
|