#include "ba0103.h" #include #include #include #include #include #include #include enum { DLG_TREE = 101, DLG_LOOK = 102, DLG_MAIN = 103 }; /////////////////////////////////////////////////////////// // TApp_window & TBook_window declarations /////////////////////////////////////////////////////////// class TBook_window; class TApp_window : public TWindow { TBook_window* _owner; TString _appname; protected: virtual long handler(WINDOW win, EVENT* ep); public: const TString& app_name() const { return _appname; } TApp_window(TBook_window* owner, const char* appname); ~TApp_window(); }; class TBook_window : public TControl_host_window { TImage _logo, _back; TAssoc_array _alfano; protected: virtual void update(); void force_page(short page); void erode_antipa(); public: virtual long handler(WINDOW win, EVENT* ep); // Used by E_PROCESS WINDOW notebook() const { return _ctrl; } short pages() const; short curr_page() const; WINDOW page_win(short pg) const; short find_page(WINDOW win) const; short add_page(const TMenuitem& mi); void set_page_caption(short page, const TString& caption, int icon); bool remove_page(WINDOW page); void set_logo(const char* logo); void set_back(const TString& back); void kill_processes(); TBook_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner); ~TBook_window(); }; /////////////////////////////////////////////////////////// // TApp_window /////////////////////////////////////////////////////////// long TApp_window::handler(WINDOW win, EVENT* ep) { switch (ep->type) { /* case E_TIMER: if (xvt_vobj_is_focusable(win)) { // Leggo il titolo della finestra corrente TString256 title; xvt_vobj_get_title(win, title.get_buffer(), title.size()); // Se la finestra ospita gia' un'applicazione non si chiama piu' "__CAMPO_HOST_WINDOW__" if (title != __MAGIC_CAPTION__) { if (xvt_win_get_children_count(win) == 0) // Se l'applicazione e' morta ... { xvt_timer_destroy(ep->v.timer.id); // Ammazzo il timer ... _owner->remove_page(win); // ... e pure la pagina ospitante } } } break; */ case E_DESTROY: xvt_sys_close_children(win); break; default: break; } return TWindow::handler(win, ep); } TApp_window::TApp_window(TBook_window* owner, const char* appname) : _owner(owner), _appname(appname) { WINDOW w = create(0, 0, -1, -1, __MAGIC_CAPTION__, WSF_NONE, W_PLAIN, owner->notebook()); //xvt_timer_create(w, 1000); // Ogni tanto controllo che l'applicazione sia ancora viva } TApp_window::~TApp_window() { xvt_sys_close_children(win()); } /////////////////////////////////////////////////////////// // TBook_window /////////////////////////////////////////////////////////// void TBook_window::update() { // Disegno lo sfondo solo se non esiste nessun notebook che occupa tutto lo spazio! if (_ctrl == NULL_WIN) { clear(NORMAL_BACK_COLOR); if (ADVANCED_GRAPHICS) { WINDOW w = win(); RCT rctw; xvt_vobj_get_client_rect(w, &rctw); if (rctw.right >= 64 && rctw.bottom >= 64) { if (_logo.ok()) { const RCT& r = _logo.draw(w, rctw, 'R', 'B', '-'); // Disegna logo in basso if (_back.ok() && r.top >= 64) { rctw.bottom = r.top; _back.draw(w, rctw, 'R', 'T', '*'); // Disegna sfondo in alto } } const PNT pnt = { 0, 0 }; draw_spider(w, 0x3, pnt); } } } } short TBook_window::pages() const { return _ctrl == NULL_WIN ? 0 : xvt_notebk_get_num_tabs(_ctrl); } short TBook_window::curr_page() const { return _ctrl == NULL_WIN ? -1 : xvt_notebk_get_front_page(_ctrl); } static BOOLEAN hell_riser(WINDOW child, long data) { if (data > 0) xvt_vobj_raise(child); xvt_win_enum_wins(child, hell_riser, data+1, 0); return TRUE; } void TBook_window::force_page(short page) { if (page >= 0 && page < pages()) // Implies _ctrl != NULL_WIN too { xvt_notebk_set_front_page(_ctrl, page); WINDOW w = xvt_notebk_get_page(_ctrl, page); xvt_win_enum_wins(w, hell_riser, 0, 0); } } long TBook_window::handler(WINDOW win, EVENT* ep) { switch (ep->type) { case E_MOUSE_MOVE: if (_ctrl == NULL_WIN) draw_spider(win, 0x3, ep->v.mouse.where); break; case E_CONTROL: if (ep->v.ctl.ci.type == WC_NOTEBK && ep->v.ctl.ci.win == _ctrl) { if (ep->v.ctl.ci.v.notebk.page != NULL_WIN) // != NULL_WIN means page CHANGED, non changing! force_page(ep->v.ctl.ci.v.notebk.page_new); return 0L; } break; case E_SIZE: if (pages() > 0) dispatch_e_menu(cur_win(), 8883); // Notifica un ridimensionamento indesiderato break; case E_PROCESS: { TString8 pid; pid << ep->v.process.pid; switch (ep->v.process.msg_id) { case 0: { TString16 pg; pg << (long)page_win(pages()-1); _alfano.add(pid, pg); // Memorizza la pagina che ospita il processo } break; default: { const TString* pg = (const TString*)_alfano.objptr(pid); if (pg != NULL) { WINDOW pw = atol(*pg); // Converte pg _alfano.remove(pid); // Distrugge pg remove_page(pw); // Elimina pagina } } } break; } break; default: break; } return TControl_host_window::handler(win, ep); } WINDOW TBook_window::page_win(short pg) const { WINDOW win = NULL_WIN; if (_ctrl != NULL_WIN) { if (pg < 0) pg = xvt_notebk_get_front_page(_ctrl); win = xvt_notebk_get_page(_ctrl, pg); } return win; } short TBook_window::find_page(WINDOW win) const { short pg = -1; for (pg = pages()-1; pg >= 0; pg--) if (xvt_notebk_get_page(_ctrl, pg) == win) break; return pg; } short TBook_window::add_page(const TMenuitem& mi) { if (_ctrl == NULL_WIN) { XVT_COLOR_COMPONENT xcc[4]; memset(xcc, 0, sizeof(xcc)); xcc[0].type = XVT_COLOR_BACKGROUND; xcc[0].color = MASK_BACK_COLOR; xcc[1].type = XVT_COLOR_FOREGROUND; xcc[1].color = NORMAL_COLOR; WIN_DEF wd; memset(&wd, 0, sizeof(wd)); wd.wtype = WC_NOTEBK; wd.ctlcolors = xcc; wd.v.ctl.ctrl_id = DLG_MAIN; wd.v.ctl.font_id = xvtil_default_font(); wd.v.ctl.flags = CTL_FLAG_TAB_BOTTOM; // should be wxCHECK_VERSION(2,8,9) wd.v.ctl.flags |= CTL_FLAG_CENTER_JUST; // old compatibility flags xvt_vobj_get_client_rect(win(), &wd.rct); _ctrl = xvt_ctl_create_def(&wd, win(), 0L); // Blocca le dimensioni del pannello (Non va micca!) xvt_pane_set_size_range(win(), wd.rct.right, wd.rct.right, wd.rct.right); enable_options_menu(false); // Disabilita le opzioni } for (short pg = pages()-1; pg >= 0; pg--) { WINDOW awin = xvt_notebk_get_page(_ctrl, pg); TApp_window* w = (TApp_window*)xvt_vobj_get_data(awin); if (w != NULL && w->app_name() == mi.action()) { force_page(pg); return -1; // Don't perform menu! } } TApp_window* w = new TApp_window(this, mi.action()); const short pg = xvt_notebk_add_page(_ctrl, w->win(), mi.caption(), NULL, -1); if (pg >= 0) force_page(pg); else delete w; return pg; } void TBook_window::set_page_caption(short page, const TString& caption, int icon) { if (_ctrl != NULL_WIN && page >= 0) { xvt_notebk_set_tab_title(_ctrl, page, caption); // Titolo dell'orecchio xvt_notebk_set_tab_icon(_ctrl, page, icon); // Icona dell'orecchio xvt_notebk_set_page_title(_ctrl, page, caption); // Titolo della finestra } } bool TBook_window::remove_page(WINDOW page) { bool bFound = false; for (int p = pages()-1; p >= 0; p--) { WINDOW win = xvt_notebk_get_page(_ctrl, p); if (win == page || page == NULL_WIN) { xvt_notebk_rem_page(_ctrl, p); bFound = true; if (page != NULL_WIN) break; } } if (bFound) { xvt_vobj_raise(TASK_WIN); // Riporta in primo piano il menu principale if (pages() == 0) { erode_antipa(); force_update(); } else force_page(0); } return bFound; } void TBook_window::erode_antipa() { if (_ctrl != NULL_WIN) { // Ammazza anche tutti ... coloro che son sospesi for (int p = pages()-1; p >= 0; p--) xvt_notebk_rem_page(_ctrl, p); xvt_vobj_destroy(_ctrl); _ctrl = NULL_WIN; enable_options_menu(true); // Riabilita le opzioni } } void TBook_window::set_logo(const char* logo) { _logo.load(logo); if (is_power_reseller(true)) { const short w = _logo.width(); const short h = _logo.height(); const short h2 = h/4; XVT_IMAGE big = xvt_image_create(XVT_IMAGE_RGB, w, h+h2, MASK_BACK_COLOR); RCT rct; xvt_rect_set(&rct, 0, 0, w, h); xvt_image_transfer(big, _logo.xvt_image(), &rct, &rct); XVT_IMAGE tile = get_background_texture(); if (tile != NULL) { short tw, th; xvt_image_get_dimensions(tile, &tw, &th); if (tw > 0 && th > 0) { RCT src; xvt_rect_set(&src, 0, 0, tw, th); for (short y = 0; y < h2; y += th) { for (short x = 0; x < w; x += tw) { RCT dst; xvt_rect_set(&dst, x, y+h, x+tw, y+th+h); xvt_image_transfer(big, tile, &dst, &src); } } } } for (short y = 0; y < h2; y++) { const double weight = 0.5+double(y)/double(2*h2); const short sy = h-y*h/h2-1; for (short x = 0; x < w; x++) { const short sx = x-2*y; if (sx >= 0) { const COLOR src = xvt_image_get_pixel(big, sx, sy); const unsigned char r = XVT_COLOR_GET_RED(src); const unsigned char g = XVT_COLOR_GET_GREEN(src); const unsigned char b = XVT_COLOR_GET_BLUE(src); if (abs(r-g)>8 || abs(g-b)>8) // Non e' grigio, cioe' !(r==g && g==b) { const COLOR dst = xvt_image_get_pixel(big, x, y+h); COLOR col = blend_colors(dst, src, weight); xvt_image_set_pixel(big, x, y+h, col); } } } } _logo.set(big); } else { if (_logo.ok() && can_be_transparent(_logo)) _logo.convert_transparent_color(NORMAL_BACK_COLOR); } } void TBook_window::set_back(const TString& back) { if (ADVANCED_GRAPHICS && is_power_station()) { TFilename str = back; str.ext("png"); bool ok = str.custom_path(); if (!ok) { str.ext("jpg"); ok = str.custom_path(); } if (!ok) { str.ext("gif"); str.custom_path(); } if (ok && _back.load(back)) { TWait_cursor hourglass; const short w = _back.width(); const short h = _back.height(); for (short y = 0; y < h; y++) { for (short x = 0; x < w; x++) { const COLOR rgb = _back.get_pixel(x, y); if (rgb != NORMAL_BACK_COLOR) { const unsigned char r = XVT_COLOR_GET_RED(rgb); const unsigned char g = XVT_COLOR_GET_GREEN(rgb); const unsigned char b = XVT_COLOR_GET_BLUE(rgb); const COLOR col = blend_colors(NORMAL_BACK_COLOR, rgb, 0.9); if (col != rgb) _back.set_pixel(x, y, col); } } } if (pages() == 0) force_update(); } } } void TBook_window::kill_processes() { TString_array pid; _alfano.get_keys(pid); for (int i = pid.last(); i >= 0; i--) { const long p = atol(pid.row(i)); xvt_sys_kill(p); } } TBook_window::TBook_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner) : TControl_host_window(x, y, dx, dy, parent, owner), _logo(""), _back("") { set_logo(get_logo()); } TBook_window::~TBook_window() { erode_antipa(); } /////////////////////////////////////////////////////////// // TBook_field /////////////////////////////////////////////////////////// class TBook_field : public TWindowed_field { protected: virtual TField_window* create_window(int x, int y, int dx, int dy, WINDOW parent); public: virtual void create(short dlg, int x, int y, int dx, int dy, WINDOW parent); short pages() const; short add_page(const TMenuitem& mi); void set_page_caption(short page, const TString& caption, int icon); void set_back(const TString& image); WINDOW page_win(short page); void remove_all_pages(); void remove_page(short page); void kill_processes() { ((TBook_window&)win()).kill_processes(); } TBook_field(TMask* m) : TWindowed_field(m) {} }; short TBook_field::pages() const { TBook_window& bw = (TBook_window&)win(); return bw.pages(); } short TBook_field::add_page(const TMenuitem& mi) { TBook_window& bw = (TBook_window&)win(); return bw.add_page(mi); } void TBook_field::set_page_caption(short page, const TString& caption, int icon) { TBook_window& bw = (TBook_window&)win(); bw.set_page_caption(page, caption, icon); } void TBook_field::set_back(const TString& image) { TBook_window& bw = (TBook_window&)win(); bw.set_back(image); } WINDOW TBook_field::page_win(short page) { TBook_window& bw = (TBook_window&)win(); return bw.page_win(page); } void TBook_field::remove_all_pages() { TBook_window& bw = (TBook_window&)win(); bw.remove_page(NULL_WIN); } void TBook_field::remove_page(short page) { TBook_window& bw = (TBook_window&)win(); if (page >= 0) { WINDOW pw = bw.page_win(page); if (pw != NULL_WIN) bw.remove_page(pw); } else bw.remove_page(NULL_WIN); } TField_window* TBook_field::create_window(int x, int y, int dx, int dy, WINDOW parent) { return new TBook_window(x, y, dx, dy, parent, this); } void TBook_field::create(short dlg, int x, int y, int dx, int dy, WINDOW parent) { _dlg = dlg; _win = create_window(x, y, dx, dy, parent); } /////////////////////////////////////////////////////////// // TOutlook_mask /////////////////////////////////////////////////////////// void TOutlook_mask::save_perspective(int per) { const TTree_field& bf = tfield(DLG_TREE); TString str(_per_def.size()); const int sz = xvt_pane_manager_save_perspective(bf.win().win(), NULL, 0); xvt_pane_manager_save_perspective(bf.win().win(), str.get_buffer(sz), sz); switch (per) { case 1: { TConfig ini(CONFIG_GUI, "ba0103"); ini.set("Layout", str, NULL, true, bf.dlg()); } break; case 2: _per_tmp = str; break; default: _per_def = str; break; } } void TOutlook_mask::load_perspective(int per) { const TTree_field& bf = tfield(DLG_TREE); TString str; switch (per) { case 1: { TConfig ini(CONFIG_GUI, "ba0103"); str = ini.get("Layout", NULL, bf.dlg()); } break; case 2: str = _per_tmp; break; default: str = _per_def; break; } xvt_pane_manager_load_perspective(bf.win().win(), str); } TBook_field& TOutlook_mask::book_field() const { return (TBook_field&)field(DLG_MAIN); } bool TOutlook_mask::can_be_closed() const { const bool yes = !is_running(); if (!yes) { TBook_field& bf = book_field(); if (bf.pages() > 0) { TMask cm(TR("Chiusura applicazioni"), 1, 50, 7); cm.add_radio(DLG_USER, 0, TR("Azione"), 1, 0, 48, "0|1", TR("Non chiudere le applicazioni in esecuzione|Chiusura forzata (solo in caso d'emergenza)")); cm.add_button(DLG_OK, 0, "", -12, -1, 10, 2); cm.add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2); if (cm.run() == K_ENTER && cm.get_int(DLG_USER)) bf.kill_processes(); } if (bf.pages() == 0) ((TOutlook_mask*)this)->send_key(K_FORCE_CLOSE, 0); } return yes; } short TOutlook_mask::add_page(const TMenuitem& mi) { TBook_field& bf = book_field(); if (bf.pages() == 0) save_perspective(2); // Save temporary perspective return bf.add_page(mi); } void TOutlook_mask::set_page_caption(short page, const TString& caption, int icon) { TBook_field& bf = book_field(); bf.set_page_caption(page, caption, icon); } long TOutlook_mask::handler(WINDOW w, EVENT* ep) { if (ep->type == E_COMMAND) { switch (ep->v.cmd.tag) { case 8001: set(DLG_LOOK, "", true); // Seleziona menu completo break; case 8002: load_perspective(0); // Ricarica default break; case 8003: xvt_dm_post_string_prompt(TR("Testo da cercare"), _last_search.get_buffer(), _last_search.size()); // continue to 8004 case 8004: if (_last_search.full() && _tree.find_string(_last_search)) { TTree_field& tf = tfield(DLG_TREE); synchronize_tree_field(tf); tf.select_current(); } break; case 8005: dispatch_e_menu(TASK_WIN, M_FILE_ABOUT); break; case 8883: if (!_locked && _per_tmp.not_empty()) { _locked = true; load_perspective(2); // Ripristina layout predefinito do_events(); // Evita doppio evento E_SIZE _locked = false; } break; default : break; } } else if (ep->type == E_PROCESS) { TBook_field& bf = book_field(); TBook_window& bw = (TBook_window&)bf.win(); bw.handler(bw.win(), ep); } return TSpidey_mask::handler(w, ep); } bool TOutlook_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case DLG_TREE: if (e == fe_button) { const TMenuitem& mi = _tree.curr_item(); if (mi.enabled()) { if (mi.is_submenu()) { if (!_tree.expanded()) mi.perform(); } else { TBook_field& bf = book_field(); // ba1 e ba2 sono programmi di manutenzione da eseguire in modo esclusivo if (mi.run_modal()) { if (bf.pages() > 0) return warning_box(TR("Questa applicazione richiede che vengano chiuse tutte le altre!")); mi.perform(); // Esegui in sincrono e a tutto schermo if (installing()) // when ba1 -6 stop_run(K_FORCE_CLOSE); } else if (mi.run_fullscreen()) { mi.perform(); // Esegui in asincrono a pieno schermo } else { // Crea una pagina per accogliere la nuova applicazione asincrona const short pg = add_page(mi); if (pg >= 0) { if (mi.perform()) // Esegui in asincrono in pagina nuova { for (int i = 0; i < 20; i++) { xvt_sys_sleep(500); if (xvt_win_get_children_count(bf.page_win(pg)) != 0) break; } int ico = mi.icon(); if (ico <= 0 || ico == ICON_RSRC) { const int area = get_int(DLG_LOOK); if (area > 0 && area < _icon.items()) ico = _icon.get_int(area); else ico = ICON_RSRC; } set_page_caption(pg, mi.caption(), ico); } else book_field().remove_page(pg); // Rimuovi pagina inm caso d'errore } } } } } break; case DLG_LOOK: if (e == fe_modify) { TTree_field& tf = tfield(DLG_TREE); const int sel = atoi(o.get()); TToken_string id("MENU_000", '/'); _tree.change_root(id); // Torna alla radice standard if (sel > 0) { for (int i = 1; i < sel; i++) { do _tree.goto_rbrother(); // Sceglie l'opportuno ramo principale while (!_tree.enabled()); } _tree.goto_firstson(); _tree.curr_id(id); _tree.change_root(id.get(1)); // Imposta una nuova radice synchronize_tree_field(tf); } else { _tree.goto_root(); _tree.shrink_all(); tf.win().force_update(); tf.on_key(K_SPACE); } if (_picture.objptr(sel)) book_field().set_back(_picture.row(sel)); main_app().enable_menu_item(30005, id.find("MENU_PREFERITI") < 0); } else if (e == fe_init) { TOutlook_field& of = (TOutlook_field&)o; of.clear(); TString caption; int ico = 10219; of.add_item(ico, TR("Menu principale"), 0); _icon.add_long(ico); TToken_string id("MENU_000", '/'); _tree.change_root(id); // Torna alla radice standard for (bool ok = _tree.goto_root(); ok; ok = _tree.goto_rbrother()) { const TMenuitem& mi = _tree.curr_item(); if (mi.enabled()) { _tree.get_description(caption); const int ico = mi.icon(); of.add_item(ico, caption, 0); _icon.add_long(ico); // Memorizza icona per orecchie if (_picture.empty()) _picture.add(mi.submenu().picture()); _picture.add(mi.child_submenu()->picture()); } } if (atoi(of.get()) >= of.items()-1) // Se sono sui preferiti ... set(o.dlg(), "", true); // ... torna al menu principale if (_picture.objptr(0)) book_field().set_back(_picture.row(0)); } break; default: break; } if (e == fe_info) { MENU_ITEM* mi = xvt_res_get_menu(10004); // Menu_Ba0-3 if (mi != NULL) { dictionary_translate_menu(mi); const PNT pos = { -1, -1 }; xvt_menu_popup(mi->child, o.parent(), pos, XVT_POPUP_LEFT_ALIGN, 0); xvt_res_free_menu_tree(mi); return false; // Non fare la gestione standard } } return true; } TOutlook_mask::TOutlook_mask(TMenu& menu) : _tree(menu), _locked(false) { xvtil_statbar_destroy(); // Ammazza status bar inutile RCT rct; xvt_vobj_get_client_rect(TASK_WIN, &rct); WINDOW panel = page_win(0); xvt_vobj_move(panel, &rct); // Resiza la maschera in modo da occupare lo spazio liberato menu.set_mask_mode(3); // Outlook mode const int w = 24; const int h = rows() / 2; TTree_field& trifola = add_tree(DLG_TREE, 0, 0, 0, w, h); trifola.set_tree(&_tree); TOutlook_field* of = new TOutlook_field(this); of->create(DLG_LOOK, 0, h, w, h, panel); add_field(of); TBook_field* cf = new TBook_field(this); cf->create(DLG_MAIN, w, 0, 0, 0, panel); add_field(cf); xvt_pane_add(panel, dlg2win(DLG_TREE), "Menu", 1, 0); // Left upper pane xvt_pane_add(panel, dlg2win(DLG_LOOK), "Aree", 1, 0); // Left lower pane xvt_pane_add(panel, dlg2win(DLG_MAIN), "Main", 0, 0); // Main pane save_perspective(0); // Salva default load_perspective(1); // Carica custom set_handlers(); } TOutlook_mask::~TOutlook_mask() { save_perspective(1); // Salva custom // Ricostruisci status bar tornata utile xvtil_create_statbar(); }