campo-sirio/ba/ba0102.cpp
guy dddb1a668f Supporto base per tema METRO
git-svn-id: svn://10.65.10.50/branches/R_10_00@23185 c028cbd2-c16b-5b4b-a496-9718f37d4682
2016-04-15 08:12:39 +00:00

1345 lines
33 KiB
C++
Executable File
Raw Blame History

#include <config.h>
#include <diction.h>
#include <prefix.h>
#include <toolfld.h>
#include <urldefid.h>
#include <utility.h>
#include <xvtility.h>
#include "ba0102.h"
///////////////////////////////////////////////////////////
// TMenu_tree
///////////////////////////////////////////////////////////
const TSubmenu& TMenu_tree::curr_submenu() const
{
CHECKS(_submenu, "NULL submenu ", (const char*)_curr_id);
return *_submenu;
}
const TMenuitem& TMenu_tree::curr_item() const
{
const TSubmenu& sm = curr_submenu();
if (_menuitem < 0 || _menuitem >= sm.items())
{
NFCHECK("Invalid submenu item %d in %s", _menuitem, (const char*)sm.name());
return sm.item(0);
}
return sm.item(_menuitem);
}
bool TMenu_tree::enabled() const
{
return curr_item().enabled();
}
bool TMenu_tree::marked() const
{
bool yes = false;
/* Non cambia nulla!
const TMenuitem& mi = curr_item();
if (mi.is_program() && mi.enabled())
{
TFilename n = mi.action().before(' ');
n.ext("exe");
if (n.custom_path())
{
n.lower();
yes = n.find("custom") > 0;
}
}
*/
return yes;
}
struct TFind_node_data
{
TString _id;
size_t _count;
};
struct TFind_string_data
{
TString256 _str, _best;
TAssoc_array* _ignore_list;
double _score;
};
HIDDEN bool find_string_callback(TTree& tree, void* jolly, word flags)
{
if (flags == SCAN_PRE_ORDER)
{
const TMenu_tree& mt = (const TMenu_tree&)tree;
const TSubmenu& sm = mt.curr_submenu();
if (sm.disabled())
return false;
TFind_string_data& data = *(TFind_string_data*)jolly;
if (data._ignore_list->is_key(sm.name()))
return false;
TString desc; mt.get_description(desc);
desc.upper();
if (desc.find(data._str) >= 0 || desc.match(data._str))
{
data._score = 1.0;
mt.curr_id(data._best);
return true;
}
const double s = xvt_str_fuzzy_compare(desc, data._str);
if (s > data._score)
{
data._score = s;
mt.curr_id(data._best);
}
}
return false;
}
HIDDEN bool find_node_callback(TTree& tree, void* jolly, word flags)
{
if (flags == SCAN_PRE_ORDER)
{
TFind_node_data& data = *(TFind_node_data*)jolly;
data._count++;
TString id; tree.curr_id(id);
if (id == data._id)
return TRUE;
}
return FALSE;
}
HIDDEN bool find_leaf_callback(TTree& tree, void* jolly, word flags)
{
if (flags == SCAN_PRE_ORDER)
{
const TString& leaf = *(TString*)jolly;
TString id; tree.curr_id(id);
const int slash = id.rfind('/');
if (slash > 0)
id = id.mid(slash+1);
if (id == leaf)
return true;
}
return false;
}
bool TMenu_tree::find_string(const TString& str)
{
TFind_string_data data;
data._str = str; data._str.upper();
data._ignore_list = &_menu->search_ignore_list();
data._score = 0;
if (data._str != _menu->last_search_string())
{
_menu->last_search_string() = data._str;
_menu->search_ignore_list().destroy();
}
goto_root();
bool ok = scan_depth_first(find_string_callback, &data, SCAN_PRE_ORDER);
if (!ok && data._score > 0.9)
ok = goto_node(data._best);
if (ok)
_menu->search_ignore_list().add(curr_submenu().name());
else
_menu->search_ignore_list().destroy();
return ok;
}
bool TMenu_tree::find_leaf(const TString& str)
{
goto_root();
bool ok = scan_depth_first(find_leaf_callback, (void *)&str, SCAN_PRE_ORDER);
return ok;
}
void TMenu_tree::node2id(const TObject* node, TString& id) const
{
TString* str = (TString*)node;
id = *str;
}
bool TMenu_tree::goto_root()
{
TSubmenu* sm = _menu->find(_root_id);
if (sm)
{
_curr_id = _root_id;
_curr_id << ".0";
_submenu = sm;
_menuitem = 0;
}
return sm != NULL;
}
bool TMenu_tree::goto_firstson()
{
const TMenuitem& mi = curr_item();
const TSubmenu* sm = mi.child_submenu();
if (sm != NULL)
{
_curr_id << '/' << mi.action() << ".0";
_submenu = sm;
_menuitem = 0;
return true;
}
return false;
}
bool TMenu_tree::goto_rbrother()
{
if (_menuitem < _submenu->items()-1)
{
const int dot = _curr_id.rfind('.');
_curr_id.cut(dot+1);
_curr_id << (++_menuitem);
return true;
}
return false;
}
bool TMenu_tree::goto_node(const TString &id)
{
if (_curr_id != id)
{
const int dot = id.rfind('.');
CHECKS(dot > 0, "Invalid tree node ", (const char*)id);
_menuitem = atoi(id.mid(dot+1));
_curr_id = id.left(dot);
const int slash = _curr_id.rfind('/');
_curr_id = _curr_id.mid(slash+1);
_submenu = _menu->find(_curr_id);
_curr_id = id;
}
return _submenu != NULL;
}
bool TMenu_tree::has_son() const
{
const TMenuitem& mi = curr_item();
return mi.is_submenu();
}
bool TMenu_tree::has_rbrother() const
{
return _menuitem < _submenu->items()-1;
}
bool TMenu_tree::has_root() const
{
return _root_id.not_empty();
}
bool TMenu_tree::has_father() const
{
return _curr_id.find('/') > 0;
}
bool TMenu_tree::has_lbrother() const
{
return _menuitem > 0;
}
bool TMenu_tree::goto_father()
{
const int slash = _curr_id.rfind('/');
if (slash > 0)
{
const TString id = _curr_id.left(slash);
return goto_node(id);
}
return false;
}
bool TMenu_tree::goto_lbrother()
{
if (_menuitem > 0)
{
const int dot = _curr_id.rfind('.');
_curr_id.cut(dot+1);
_curr_id << (--_menuitem);
return true;
}
return false;
}
TObject* TMenu_tree::curr_node() const
{
return &((TMenu_tree*)this)->_curr_id;
}
bool TMenu_tree::get_description(TString& desc) const
{
const TMenuitem& mi = curr_item();
desc = mi.caption();
return desc.full();
}
TImage* TMenu_tree::image(bool selected) const
{
const TMenuitem& mi = curr_item();
if (mi.disabled())
return get_res_icon(10203); // Icona di stop
int ico = mi.icon(); // Eventuale icona di programma o cartella
if (ico <= 0 && mi.is_program()) // Forza icona per i programmi
ico = ICON_RSRC;
TImage* img = ico > 0 ? get_res_icon(ico) : NULL;
return img ? img : TTree::image(selected);
}
long TMenu_tree::find_node(const TString& id)
{
TFind_node_data data;
data._id = id;
data._count = 0;
goto_root();
scan_depth_first(find_node_callback, &data,
SCAN_PRE_ORDER | SCAN_IGNORING_UNEXPANDED);
return data._count;
}
void TMenu_tree::change_root(const char* rid)
{
_root_id = rid;
const int dot = _root_id.find('.');
if (dot > 0)
_root_id.cut(dot);
goto_root();
}
void TMenu_tree::set_menu(TMenu& menu)
{
_menu = &menu;
_curr_id.cut(0);
change_root("MENU_000");
}
TMenu_tree::TMenu_tree(TMenu& menu) : _menu(NULL), _curr_id(128, '/')
{
set_menu(menu);
}
///////////////////////////////////////////////////////////
// Utility
///////////////////////////////////////////////////////////
//flag per impedire un doppio aggiornamento causato adall'autofocus del primo elemento dell'albero
//senza questo flag entra automaticamente nella prima voce di menu, un livello sotto a quello..
//..richiesto dall'utente
static bool _sincronaising = false;
// Sincronizza l'albero in basa alla list view
void synchronize_tree_field(TTree_field& tf)
{
_sincronaising = true;
TTree& mt = *tf.tree();
TString id; mt.curr_id(id); // Memorizza nodo corrente
mt.shrink_all(); // Collassa tutto l'albero
// Espande il nodo corrente all'indietro fino alla radice
mt.goto_node(id);
do mt.expand(); while (mt.goto_father());
mt.goto_node(id); // Torna al nodo corrente
tf.win().force_update(); // Provoca la rigenerazione dell'albero espanso come sopra
tf.on_key(K_SPACE);
_sincronaising = false;
}
bool can_be_transparent(const TImage& i)
{
if (xvt_image_get_format(i) == XVT_IMAGE_RGB)
return false;
const int w = i.width()-1;
const int h = i.height()-1;
const COLOR col = i.get_pixel(0,0);
if (i.get_pixel(w,0) != col)
return false;
if (i.get_pixel(w,h) != col)
return false;
if (i.get_pixel(0,h) != col)
return false;
return true;
}
///////////////////////////////////////////////////////////
// TMenulist_images
///////////////////////////////////////////////////////////
class TMenulist_images : public TCache
{
WINDOW _win;
int _max_side;
protected:
TObject* key2obj(const char* key);
public:
void set_owner_info(WINDOW win, int max_side);
TImage* image(const char* filename);
TMenulist_images() : TCache(17), _win(NULL_WIN), _max_side(0) { }
};
int fast_hypot(int x, int y)
{
// loop unrolled
#define TEST(s, h, i) { const int k = h+i; if (k*k <= s) h = k; }
const int s = x*x + y*y;
int h = 0;
TEST(s, h, 512); TEST(s, h, 256); TEST(s, h, 128);
TEST(s, h, 64); TEST(s, h, 32); TEST(s, h, 16);
TEST(s, h, 8); TEST(s, h, 4); TEST(s, h, 2); TEST(s, h, 1);
return h;
}
void TMenulist_images::set_owner_info(WINDOW win, int max_side)
{
if (max_side != _max_side)
destroy();
_win = win;
_max_side = max_side;
}
TObject* TMenulist_images::key2obj(const char* key)
{
TImage* img = NULL;
TFilename name;
const char* ext[] = { "jpg", "gif", "bmp", "png", NULL };
for (int i = 0; ext[i] != NULL; i++)
{
name = key;
name.ext(ext[i]);
if (name.custom_path())
break;
}
if (name.exist())
{
TWait_cursor hourglass;
TImage image(name);
if (can_be_transparent(image))
image.convert_transparent_color(NORMAL_BACK_COLOR);
RCT rct; xvt_vobj_get_client_rect(_win, &rct);
const double max_img = (double)_max_side;
const double max_lgo = rct.right - _max_side;
if (xvt_str_compare_ignoring_case(key, get_logo()) != 0)
{
const double ratiox = max_img / image.width();
const double ratioy = max_img / image.height();
const double ratio = min(ratiox, ratioy);
const int maxx = int(ratio * image.width());
const int maxy = int(ratio * image.height());
img = new TImage(image, maxx, maxy);
//Sfumatura costante sui lati sx e up
const double radius = min(maxx,maxy)/6.0;
for (int y = 0; y < maxy; y++)
{
for (int x = 0; x < maxx; x++)
{
if (x <= radius || y <= radius)
{
double perc = 1.0;
if (x <= radius && y <= radius)
{
const int r = fast_hypot(int(radius-x),int(radius-y));
if (r <= radius)
perc = 1.0-r/radius;
else
perc = 0;
}
else
perc = min(x,y)/radius;
COLOR col = img->get_pixel(x, y);
COLOR bri = blend_colors(col, NORMAL_BACK_COLOR, perc);
img->set_pixel(x, y, bri);
}
}
}
}
else //caso particolare del logo
{
const double ratio = max_lgo / image.width();
const int maxx = int(ratio * image.width());
const int maxy = int(ratio * image.height());
img = new TImage(image, maxx, maxy);
}
}
return img;
}
TImage* TMenulist_images::image(const char* name)
{
TObject* obj = objptr(name);
if (obj == NULL &&
xvt_str_compare_ignoring_case(name, "ba00") != 0 &&
xvt_str_compare_ignoring_case(name, get_logo()) != 0)
obj = objptr("ba00");
return (TImage*)obj;
}
///////////////////////////////////////////////////////////
// TMenulist_field
///////////////////////////////////////////////////////////
class TMenulist_window : public TField_window
{
private:
TMenu_tree* _tree;
size_t MENU_COLS, MENU_ROWS;
TString _curr_node;
bool _can_go_back;
TMenulist_images _images;
TString _image_name;
int _selected;
TPointer_array _sorted;
clock_t _last_update;
protected:
virtual void update();
virtual long handler(WINDOW win, EVENT* ep);
virtual bool on_key(KEY k);
void synchronize_buddy_tree() const;
void draw_item(int i);
void draw_menu_caption();
void click_on(int index);
void select(int s, int direction);
public:
void curr_item(TToken_string& id) const;
void set_menu(TMenu_tree& mt);
TMenulist_window(int x, int y, int dx, int dy, WINDOW parent, TMenulist_field* owner);
virtual ~TMenulist_window();
};
void TMenulist_window::draw_item(int i)
{
if (i < 0 && i >= _sorted.items())
return; // Scarta elementi non validi
WINDOW w = win();
RCT rct; xvt_vobj_get_client_rect(w, &rct);
const int width = rct.right - rct.left;
const int height = rct.bottom - rct.top;
xvtil_set_font(w, NULL, 0, 0); // Set default font
set_opaque_text(TRUE);
const TMenuitem& item = (const TMenuitem&)_sorted[i];
if (item.enabled())
{
if (i == _selected) //testo nero su sfondo con colore del focus se la voce e' selezionata
set_color(FOCUS_COLOR, FOCUS_BACK_COLOR);
else //testo nero su sfondo trasparente x voci non selezionate
set_color(NORMAL_COLOR, NORMAL_BACK_COLOR);
}
else //testo grigio su sfondo trasparente x voci non selezionate
set_color(DISABLED_COLOR, DISABLED_BACK_COLOR);
const int row = i / MENU_COLS;
const int col = i % MENU_COLS;
const int left = col * width / MENU_COLS;
const int right = (col+1) * width / MENU_COLS;
const int top = row * height / MENU_ROWS;
// const int bottom = (row+1) * height / MENU_ROWS;
const int cx = (left+right)/2;
// const int cy = (top+bottom)/2; verificare
const int ico = item.enabled() ? item.icon() : 0;
const int ix = cx-16;
const int iy = top+2;
if (item.is_submenu())
{
xvt_dwin_draw_icon(w, ix, iy, 10202);
if (ico > 0)
xvt_dwin_draw_icon(w, ix, iy+4, ico);
}
else
{
xvt_dwin_draw_icon(w, ix, iy, ico > 0 ? ico : ICON_RSRC);
}
TString80 str = item.caption();
if (i == 0 && _can_go_back)
str = "(..)";
// const int maxchars = (right-left)/CHARX - 1;
int maxchars = 24;
const int ll = xvt_dwin_get_text_width(w, str, -1);
if (ll >= (right-left))
maxchars = (right-left) * str.len() / ll - 1;
TParagraph_string para(str, maxchars);
int y = iy + 32 + CHARY-1;
FOR_EACH_TOKEN(para, line)
{
const int ll = xvt_dwin_get_text_width(w, line, -1);
const int x = cx - ll/2;
xvt_dwin_draw_text(w, x, y, line, -1);
y += CHARY-2;
}
if (item.disabled())
{
RCT rct; xvt_rect_set(&rct, ix+16, iy+16, ix+32, iy+32);
xvt_dwin_draw_icon_rect(w, &rct, 10203); // Stop icon
}
}
//scrive la voce di menu corrente a video
void TMenulist_window::draw_menu_caption()
{
const char* caption = "";
if (_sorted.items() > 1)
{
const TMenuitem& mi = (const TMenuitem&)_sorted[1];
const TSubmenu& sm = mi.submenu();
caption = sm.caption();
}
else
{
const TMenuitem& mi = (const TMenuitem&)_sorted[0];
caption = mi.caption();
}
xvt_pane_set_title(win(), caption);
xvtil_statbar_set(caption);
}
void TMenulist_window::update()
{
TField_window::update();
if (_tree == NULL)
return; // Nothing to draw
const bool db = ADVANCED_GRAPHICS;
TImage* img = db ? _images.image(_image_name) : NULL;
if (img != NULL)
{
RCT rct; xvt_vobj_get_client_rect(win(), &rct);
rct.left = rct.right/2; rct.top = rct.bottom/2;
img->draw(win(), rct, 'R', 'B', '-');
}
TImage* logo = db ? _images.image(get_logo()) : NULL; //logo del programma
if (logo != NULL) //disegna il logo
{
RCT rct; xvt_vobj_get_client_rect(win(), &rct);
rct.left = rct.right/2; rct.top = rct.bottom/2;
logo->draw(win(), rct, 'L', 'B', '-');
}
FOR_EACH_ARRAY_ITEM(_sorted, i, obj)
draw_item(i);
draw_menu_caption();
}
void TMenulist_window::click_on(int index)
{
if (index >= 0 && index < _sorted.items())
{
const TMenuitem& mi = (const TMenuitem&)_sorted[index];
if (mi.enabled())
{
if (xvt_vobj_get_attr(NULL_WIN, ATTR_SPEECH_MODE) & (1<<7))
{
const TString& str = mi.caption();
if (str.find("..") < 0)
xvt_dm_post_speech(str, 7, TRUE);
}
if (mi.is_submenu())
{
if (index == 0 && _can_go_back) // S<> di un livello
{
_tree->goto_node(_curr_node);
_tree->goto_father();
set_menu(*_tree);
}
else // Gi<47> di un livello
{
if (mi.perform()) // Eventuale richiesta ditta
{
_tree->goto_node(_curr_node);
const TSubmenu& mnu = _tree->curr_submenu();
for (int i = 0; i < mnu.items(); i++)
{
const TMenuitem& ti = mnu[i];
if (ti.action() == mi.action())
{
_tree->goto_firstson();
set_menu(*_tree);
synchronize_buddy_tree();
break;
}
_tree->goto_rbrother();
}
}
}
}
else
{
mi.perform();
//se installa si suicida
if (installing())
owner().mask().stop_run(K_FORCE_CLOSE);
}
set_focus();
}
else
xvt_sys_beep(1);
}
}
long TMenulist_window::handler(WINDOW w, EVENT* ep)
{
switch (ep->type)
{
case E_MOUSE_DOWN:
{
RCT rct; xvt_vobj_get_client_rect(w, &rct);
const int row = ep->v.mouse.where.v * MENU_ROWS / rct.bottom;
const int col = ep->v.mouse.where.h * MENU_COLS / rct.right;
const int index = row * MENU_COLS + col;
if (ep->v.mouse.button > 0) // Tasto destro
{
if (index < _sorted.items())
{
const TMenuitem& mi = (const TMenuitem&)_sorted[index];
message_box("%s\n%s", (const char*)mi.submenu().name(), (const char*)mi.action());
}
else
{
if (_can_go_back)
click_on(0);
}
}
else
{
click_on(index); // Tasto sinistro
}
}
break;
case E_MOUSE_MOVE:
if (ADVANCED_GRAPHICS)
{
EVENT e = *ep;
xvt_vobj_translate_points(w, parent(), &e.v.mouse.where, 1);
xvt_win_dispatch_event(parent(), &e);
}
break;
case E_SIZE:
{
const int h = ep->v.size.height; // Client height
const int w = ep->v.size.width; // Client width
const size_t rh = 32 + 3 * CHARY; // Row height
MENU_ROWS = max(1, h / rh);
const size_t cw = 16*CHARX; // Column width
MENU_COLS = max(1, w / cw);
const int ms = h - 3 * rh; // Max. image size
_images.set_owner_info(win(), ms);
}
break;
default:
break;
}
return TField_window::handler(w, ep);
}
void TMenulist_window::select(int s, int direction)
{
const int old_selection = _selected;
if (s < 0)
s = 0;
if (s >= _sorted.items())
s = _sorted.last();
_selected = s;
const TMenuitem& mi = (const TMenuitem&)_sorted[_selected];
if (!mi.enabled())
{
for (_selected += direction; ; _selected += direction)
{
if (_selected < 0)
_selected = _sorted.last();
if (_selected >= _sorted.items())
_selected = 0;
if (_selected == s) // Ho rifatto l'intero giro!
break;
const TMenuitem& item = (const TMenuitem&)_sorted[_selected];
if (item.enabled())
break; // Ho trovato un elemento abilitato!
}
}
draw_item(old_selection);
draw_item(_selected);
}
bool TMenulist_window::on_key(KEY k)
{
switch (k)
{
case K_ESC:
case K_BACKSPACE:
if (_tree != NULL && _can_go_back) // S<> di un livello
click_on(0);
break;
case K_ENTER:
case K_SPACE:
click_on(_selected);
break;
case K_HOME:
select(0, +1);
break;
case K_UP:
case K_PREV:
select(_selected - MENU_COLS, -1);
break;
case K_DOWN:
case K_NEXT:
select(_selected + MENU_COLS, +1);
break;
case K_LEFT:
case K_BTAB:
select(_selected-1, -1);
break;
case K_RIGHT:
case K_TAB:
select(_selected+1, +1);
break;
case K_END:
select(_sorted.last(), -1);
break;
default:
break;
}
return TRUE;
}
void TMenulist_window::synchronize_buddy_tree() const
{
TMask& m = owner().mask();
FOR_EACH_MASK_FIELD(m, i, f)
{
if (f->is_kind_of(CLASS_TREE_FIELD))
{
TTree_field& tf = (TTree_field&)*f;
synchronize_tree_field(tf);
break;
}
}
}
void TMenulist_window::curr_item(TToken_string& id) const
{
if (_selected >= 0 && _selected < _sorted.items())
{
const TMenuitem& item = (const TMenuitem&)_sorted[_selected];
const TSubmenu& sm = item.submenu();
const int index = sm.find(item);
id = item.caption();
id.add(sm.name());
id << '.' << index;
}
}
void TMenulist_window::set_menu(TMenu_tree& tree)
{
_tree = &tree;
tree.curr_id(_curr_node);
const int dot = _curr_node.rfind('.')+1;
int sel = -1;
if (dot > 0)
{
sel = atoi(_curr_node.mid(dot));
_curr_node.cut(dot);
_curr_node << '0';
}
_sorted.destroy();
_can_go_back = tree.goto_father();
if (_can_go_back) // Esiste un livello precedente?
{
_sorted.add(tree.curr_item()); // Determina il nome del livello precedente
tree.goto_node(_curr_node); // Torna al nodo corrente
}
int folders = _sorted.items();
// Lista riordinata dei menu items
const TSubmenu& mnu = tree.curr_submenu();
for (int i = 0; i < mnu.items(); i++)
{
const TMenuitem& item = mnu[i];
if (item.is_submenu())
_sorted.insert(item, folders++);
else
_sorted.add(item);
}
TString80 sel_act;
if (sel >= 0 && sel < mnu.items())
sel_act= mnu[sel].action();
for (_selected = _sorted.last(); _selected > 0; _selected--)
{
const TMenuitem& sm = (const TMenuitem&)_sorted[_selected];
if (sm.enabled() && sm.action() == sel_act)
break;
}
_image_name = mnu.picture();
force_update();
}
TMenulist_window::TMenulist_window(int x, int y, int dx, int dy, WINDOW parent, TMenulist_field* owner)
: TField_window(x, y, dx, dy, parent, owner), _tree(NULL), MENU_COLS(4), MENU_ROWS(5)
{
set_scroll_max(0, 0); // Get rid of that useless scrollbars
}
TMenulist_window::~TMenulist_window()
{ }
TField_window* TMenulist_field::create_window(int x, int y, int dx, int dy, WINDOW parent)
{ return new TMenulist_window(x, y, dx, dy, parent, this); }
void TMenulist_field::create(short dlg, int x, int y, int dx, int dy, WINDOW parent)
{
_dlg = dlg;
_win = create_window(x, y, dx, dy, parent);
}
void TMenulist_field::set_menu(TMenu_tree& mt)
{
TMenulist_window& w = (TMenulist_window&)win();
w.set_menu(mt);
}
void TMenulist_field::curr_item(TToken_string& id) const
{
TMenulist_window& w = (TMenulist_window&)win();
w.curr_item(id);
}
///////////////////////////////////////////////////////////
// TSpidey_mask
///////////////////////////////////////////////////////////
#define DLG_TREE 301
#define DLG_LIST 302
#define DLG_LOOK 303
void draw_spider(WINDOW w, int mode, const PNT& mouse)
{
// Attiva eventuale ragno;
static int _spider = (ADVANCED_GRAPHICS && is_power_reseller(true)) ?
ini_get_int(CONFIG_GUI, "Colors", "TreeView", 3) : 0;
if (_spider>=2 && xvt_vobj_is_focusable(w))
{
RCT client; xvt_vobj_get_client_rect(w, &client);
CBRUSH brush_yellow;
brush_yellow.color = _spider == 4 ? COLOR_WHITE : COLOR_YELLOW;
brush_yellow.pat = PAT_SOLID;
CPEN pen_thick; pen_thick.color = COLOR_BLACK;
pen_thick.pat = PAT_SOLID; pen_thick.style =P_SOLID;
pen_thick.width = 2;
const int nRadius = 48;
if (client.right > 2*nRadius && client.bottom > 2*nRadius)
{
const PNT p0 = { client.top+3*nRadius/2, client.right-3*nRadius/2 }; // Centro dello smile
if (mode & 0x1)
{
// Disegno la faccina
xvt_dwin_set_cbrush(w, &brush_yellow);
xvt_dwin_set_cpen(w, &pen_thick);
RCT rct; xvt_rect_set(&rct, p0.h-nRadius, p0.v-nRadius, p0.h+nRadius, p0.v+nRadius);
xvt_dwin_draw_oval(w, &rct);
}
xvt_dwin_set_std_cpen(w, TL_PEN_BLACK);
if (mode & 0x2)
{
const int eye = nRadius/4;
const int pupil = 2*eye/3;
RCT rct; // rettangolo jolly
// Disegno gli occhietti
for (int i = 0; i < 2; i++)
{
// Calcolo il centro dell'occhietto
const PNT p1 = { p0.v-eye, i == 0 ? p0.h-(5*eye/4) : p0.h+(5*eye/4) };
// Disegno il bulbo
xvt_rect_set(&rct, p1.h-eye, p1.v-2*eye, p1.h+eye, p1.v+2*eye);
xvt_dwin_set_std_cbrush(w, TL_BRUSH_WHITE);
xvt_dwin_draw_oval(w, &rct);
// Disegno la pupilla
const double angle = atan2(double(mouse.v - p1.v), double(mouse.h - p1.h));
const int mx = eye-pupil+1; int dx = mouse.h - p1.h;
const int my = 2*eye-pupil+1; int dy = mouse.v - p1.v;
if (abs(dx) > mx || abs(dy) > my)
{
dx = int(cos(angle)*mx+0.5);
dy = int(sin(angle)*my+0.5);
}
xvt_rect_set(&rct, p1.h-pupil+dx, p1.v-pupil+dy, p1.h+pupil+dx, p1.v+pupil+dy);
xvt_dwin_set_std_cbrush(w, TL_BRUSH_BLACK);
xvt_dwin_draw_oval(w, &rct);
xvt_dwin_set_std_cbrush(w, TL_BRUSH_WHITE);
xvt_rect_deflate(&rct, 3*pupil/2, 3*pupil/2);
xvt_rect_offset(&rct, -pupil/2, -pupil/2);
xvt_dwin_draw_oval(w, &rct);
}
// Disegno la boccuccia aperta se il mouse e' vicino
const int dx = mouse.h-p0.h, dy = mouse.v-p0.v;
const bool vicino = dx*dx+dy*dy < 65536;
xvt_rect_set(&rct, p0.h-nRadius/2, p0.v+nRadius/4, p0.h+nRadius/2, p0.v+3*nRadius/4);
if (vicino)
{
xvt_dwin_set_std_cbrush(w, TL_BRUSH_BLACK);
xvt_dwin_draw_oval(w, &rct);
}
else
{
const int my = (rct.top + rct.bottom)/2;
xvt_dwin_set_std_cpen(w, TL_PEN_HOLLOW);
xvt_dwin_set_cbrush(w, &brush_yellow);
xvt_dwin_draw_oval(w, &rct);
xvt_dwin_set_std_cpen(w, TL_PEN_BLACK);
xvt_dwin_draw_arc(w, &rct, rct.left, my, rct.right, my);
}
// Il puntatore del mouse diventa una mosca vicino al ragno
xvt_win_set_cursor(w, vicino ? 8883 : CURSOR_ARROW);
}
}
}
}
void TSpidey_mask::on_firm_change()
{
force_update();
}
WINDOW TSpidey_mask::dlg2win(short id) const
{
WINDOW w = NULL_WIN;
TMask_field* f = find_by_id(id);
if (f && f->is_kind_of(CLASS_WINDOWED_FIELD))
w = ((const TWindowed_field*)f)->win().win();
return w;
}
bool TSpidey_mask::stop_run(KEY k)
{
if (k == K_CTRL+'R')
return TWindow::stop_run(k);
if (k == K_QUIT)
{
if (ADVANCED_GRAPHICS)
{
const int divider = 8;
const WINDOW window[4] = { win(), dlg2win(101), dlg2win(102), dlg2win(103) };
XVT_IMAGE image[4]; memset(image, 0, sizeof(image));
int i;
for (i = 0; i < 4; i++)
{
const WINDOW& w = window[i];
if (w != NULL_WIN)
{
RCT rct; xvt_vobj_get_client_rect(w, &rct);
RCT irct = rct; irct.right /= divider; irct.bottom /= divider;
XVT_IMAGE cap = xvt_image_capture(w, &rct);
XVT_IMAGE img = xvt_image_create(XVT_IMAGE_RGB, irct.right, irct.bottom, 0);
xvt_image_transfer(img, cap, &irct, &rct);
xvt_image_destroy(cap);
for (int y = 0; y < irct.bottom; y++)
{
for (int x = 0; x < irct.right; x++)
{
COLOR rgb = xvt_image_get_pixel(img, x, y);
const unsigned int r = XVT_COLOR_GET_RED(rgb) / 2;
const unsigned int g = XVT_COLOR_GET_GREEN(rgb) / 2;
const unsigned int b = XVT_COLOR_GET_BLUE(rgb) / 2;
xvt_image_set_pixel(img, x, y, XVT_MAKE_COLOR(r, g, b));
}
}
image[i] = img;
}
}
for (i = 3; i >= 0; i--) if (image[i] != NULL)
{
const WINDOW& w = window[i];
if (w != NULL_WIN)
{
RCT rct; xvt_vobj_get_client_rect(w, &rct);
RCT irct = rct; irct.right /= divider; irct.bottom /= divider;
xvt_dwin_draw_image(w, image[i], &rct, &irct);
}
}
// Butto via le immagini dopo averle disegnate tutte
for (i = 3; i >= 0; i--)
xvt_image_destroy(image[i]);
if (installing()) //se e' stata lanciata la installazione moduli...
{
xvt_sys_sleep(1); //..aspetta un attimo poi forza l'uscita
}
else
{
if (!yesno_box(TR("Si desidera uscire?"))) //..altrimenti chiede educatamente se si desidera uscire
{
for (i = 0; i < 3; i++)
{
if (window[i] != NULL)
xvt_dwin_invalidate_rect(window[i], NULL);
}
return false;
}
}
}
}
return TMask::stop_run(k);
}
bool TSpidey_mask::on_key(KEY k)
{
if (k == K_FORCE_CLOSE || k == K_QUIT)
return stop_run(k);
return TMask::on_key(k);
}
TSpidey_mask::TSpidey_mask() : TAutomask ("Menu", 1, 0, 0, 0, 0)
{ }
///////////////////////////////////////////////////////////
// TExplorer_mask
///////////////////////////////////////////////////////////
void TExplorer_mask::update()
{
TMask::update();
if (ADVANCED_GRAPHICS)
{
WINDOW w = toolwin();
RCT client; xvt_vobj_get_client_rect(w, &client);
const TString& ragsoc = prefix().firm().ragione_sociale();
const int len = xvt_dwin_get_text_width(w, ragsoc, -1);
xvt_dwin_draw_text(w, (client.right-len)/2, client.bottom-2, ragsoc, -1);
const PNT pnt = { 0, 0 };
draw_spider(w, 0x3, pnt);
}
}
long TExplorer_mask::handler(WINDOW win, EVENT* ep)
{
if (ep->type == E_MOUSE_MOVE)
draw_spider(toolwin(), 0x3, ep->v.mouse.where);
return TSpidey_mask::handler(win, ep);
}
void TExplorer_mask::select_tree_current()
{
TTree_field& tf = tfield(DLG_TREE);
TMenulist_field& mf = (TMenulist_field&)field(DLG_LIST);
TMenu_tree& mt = (TMenu_tree&)*tf.tree();
mf.set_menu(mt);
synchronize_tree_field(tf);
mf.set_focus();
}
bool TExplorer_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch(o.dlg())
{
case DLG_TREE:
if (e == fe_modify)
{
TTree_field& tf = (TTree_field&)o;
TMenu_tree& mt = *(TMenu_tree*)tf.tree();
if (!_sincronaising)
{
const TMenuitem& mi = mt.curr_item();
if (mi.perform() && mt.goto_firstson())
{
TMenulist_field& mf = (TMenulist_field&)field(DLG_LIST);
mf.set_menu(mt);
}
}
else
{
TMenulist_field& mf = (TMenulist_field&)field(DLG_LIST);
mf.set_menu(mt);
}
}
break;
case DLG_SHRINK:
if (e == fe_button)
{
TTree_field& tf = tfield(DLG_TREE);
TTree& mt = *tf.tree();
mt.shrink_all();
mt.goto_root();
select_tree_current();
}
break;
case DLG_FINDREC:
if (e == fe_button)
{
TString80 str = _last_search_string;
const char* s = xvt_dm_post_string_prompt(TR("Testo"), str.get_buffer(), str.size());
if (s && *s)
{
_last_search_string = s;
send_key(K_F3, 0);
}
}
break;
case DLG_CONFIG:
dispatch_e_menu(TASK_WIN, MENU_ITEM_ID(2));
break;
case DLG_ADDPREF:
dispatch_e_menu(TASK_WIN, MENU_ITEM_ID(5));
break;
case DLG_PREF:
dispatch_e_menu(TASK_WIN, MENU_ITEM_ID(6));
break;
case DLG_USER:
dispatch_e_menu(TASK_WIN, MENU_ITEM_ID(7));
break;
default:
break;
}
return true;
}
bool TExplorer_mask::on_key(KEY k)
{
if (k == K_F3 || k == K_F8)
{
TTree_field& tf = tfield(DLG_TREE);
TMenu_tree& mt = *(TMenu_tree*)tf.tree();
if (_last_search_string.full() && mt.find_string(_last_search_string))
select_tree_current();
else
beep();
return true;
}
return TSpidey_mask::on_key(k);
}
TExplorer_mask::TExplorer_mask(TMenu& menu) : _tree(menu)
{
add_button_tool(DLG_SHRINK, TR("Menu Iniziale"), TOOL_FIRSTREC);
add_button_tool(DLG_FINDREC, TR("Ricerca"), TOOL_FINDREC);
add_button_tool(DLG_NULL, "", 0);
add_button_tool(DLG_CONFIG, TR("Opzioni"), TOOL_CONFIG);
add_button_tool(DLG_USER, TR("Utente"), TOOL_PERMISSIONS);
add_button_tool(DLG_SETPRINT, TR("Imposta"), TOOL_SETPRINT);
add_button_tool(DLG_NULL, "", 0);
add_button_tool(DLG_PREF, TR("Preferiti"), TOOL_PREF);
add_button_tool(DLG_ADDPREF, TR("Aggiungi"), TOOL_ADDPREF);
add_button_tool(DLG_NULL, "", 0);
add_button_tool(DLG_INFO, TR("Info"), TOOL_INFO);
add_button_tool(DLG_HELP, TR("Help"), TOOL_HELP);
add_button_tool(DLG_QUIT, TR(""), TOOL_QUIT);
WINDOW panel = page_win(0);
// Tree view
TTree_field& trifola = add_tree(DLG_TREE, 0, 0, 0, 32, 0);
trifola.set_tree(&_tree);
trifola.hide_leaves(true); // Nascondo le foglie che vengono gestite dal TMenulist_field
// List view
TMenulist_field* mf = new TMenulist_field(this);
mf->create(DLG_LIST, 48, 0, 0, 0, panel);
mf->set_menu(*(TMenu_tree*)trifola.tree());
add_field(mf);
xvt_pane_add(panel, dlg2win(DLG_LIST), "Main", 0, 0); // Right pane
xvt_pane_change_flags(dlg2win(DLG_LIST), 1<<10,0);
xvt_pane_add(panel, dlg2win(DLG_TREE), "Menu", 1, 0); // Left pane
set_handlers();
}
const TString& get_logo()
{
static TFilename currlogo;
if (currlogo.blank())
{
// Controllo se il cliente ha un menulogo,jpg nella cartella custom
currlogo = "menulogo.jpg";
if (currlogo.custom_path())
{
currlogo.lower();
if (currlogo.find("custom") < 0)
currlogo.cut(0);
}
else
currlogo.cut(0); //deve azzerarlo senn<6E> resta menulogo.jpg
if (currlogo.blank())
{
//seleziona il logo da usare in base al producer!!
currlogo = get_oem_info("Logo");
currlogo.insert("setup/");
if (!currlogo.exist())
currlogo.cut(0);
}
if (currlogo.blank())
{
//se non trova il logo del producer usa il logo standard
currlogo = "sirio_logo.jpg";
}
}
return currlogo;
}