#include #include #include #include #include #include #include #include #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); if (mi.is_program()) { int ico = mi.icon(); if (ico <= 0) ico = ICON_RSRC; return get_res_icon(ico); } return 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; 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 void 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 RCT rct; xvt_vobj_get_client_rect(win(), &rct); const int width = rct.right - rct.left; const int height = rct.bottom - rct.top; xvtil_set_font(win(), 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(win(), ix, iy, 10202); if (ico > 0) xvt_dwin_draw_icon(win(), ix, iy+4, ico); } else { xvt_dwin_draw_icon(win(), 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(win(), 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(win(), line, -1); const int x = cx - ll/2; xvt_dwin_draw_text(win(), x, y, line, -1); y += CHARY-2; } if (item.disabled()) xvt_dwin_draw_icon(win(), ix+4, iy+4, 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ù 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); } } void 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; } 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); } } void TExplorer_mask::handler(WINDOW win, EVENT* ep) { if (ep->type == E_MOUSE_MOVE) draw_spider(toolwin(), 0x3, ep->v.mouse.where); 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_LENTE); 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ò 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; }