campo-sirio/ba/ba0102.cpp

1292 lines
32 KiB
C++
Raw Normal View History

#include <config.h>
#include <controls.h>
#include <diction.h>
#include <prefix.h>
#include <statbar.h>
#include <toolfld.h>
#include <urldefid.h>
#include <utility.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();
}
struct TFind_node_data
{
TString _id;
size_t _count;
};
struct TFind_string_data
{
TString _str;
TAssoc_array* _ignore_list;
};
HIDDEN bool find_string_callback(TTree& tree, void* jolly, word flags)
{
if (flags == SCAN_PRE_ORDER)
{
TMenu_tree& mt = (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))
return true;
}
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();
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)
_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;
return ico > 0 ? get_res_icon(ico) : 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();
}
TMenu_tree::TMenu_tree(TMenu& menu) : _menu(&menu), _curr_id(128, '/')
{
change_root("MENU_000");
}
///////////////////////////////////////////////////////////
// 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)
{
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) { }
};
inline 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;
Patch level : 2.0 470 Files correlati : ba0.exe ba1.exe ba3.exe ba4.exe Ricompilazione Demo : [ ] Commento : EP20037 Esempio : Visualizzazione liquidazione, Indico: esercizio =2003, mese liquidazione =gennaio seleziono la ditta clicco su conferma. Nella visualizzazione la barra di scorrimento non funziona. EP20038 Inserendo nel campo "utente" un'utente inesistente e nel campo "password" ad.min , entro in campo senza che venga segnalata la non esistenza dell'utente EP20041 Col mouse seleziono un codice di pagamento già inserito e clicco sul bottone stampa.A video (come da impostazioni stampante) viene visualizzata la stampa della condizione di pagamento selezionata.Clicco su stampa, non parte la stampa su carta. Clicco su fine ritorno nella maschera "stampa condizioni di pagamento", clicco su fine errore ba3.exe EP20049 Seleziono un codice valuta inserito con spunta su voce "contro euro" in tabella valute; la spunta viene riportata anche nella maschera "Cambi giornalieri". Inserisco la data di oggi nel campo data del group box valuta e col mouse mi posizono sul campo cambio: la spunta sulla voce "contro euro" scompare EP20050 Clicco sul bottone di ricerca e richiamo una ditta memorizzata. Clicco sul bottone posta errore il campo 203 non nesiste EP20054 Ho registrato tre anagrafiche. Col mouse.Clicco sul bottone di ricerca e richiamo la n°2. Clicco sulla freccia singola a sinistra del bottone ricerca per posizionarmi sull'anagrafica n°1 e viene visualizzato messaggio vuoi registrare le modifiche?(anche per altre freccie associate al bottone) EP20055 Col mouse.Clicco su ricerca e richiamo un'anagrafica già presente.Clicco sul bottone Nuovo:messaggio registrare le modifiche? EP20057 clicco sul bottone di ricerca e seleziono un utente già registrato. I campi vengono compilati, clicco sul bottone nuovo: i campi non vengono svuotati ma compare messaggio "vuoi registrare dati inseriti?" EP20058 Ho inserito n utenti. Clicco sul bottone di ricerca e richiamo un utente già registrato. Clicco sulla freccina singola a sx del botone ricerca (e anche sulle altre freccie): messaggo "vuoi registrare dati inseriti?" EP20064 Richiamo una ditta già inserita clicco sul bottone annulla messaggio: "attività assente si desidera annullare?" EP20075 Tutte le freccie associate al bottone ricerca non funzionano git-svn-id: svn://10.65.10.50/trunk@11128 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-05-14 13:35:51 +00:00
TFilename name;
const char* ext[] = { "jpg", "gif", "bmp", "png", NULL };
for (int i = 0; ext[i] != NULL; i++)
Patch level : 2.0 470 Files correlati : ba0.exe ba1.exe ba3.exe ba4.exe Ricompilazione Demo : [ ] Commento : EP20037 Esempio : Visualizzazione liquidazione, Indico: esercizio =2003, mese liquidazione =gennaio seleziono la ditta clicco su conferma. Nella visualizzazione la barra di scorrimento non funziona. EP20038 Inserendo nel campo "utente" un'utente inesistente e nel campo "password" ad.min , entro in campo senza che venga segnalata la non esistenza dell'utente EP20041 Col mouse seleziono un codice di pagamento già inserito e clicco sul bottone stampa.A video (come da impostazioni stampante) viene visualizzata la stampa della condizione di pagamento selezionata.Clicco su stampa, non parte la stampa su carta. Clicco su fine ritorno nella maschera "stampa condizioni di pagamento", clicco su fine errore ba3.exe EP20049 Seleziono un codice valuta inserito con spunta su voce "contro euro" in tabella valute; la spunta viene riportata anche nella maschera "Cambi giornalieri". Inserisco la data di oggi nel campo data del group box valuta e col mouse mi posizono sul campo cambio: la spunta sulla voce "contro euro" scompare EP20050 Clicco sul bottone di ricerca e richiamo una ditta memorizzata. Clicco sul bottone posta errore il campo 203 non nesiste EP20054 Ho registrato tre anagrafiche. Col mouse.Clicco sul bottone di ricerca e richiamo la n°2. Clicco sulla freccia singola a sinistra del bottone ricerca per posizionarmi sull'anagrafica n°1 e viene visualizzato messaggio vuoi registrare le modifiche?(anche per altre freccie associate al bottone) EP20055 Col mouse.Clicco su ricerca e richiamo un'anagrafica già presente.Clicco sul bottone Nuovo:messaggio registrare le modifiche? EP20057 clicco sul bottone di ricerca e seleziono un utente già registrato. I campi vengono compilati, clicco sul bottone nuovo: i campi non vengono svuotati ma compare messaggio "vuoi registrare dati inseriti?" EP20058 Ho inserito n utenti. Clicco sul bottone di ricerca e richiamo un utente già registrato. Clicco sulla freccina singola a sx del botone ricerca (e anche sulle altre freccie): messaggo "vuoi registrare dati inseriti?" EP20064 Richiamo una ditta già inserita clicco sul bottone annulla messaggio: "attività assente si desidera annullare?" EP20075 Tutte le freccie associate al bottone ricerca non funzionano git-svn-id: svn://10.65.10.50/trunk@11128 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-05-14 13:35:51 +00:00
{
name = key;
name.ext(ext[i]);
if (name.custom_path())
Patch level : 2.0 470 Files correlati : ba0.exe ba1.exe ba3.exe ba4.exe Ricompilazione Demo : [ ] Commento : EP20037 Esempio : Visualizzazione liquidazione, Indico: esercizio =2003, mese liquidazione =gennaio seleziono la ditta clicco su conferma. Nella visualizzazione la barra di scorrimento non funziona. EP20038 Inserendo nel campo "utente" un'utente inesistente e nel campo "password" ad.min , entro in campo senza che venga segnalata la non esistenza dell'utente EP20041 Col mouse seleziono un codice di pagamento già inserito e clicco sul bottone stampa.A video (come da impostazioni stampante) viene visualizzata la stampa della condizione di pagamento selezionata.Clicco su stampa, non parte la stampa su carta. Clicco su fine ritorno nella maschera "stampa condizioni di pagamento", clicco su fine errore ba3.exe EP20049 Seleziono un codice valuta inserito con spunta su voce "contro euro" in tabella valute; la spunta viene riportata anche nella maschera "Cambi giornalieri". Inserisco la data di oggi nel campo data del group box valuta e col mouse mi posizono sul campo cambio: la spunta sulla voce "contro euro" scompare EP20050 Clicco sul bottone di ricerca e richiamo una ditta memorizzata. Clicco sul bottone posta errore il campo 203 non nesiste EP20054 Ho registrato tre anagrafiche. Col mouse.Clicco sul bottone di ricerca e richiamo la n°2. Clicco sulla freccia singola a sinistra del bottone ricerca per posizionarmi sull'anagrafica n°1 e viene visualizzato messaggio vuoi registrare le modifiche?(anche per altre freccie associate al bottone) EP20055 Col mouse.Clicco su ricerca e richiamo un'anagrafica già presente.Clicco sul bottone Nuovo:messaggio registrare le modifiche? EP20057 clicco sul bottone di ricerca e seleziono un utente già registrato. I campi vengono compilati, clicco sul bottone nuovo: i campi non vengono svuotati ma compare messaggio "vuoi registrare dati inseriti?" EP20058 Ho inserito n utenti. Clicco sul bottone di ricerca e richiamo un utente già registrato. Clicco sulla freccina singola a sx del botone ricerca (e anche sulle altre freccie): messaggo "vuoi registrare dati inseriti?" EP20064 Richiamo una ditta già inserita clicco sul bottone annulla messaggio: "attività assente si desidera annullare?" EP20075 Tutte le freccie associate al bottone ricerca non funzionano git-svn-id: svn://10.65.10.50/trunk@11128 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-05-14 13:35:51 +00:00
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)
Patch level : 2.0 470 Files correlati : ba0.exe ba1.exe ba3.exe ba4.exe Ricompilazione Demo : [ ] Commento : EP20037 Esempio : Visualizzazione liquidazione, Indico: esercizio =2003, mese liquidazione =gennaio seleziono la ditta clicco su conferma. Nella visualizzazione la barra di scorrimento non funziona. EP20038 Inserendo nel campo "utente" un'utente inesistente e nel campo "password" ad.min , entro in campo senza che venga segnalata la non esistenza dell'utente EP20041 Col mouse seleziono un codice di pagamento già inserito e clicco sul bottone stampa.A video (come da impostazioni stampante) viene visualizzata la stampa della condizione di pagamento selezionata.Clicco su stampa, non parte la stampa su carta. Clicco su fine ritorno nella maschera "stampa condizioni di pagamento", clicco su fine errore ba3.exe EP20049 Seleziono un codice valuta inserito con spunta su voce "contro euro" in tabella valute; la spunta viene riportata anche nella maschera "Cambi giornalieri". Inserisco la data di oggi nel campo data del group box valuta e col mouse mi posizono sul campo cambio: la spunta sulla voce "contro euro" scompare EP20050 Clicco sul bottone di ricerca e richiamo una ditta memorizzata. Clicco sul bottone posta errore il campo 203 non nesiste EP20054 Ho registrato tre anagrafiche. Col mouse.Clicco sul bottone di ricerca e richiamo la n°2. Clicco sulla freccia singola a sinistra del bottone ricerca per posizionarmi sull'anagrafica n°1 e viene visualizzato messaggio vuoi registrare le modifiche?(anche per altre freccie associate al bottone) EP20055 Col mouse.Clicco su ricerca e richiamo un'anagrafica già presente.Clicco sul bottone Nuovo:messaggio registrare le modifiche? EP20057 clicco sul bottone di ricerca e seleziono un utente già registrato. I campi vengono compilati, clicco sul bottone nuovo: i campi non vengono svuotati ma compare messaggio "vuoi registrare dati inseriti?" EP20058 Ho inserito n utenti. Clicco sul bottone di ricerca e richiamo un utente già registrato. Clicco sulla freccina singola a sx del botone ricerca (e anche sulle altre freccie): messaggo "vuoi registrare dati inseriti?" EP20064 Richiamo una ditta già inserita clicco sul bottone annulla messaggio: "attività assente si desidera annullare?" EP20075 Tutte le freccie associate al bottone ricerca non funzionano git-svn-id: svn://10.65.10.50/trunk@11128 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-05-14 13:35:51 +00:00
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);
statbar_set_title(TASK_WIN, 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; // Delay time before clearing
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
///////////////////////////////////////////////////////////
void draw_spider(WINDOW w, int mode, const PNT& mouse)
{
static int _spider = -1;
if (_spider < 0)
_spider = ADVANCED_GRAPHICS && is_power_station(); // Attiva eventuale ragno
if (_spider && xvt_vobj_is_focusable(w))
{
RCT client; xvt_vobj_get_client_rect(w, &client);
if (client.right > 128 && client.bottom > 64)
{
const PNT p0 = { client.top+64, client.right-64 }; // Centro del ragno
if (mode & 0x1)
{
// Disegno il filo
const PNT p1 = { client.top, p0.h };
xvt_dwin_set_std_cpen(w, TL_PEN_LTGRAY);
xvt_dwin_draw_set_pos(w, p0); xvt_dwin_draw_line(w, p1);
// Disegno il corpicino
xvt_dwin_set_std_cpen(w, TL_PEN_BLACK);
xvt_dwin_set_std_cbrush(w, TL_BRUSH_BLACK);
RCT rct; xvt_rect_set(&rct, p0.h-20, p0.v-10, p0.h+20, p0.v+10);
xvt_dwin_draw_oval(w, &rct);
// Disegno le 4 paia di zampette
const int leg = 20;
const int foot = 10;
for (int i = 0; i < 4; i++)
{
PNT p[8];
p[0].h = rct.left-leg-3*i; p[0].v = rct.bottom-3*i; // Zampa sinistra
p[1].h = p[0].h+foot; p[1].v = p[0].v;
p[2].h = p[0].h; p[2].v = p[0].v-leg-3*i;
p[3] = p0; // Centro del corpo
p[4].h = 2*p0.h-p[2].h; p[4].v = p[2].v; // Zampa destra simmetrica
p[5].h = 2*p0.h-p[1].h; p[5].v = p[1].v;
p[6].h = 2*p0.h-p[0].h; p[6].v = p[0].v;
xvt_dwin_draw_polyline(w, p, 7);
}
}
if (mode & 0x2)
{
const int eye = 7;
const int pupil = 3;
RCT rct; // rettangolo jolly
// Disegno gli occhietti
xvt_dwin_set_std_cpen(w, TL_PEN_BLACK);
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-eye, p1.h+eye, p1.v+eye);
xvt_dwin_set_std_cbrush(w, TL_BRUSH_WHITE);
xvt_dwin_draw_oval(w, &rct);
// Disegno la pupilla
const int dx = mouse.h <= rct.left ? -pupil : (mouse.h >= rct.right ? +pupil : 0);
const int dy = mouse.v <= rct.top ? -pupil : (mouse.v >= rct.bottom ? +pupil : 0);
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);
}
// 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_dwin_set_std_cbrush(w, vicino ? TL_BRUSH_WHITE : TL_BRUSH_BLACK);
xvt_rect_set(&rct, p0.h-eye, p0.v, p0.h+eye, p0.v+eye);
xvt_dwin_draw_oval(w, &rct);
// 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;
const int pos = id2pos(id);
if (pos >= 0)
{
TMask_field& f = fld(pos);
CHECKD(f.is_kind_of(CLASS_WINDOWED_FIELD), "Not a windowed field ", id);
w = ((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
///////////////////////////////////////////////////////////
#define DLG_TREE 301
#define DLG_LIST 302
#define DLG_LOOK 303
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 = "menulogo.jpg";
}
}
return currlogo;
}