#include "ba0103.h" #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; protected: virtual void handler(WINDOW win, EVENT* ep); public: TApp_window(TBook_window* owner); }; class TBook_window : public TControl_host_window { TImage _logo; protected: virtual void update(); virtual void handler(WINDOW win, EVENT* ep); short pages() const; void force_page(short page); void erode_antipa(); public: WINDOW notebook() const { return _ctrl; } WINDOW page_win(short pg); short add_page(const TString& caption); void set_page_caption(short page, const TString& caption, int icon); bool remove_page(WINDOW page); TBook_window(int x, int y, int dx, int dy, WINDOW parent, TWindowed_field* owner); ~TBook_window(); }; /////////////////////////////////////////////////////////// // TApp_window /////////////////////////////////////////////////////////// void 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_MENU__" 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; } TWindow::handler(win, ep); } TApp_window::TApp_window(TBook_window* owner) : _owner(owner) { WINDOW w = create(0, 0, -1, -1, __MAGIC_CAPTION__, WSF_NONE, W_PLAIN, owner->notebook()); xvt_timer_create(w, 1500); // Ogni tanto controllo se l'applicazione e' ancora viva } /////////////////////////////////////////////////////////// // 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(COLOR_WHITE); RCT rctw; xvt_vobj_get_client_rect(win(), &rctw); if (rctw.right >= 64 && rctw.bottom >= 64) { if (_logo.ok()) { RCT rcti = _logo.rect(); if (rcti.right > rctw.right) { const double ratio = double(rctw.right) / double(rcti.right); rcti.right = int(rcti.right * ratio); rcti.bottom = int(rcti.bottom * ratio); } xvt_rect_offset(&rcti, rctw.right - rcti.right, rctw.bottom - rcti.bottom); _logo.draw(win(), rcti); } const PNT pnt = { 0, 0 }; draw_spider(win(), 0x3, pnt); } } } short TBook_window::pages() const { return _ctrl == NULL_WIN ? 0 : xvt_notebk_get_num_tabs(_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) { xvt_notebk_set_front_page(_ctrl, page); WINDOW w = xvt_notebk_get_page(_ctrl, page); xvt_win_enum_wins(w, hell_riser, 0, 0); } void 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.win == _ctrl) { force_page(ep->v.ctl.ci.v.notebk.tab_no); return; } break; default: break; } TControl_host_window::handler(win, ep); } WINDOW TBook_window::page_win(short pg) { WINDOW win = NULL_WIN; if (_ctrl != NULL_WIN) win = xvt_notebk_get_page(_ctrl, pg); return win; } short TBook_window::add_page(const TString& caption) { if (_ctrl == NULL_WIN) { WIN_DEF wd; memset(&wd, 0, sizeof(wd)); wd.wtype = WC_NOTEBK; wd.v.ctl.ctrl_id = DLG_MAIN; wd.v.ctl.flags = CTL_FLAG_CENTER_JUST; // i.e. bottom! xvt_vobj_get_client_rect(win(), &wd.rct); _ctrl = xvt_ctl_create_def(&wd, win(), 0L); xvt_pane_set_size_range(win(), 0, 0); // Blocca le dimensioni del pannello (Non va!) } TString256 cap; for (short pg = pages()-1; pg >= 0; pg--) { xvt_notebk_get_tab_title(_ctrl, pg, cap.get_buffer(), cap.size()); if (cap.compare(caption, -1, true) == 0) { force_page(pg); return -1; // Don't perform menu! } } TApp_window* w = new TApp_window(this); const short pg = xvt_notebk_add_page(_ctrl, w->win(), 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) { 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; } } 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("logo.gif") { set_scroll_max(0, 0); // Get rid of that useless scrollbars if (_logo.ok() && can_be_transparent(_logo)) _logo.convert_transparent_color(NORMAL_BACK_COLOR); } 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 add_page(const TString& caption); void set_page_caption(short page, const TString& caption, int icon); WINDOW page_win(short page); void remove_all_pages(); TBook_field(TMask* m) : TWindowed_field(m) {} }; short TBook_field::add_page(const TString& caption) { TBook_window& bw = (TBook_window&)win(); return bw.add_page(caption); } 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); } 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); } 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 /////////////////////////////////////////////////////////// short TOutlook_mask::add_page(const TString& caption) { TBook_field& bf = (TBook_field&)field(DLG_MAIN); return bf.add_page(caption); } void TOutlook_mask::set_page_caption(short page, const TString& caption, int icon) { TBook_field& bf = (TBook_field&)field(DLG_MAIN); bf.set_page_caption(page, caption, icon); } 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 = (TBook_field&)field(DLG_MAIN); // ba1 e ba2 sono programmi di manutenzione da eseguire in modo esclusivo if (mi.run_modal()) { bf.remove_all_pages(); // Chiude tutti i programmi in corso 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.caption()); if (pg >= 0) { 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 < 16) ico = _icon[area]; else ico = ICON_RSRC; } set_page_caption(pg, mi.caption(), ico); } } } } } break; case DLG_LOOK: if (e == fe_modify) { TToken_string id("MENU_000", '/'); _tree.change_root(id); // Torna alla radice standard const int sel = atoi(o.get()); for (int i = 0; i < sel; i++) _tree.goto_rbrother(); // Seglie l'opportuno ramo principale _tree.goto_firstson(); _tree.curr_id(id); _tree.change_root(id.get(1)); // Imposta una nuova radice synchronize_tree_field(tfield(DLG_TREE)); } break; default: break; } return true; } TOutlook_mask::TOutlook_mask(TMenu& menu) : _tree(menu) { 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); TString caption; int i = 0; for (bool ok = _tree.goto_root(); ok; ok = _tree.goto_rbrother()) { _tree.get_description(caption); const TMenuitem& mi = _tree.curr_item(); const int ico = mi.enabled() ? mi.icon() : 10203; of->add_item(ico, caption, 0); _icon[i++] = ico; // Memorizza icona per orecchie } const int minimain = 800; xvt_pane_add(panel, dlg2win(DLG_TREE), "Menu", 1, 0); // Left upper pane xvt_pane_add(panel, dlg2win(DLG_LOOK), "Bar", 1, 0); // Left lower pane xvt_pane_add(panel, dlg2win(DLG_MAIN), "Main", 0, 0); // Main pane set_handlers(); } TOutlook_mask::~TOutlook_mask() { // Ricostruisci status bar tornata utile xvtil_create_statbar(); }