git-svn-id: svn://10.65.10.50/branches/R_10_00@22878 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1335 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1335 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <config.h>
 | ||
| #include <controls.h>
 | ||
| #include <diction.h>
 | ||
| #include <prefix.h>
 | ||
| #include <toolfld.h>
 | ||
| #include <urldefid.h>
 | ||
| #include <utility.h>
 | ||
| #include <xvtility.h>
 | ||
| 
 | ||
| #include "ba0102.h"
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TMenu_tree
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| const TSubmenu& TMenu_tree::curr_submenu() const
 | ||
| {
 | ||
|   CHECKS(_submenu, "NULL submenu ", (const char*)_curr_id);
 | ||
|   return *_submenu;
 | ||
| }
 | ||
| 
 | ||
| const TMenuitem& TMenu_tree::curr_item() const
 | ||
| {
 | ||
|   const TSubmenu& sm = curr_submenu();
 | ||
|   if (_menuitem < 0 || _menuitem >= sm.items())
 | ||
|   {
 | ||
|     NFCHECK("Invalid submenu item %d in %s", _menuitem, (const char*)sm.name());
 | ||
|     return sm.item(0);
 | ||
|   }  
 | ||
|   return sm.item(_menuitem);
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::enabled() const
 | ||
| {
 | ||
|   return curr_item().enabled();
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::marked() const 
 | ||
| { 
 | ||
|   bool yes = false;
 | ||
|   /* Non cambia nulla!
 | ||
|   const TMenuitem& mi = curr_item();
 | ||
|   if (mi.is_program() && mi.enabled())
 | ||
|   {
 | ||
|     TFilename n = mi.action().before(' ');
 | ||
|     n.ext("exe");
 | ||
|     if (n.custom_path())
 | ||
|     {
 | ||
|       n.lower();
 | ||
|       yes = n.find("custom") > 0;
 | ||
|     }
 | ||
|   }
 | ||
|   */
 | ||
|   return yes;
 | ||
| } 
 | ||
| 
 | ||
| 
 | ||
| struct TFind_node_data
 | ||
| {
 | ||
|   TString _id;
 | ||
|   size_t _count;
 | ||
| };
 | ||
| 
 | ||
| struct TFind_string_data
 | ||
| {
 | ||
|   TString256 _str, _best;
 | ||
|   TAssoc_array* _ignore_list;
 | ||
|   double _score;
 | ||
| };
 | ||
| 
 | ||
| HIDDEN bool find_string_callback(TTree& tree, void* jolly, word flags)
 | ||
| {
 | ||
|   if (flags == SCAN_PRE_ORDER)
 | ||
|   {
 | ||
|     const TMenu_tree& mt = (const TMenu_tree&)tree;
 | ||
|     const TSubmenu& sm = mt.curr_submenu();
 | ||
| 
 | ||
|     if (sm.disabled())
 | ||
|       return false;
 | ||
| 
 | ||
|     TFind_string_data& data = *(TFind_string_data*)jolly;
 | ||
|     if (data._ignore_list->is_key(sm.name()))
 | ||
|       return false;
 | ||
|     
 | ||
|     TString desc; mt.get_description(desc);
 | ||
|     desc.upper();
 | ||
|     if (desc.find(data._str) >= 0 || desc.match(data._str))
 | ||
|     {
 | ||
|       data._score = 1.0;
 | ||
|       mt.curr_id(data._best);
 | ||
|       return true;
 | ||
|     }
 | ||
| 
 | ||
|     const double s = xvt_str_fuzzy_compare(desc, data._str);
 | ||
|     if (s > data._score)
 | ||
|     {
 | ||
|       data._score = s;
 | ||
|       mt.curr_id(data._best);
 | ||
|     }
 | ||
|   }
 | ||
|   return false;
 | ||
| }
 | ||
| 
 | ||
| HIDDEN bool find_node_callback(TTree& tree, void* jolly, word flags)
 | ||
| {
 | ||
|   if (flags == SCAN_PRE_ORDER)
 | ||
|   {
 | ||
|     TFind_node_data& data = *(TFind_node_data*)jolly;
 | ||
|     data._count++;
 | ||
|     TString id; tree.curr_id(id);
 | ||
|     if (id == data._id)
 | ||
|       return TRUE;
 | ||
|   }
 | ||
|   return FALSE;
 | ||
| }
 | ||
| 
 | ||
| HIDDEN bool find_leaf_callback(TTree& tree, void* jolly, word flags)
 | ||
| {
 | ||
|   if (flags == SCAN_PRE_ORDER)
 | ||
|   {
 | ||
|     const TString& leaf = *(TString*)jolly;
 | ||
|     TString id; tree.curr_id(id);
 | ||
|     const int slash = id.rfind('/');
 | ||
|     if (slash > 0)
 | ||
|       id = id.mid(slash+1);
 | ||
|     if (id == leaf)
 | ||
|       return true;
 | ||
|   }
 | ||
|   return false;
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::find_string(const TString& str)
 | ||
| {
 | ||
|   TFind_string_data data;
 | ||
|   data._str = str; data._str.upper();
 | ||
| 	data._ignore_list = &_menu->search_ignore_list();
 | ||
|   data._score = 0;
 | ||
| 
 | ||
|   if (data._str != _menu->last_search_string())
 | ||
| 	{
 | ||
| 		_menu->last_search_string() = data._str;
 | ||
| 		_menu->search_ignore_list().destroy();
 | ||
| 	}
 | ||
| 
 | ||
|   goto_root();
 | ||
|   bool ok = scan_depth_first(find_string_callback, &data, SCAN_PRE_ORDER);
 | ||
| 
 | ||
|   if (!ok && data._score > 0.9)
 | ||
|     ok = goto_node(data._best);
 | ||
| 
 | ||
|   if (ok)
 | ||
|     _menu->search_ignore_list().add(curr_submenu().name());
 | ||
|   else
 | ||
|     _menu->search_ignore_list().destroy();
 | ||
| 
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::find_leaf(const TString& str)
 | ||
| {
 | ||
|   goto_root();
 | ||
|   bool ok = scan_depth_first(find_leaf_callback, (void *)&str, SCAN_PRE_ORDER);
 | ||
|   return ok;                           
 | ||
| }
 | ||
| 
 | ||
| void TMenu_tree::node2id(const TObject* node, TString& id) const
 | ||
| {
 | ||
|   TString* str = (TString*)node;
 | ||
|   id = *str;
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::goto_root()
 | ||
| {
 | ||
|   TSubmenu* sm = _menu->find(_root_id);
 | ||
|   if (sm)
 | ||
|   {
 | ||
|     _curr_id = _root_id;
 | ||
|     _curr_id << ".0";
 | ||
|     _submenu = sm;
 | ||
|     _menuitem = 0;
 | ||
|   }
 | ||
|   return sm != NULL;
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::goto_firstson()
 | ||
| {
 | ||
|   const TMenuitem& mi = curr_item();
 | ||
|   const TSubmenu* sm = mi.child_submenu();
 | ||
|   if (sm != NULL)
 | ||
|   {
 | ||
|     _curr_id << '/' << mi.action() << ".0";
 | ||
|     _submenu = sm;
 | ||
|     _menuitem = 0;
 | ||
|     return true;
 | ||
|   }
 | ||
|   return false;
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::goto_rbrother()
 | ||
| {
 | ||
|   if (_menuitem < _submenu->items()-1)
 | ||
|   {
 | ||
|     const int dot = _curr_id.rfind('.');
 | ||
|     _curr_id.cut(dot+1);
 | ||
|     _curr_id << (++_menuitem);
 | ||
|     return true;
 | ||
|   }
 | ||
|   return false;
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::goto_node(const TString &id)
 | ||
| {
 | ||
|   if (_curr_id != id)
 | ||
|   {
 | ||
|     const int dot = id.rfind('.');
 | ||
|     CHECKS(dot > 0, "Invalid tree node ", (const char*)id);
 | ||
|     _menuitem = atoi(id.mid(dot+1));
 | ||
|     _curr_id = id.left(dot);
 | ||
|     const int slash = _curr_id.rfind('/');
 | ||
|     
 | ||
|     _curr_id = _curr_id.mid(slash+1);
 | ||
|     _submenu = _menu->find(_curr_id);
 | ||
|     _curr_id = id;
 | ||
|   }
 | ||
|   return _submenu != NULL;
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::has_son() const
 | ||
| {
 | ||
|   const TMenuitem& mi = curr_item();
 | ||
|   return mi.is_submenu();
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::has_rbrother() const
 | ||
| {
 | ||
|   return _menuitem < _submenu->items()-1;
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::has_root() const
 | ||
| {
 | ||
|   return _root_id.not_empty();
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::has_father() const
 | ||
| {
 | ||
|   return _curr_id.find('/') > 0;
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::has_lbrother() const
 | ||
| {
 | ||
|   return _menuitem > 0;
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::goto_father()
 | ||
| {
 | ||
|   const int slash = _curr_id.rfind('/');
 | ||
|   if (slash > 0)
 | ||
|   {
 | ||
|     const TString id = _curr_id.left(slash);
 | ||
|     return goto_node(id);
 | ||
|   }
 | ||
|   return false;
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::goto_lbrother()
 | ||
| {
 | ||
|   if (_menuitem > 0)
 | ||
|   {
 | ||
|     const int dot = _curr_id.rfind('.');
 | ||
|     _curr_id.cut(dot+1);
 | ||
|     _curr_id << (--_menuitem);
 | ||
|     return true;
 | ||
|   }
 | ||
|   return false;
 | ||
| }
 | ||
| 
 | ||
| TObject* TMenu_tree::curr_node() const
 | ||
| {
 | ||
|   return &((TMenu_tree*)this)->_curr_id;
 | ||
| }
 | ||
| 
 | ||
| bool TMenu_tree::get_description(TString& desc) const
 | ||
| {
 | ||
|   const TMenuitem& mi = curr_item();
 | ||
|   desc = mi.caption();
 | ||
|   return desc.full();
 | ||
| }
 | ||
| 
 | ||
| TImage* TMenu_tree::image(bool selected) const
 | ||
| {
 | ||
|   const TMenuitem& mi = curr_item();
 | ||
|   if (mi.disabled())
 | ||
|     return get_res_icon(10203);    // Icona di stop
 | ||
| 
 | ||
|   int ico = mi.icon();             // Eventuale icona di programma o cartella 
 | ||
|   if (ico <= 0 && mi.is_program()) // Forza icona per i programmi
 | ||
|     ico = ICON_RSRC;  
 | ||
| 
 | ||
|   TImage* img = ico > 0 ? get_res_icon(ico) : NULL;
 | ||
|   return img ? img : TTree::image(selected);
 | ||
| }
 | ||
| 
 | ||
| long TMenu_tree::find_node(const TString& id)
 | ||
| {
 | ||
|   TFind_node_data data;
 | ||
|   data._id = id; 
 | ||
|   data._count = 0;
 | ||
|   goto_root();
 | ||
|   scan_depth_first(find_node_callback, &data, 
 | ||
|                    SCAN_PRE_ORDER | SCAN_IGNORING_UNEXPANDED);
 | ||
| 	return data._count;
 | ||
| }
 | ||
| 
 | ||
| void TMenu_tree::change_root(const char* rid)
 | ||
| {
 | ||
|   _root_id = rid;
 | ||
|   const int dot = _root_id.find('.');
 | ||
|   if (dot > 0)
 | ||
|     _root_id.cut(dot);
 | ||
|   goto_root();
 | ||
| }
 | ||
| 
 | ||
| void TMenu_tree::set_menu(TMenu& menu)
 | ||
| {
 | ||
|   _menu = &menu;
 | ||
|   _curr_id.cut(0);
 | ||
|   change_root("MENU_000");
 | ||
| }
 | ||
| 
 | ||
| TMenu_tree::TMenu_tree(TMenu& menu) : _menu(NULL), _curr_id(128, '/')
 | ||
| {
 | ||
|   set_menu(menu);
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Utility
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| //flag per impedire un doppio aggiornamento causato adall'autofocus del primo elemento dell'albero
 | ||
| //senza questo flag entra automaticamente nella prima voce di menu, un livello sotto a quello..
 | ||
| //..richiesto dall'utente
 | ||
| static bool _sincronaising = false;
 | ||
| 
 | ||
| // Sincronizza l'albero in basa alla list view
 | ||
| void synchronize_tree_field(TTree_field& tf)
 | ||
| {
 | ||
|   _sincronaising = true;
 | ||
| 
 | ||
|   TTree& mt = *tf.tree();
 | ||
|   TString id; mt.curr_id(id); // Memorizza nodo corrente
 | ||
| 	mt.shrink_all();            // Collassa tutto l'albero
 | ||
|   // Espande il nodo corrente all'indietro fino alla radice
 | ||
| 	mt.goto_node(id); 
 | ||
|   do mt.expand(); while (mt.goto_father());
 | ||
| 	mt.goto_node(id);           // Torna al nodo corrente
 | ||
| 
 | ||
|   tf.win().force_update();    // Provoca la rigenerazione dell'albero espanso come sopra
 | ||
| 
 | ||
|   tf.on_key(K_SPACE);
 | ||
| 
 | ||
|   _sincronaising = false;
 | ||
| }
 | ||
| 
 | ||
| bool can_be_transparent(const TImage& i)
 | ||
| {
 | ||
|   if (xvt_image_get_format(i) == XVT_IMAGE_RGB)
 | ||
|     return false;
 | ||
| 	const int w = i.width()-1;
 | ||
| 	const int h = i.height()-1;
 | ||
| 	const COLOR col = i.get_pixel(0,0);
 | ||
| 	if (i.get_pixel(w,0) != col)
 | ||
| 		return false;
 | ||
| 	if (i.get_pixel(w,h) != col)
 | ||
| 		return false;
 | ||
| 	if (i.get_pixel(0,h) != col)
 | ||
| 		return false;
 | ||
| 	return true;
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TMenulist_images
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| class TMenulist_images : public TCache
 | ||
| {
 | ||
|   WINDOW _win;
 | ||
|   int _max_side;
 | ||
| 
 | ||
| protected:
 | ||
| 	TObject* key2obj(const char* key);
 | ||
| 
 | ||
| public:
 | ||
| 	void set_owner_info(WINDOW win, int max_side);
 | ||
| 	TImage* image(const char* filename);
 | ||
| 	TMenulist_images() : TCache(17), _win(NULL_WIN), _max_side(0) { }
 | ||
| };
 | ||
| 
 | ||
| int fast_hypot(int x, int y)
 | ||
| {
 | ||
|   // loop unrolled
 | ||
|   #define TEST(s, h, i) { const int k = h+i; if (k*k <= s) h = k; }
 | ||
| 	const int s = x*x + y*y;
 | ||
| 	int h = 0;
 | ||
|   TEST(s, h, 512); TEST(s, h, 256); TEST(s, h, 128);
 | ||
|   TEST(s, h, 64); TEST(s, h, 32); TEST(s, h, 16);
 | ||
|   TEST(s, h, 8); TEST(s, h, 4); TEST(s, h, 2); TEST(s, h, 1);
 | ||
| 	return h;
 | ||
| }
 | ||
| 
 | ||
| void TMenulist_images::set_owner_info(WINDOW win, int max_side) 
 | ||
| { 
 | ||
|   if (max_side != _max_side)
 | ||
|     destroy();
 | ||
| 
 | ||
|   _win = win; 
 | ||
|   _max_side = max_side;
 | ||
| }
 | ||
| 
 | ||
| TObject* TMenulist_images::key2obj(const char* key)
 | ||
| {
 | ||
|   TImage*	img = NULL;
 | ||
| 
 | ||
|   TFilename name;
 | ||
|   const char* ext[] = { "jpg", "gif", "bmp", "png", NULL };
 | ||
|   for (int i = 0; ext[i] != NULL; i++)
 | ||
|   {
 | ||
|     name = key;
 | ||
|     name.ext(ext[i]);
 | ||
|     if (name.custom_path())
 | ||
|       break;
 | ||
|   }
 | ||
| 
 | ||
|   if (name.exist())
 | ||
| 	{
 | ||
| 		TWait_cursor hourglass;
 | ||
| 		TImage image(name);
 | ||
| 		if (can_be_transparent(image))
 | ||
| 			image.convert_transparent_color(NORMAL_BACK_COLOR);
 | ||
| 
 | ||
| 	  RCT rct; xvt_vobj_get_client_rect(_win, &rct);
 | ||
|     const double max_img = (double)_max_side;
 | ||
|     const double max_lgo = rct.right - _max_side;
 | ||
| 
 | ||
|     if (xvt_str_compare_ignoring_case(key, get_logo()) != 0)
 | ||
|     {
 | ||
| 		  const double ratiox = max_img / image.width();
 | ||
| 		  const double ratioy = max_img / image.height();
 | ||
| 		  const double ratio = min(ratiox, ratioy);
 | ||
| 		  const int maxx = int(ratio * image.width()); 
 | ||
| 		  const int maxy = int(ratio * image.height());
 | ||
| 		  img = new TImage(image, maxx, maxy);
 | ||
| 
 | ||
|      //Sfumatura costante sui lati sx e up
 | ||
|       const double radius = min(maxx,maxy)/6.0;
 | ||
| 		  for (int y = 0; y < maxy; y++)
 | ||
| 		  {
 | ||
| 			  for (int x = 0; x < maxx; x++)
 | ||
| 			  {
 | ||
|           if (x <= radius || y <= radius)
 | ||
|           {
 | ||
|             double perc = 1.0;
 | ||
|             if (x <= radius && y <= radius)
 | ||
|             {
 | ||
|               const int r = fast_hypot(int(radius-x),int(radius-y));
 | ||
|               if (r <= radius)
 | ||
|                 perc = 1.0-r/radius;
 | ||
|               else
 | ||
|                 perc = 0;
 | ||
|             }
 | ||
|             else
 | ||
|               perc = min(x,y)/radius;
 | ||
| 
 | ||
| 				    COLOR col = img->get_pixel(x, y);
 | ||
| 				    COLOR bri = blend_colors(col, NORMAL_BACK_COLOR, perc);
 | ||
| 				    img->set_pixel(x, y, bri);
 | ||
|           }
 | ||
|         }
 | ||
| 		  }
 | ||
|     }
 | ||
|     else    //caso particolare del logo
 | ||
|     {
 | ||
| 		  const double ratio = max_lgo / image.width();
 | ||
| 		  const int maxx = int(ratio * image.width()); 
 | ||
| 		  const int maxy = int(ratio * image.height());
 | ||
| 		  img = new TImage(image, maxx, maxy);
 | ||
|     }
 | ||
| 	}
 | ||
| 	return img;
 | ||
| }
 | ||
| 
 | ||
| TImage* TMenulist_images::image(const char* name)
 | ||
| {
 | ||
| 	TObject* obj = objptr(name);
 | ||
|   if (obj == NULL && 
 | ||
|       xvt_str_compare_ignoring_case(name, "ba00") != 0 &&
 | ||
|       xvt_str_compare_ignoring_case(name, get_logo()) != 0)
 | ||
|     obj = objptr("ba00");
 | ||
| 	return (TImage*)obj;
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TMenulist_field
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| class TMenulist_window : public TField_window
 | ||
| {
 | ||
| private:
 | ||
|   TMenu_tree* _tree;
 | ||
| 	size_t MENU_COLS, MENU_ROWS;
 | ||
| 
 | ||
| 	TString _curr_node;
 | ||
| 	bool _can_go_back;
 | ||
| 
 | ||
| 	TMenulist_images _images;
 | ||
| 	TString _image_name;
 | ||
| 
 | ||
| 	int _selected;
 | ||
| 	TPointer_array _sorted;
 | ||
| 
 | ||
|   clock_t _last_update;
 | ||
| 
 | ||
| protected:
 | ||
| 	virtual void update();
 | ||
| 	virtual long handler(WINDOW win, EVENT* ep);
 | ||
|   virtual bool on_key(KEY k);
 | ||
| 
 | ||
| 	void synchronize_buddy_tree() const;
 | ||
|   void draw_item(int i);
 | ||
|   void draw_menu_caption();
 | ||
|   void click_on(int index);
 | ||
|   void select(int s, int direction);
 | ||
| 
 | ||
| public:
 | ||
|   void curr_item(TToken_string& id) const;
 | ||
| 	void set_menu(TMenu_tree& mt);
 | ||
| 
 | ||
|   TMenulist_window(int x, int y, int dx, int dy, WINDOW parent, TMenulist_field* owner);
 | ||
|   virtual ~TMenulist_window();
 | ||
| };
 | ||
| 
 | ||
| void TMenulist_window::draw_item(int i)
 | ||
| {
 | ||
| 	if (i < 0 && i >= _sorted.items())
 | ||
| 		return;  // Scarta elementi non validi
 | ||
|   WINDOW w = win();
 | ||
| 	RCT rct; xvt_vobj_get_client_rect(w, &rct);
 | ||
| 	const int width = rct.right - rct.left;
 | ||
| 	const int height = rct.bottom - rct.top;
 | ||
| 	
 | ||
| 	xvtil_set_font(w, NULL, 0, 0); // Set default font
 | ||
| 	set_opaque_text(TRUE);
 | ||
| 
 | ||
|   const TMenuitem& item = (const TMenuitem&)_sorted[i];
 | ||
| 	if (item.enabled())
 | ||
|   {
 | ||
|     if (i == _selected) //testo nero su sfondo con colore del focus se la voce e' selezionata
 | ||
|   	  set_color(FOCUS_COLOR, FOCUS_BACK_COLOR);   
 | ||
|     else                //testo nero su sfondo trasparente x voci non selezionate
 | ||
|       set_color(NORMAL_COLOR, NORMAL_BACK_COLOR); 
 | ||
|   }
 | ||
| 	else                  //testo grigio su sfondo trasparente x voci non selezionate
 | ||
|     set_color(DISABLED_COLOR, DISABLED_BACK_COLOR); 
 | ||
| 
 | ||
| 	const int row = i / MENU_COLS;
 | ||
| 	const int col = i % MENU_COLS;
 | ||
| 	const int left = col * width / MENU_COLS;
 | ||
| 	const int right = (col+1) * width / MENU_COLS;
 | ||
| 	const int top = row * height / MENU_ROWS;
 | ||
| //	const int bottom = (row+1) * height / MENU_ROWS;
 | ||
| 	
 | ||
| 	const int cx = (left+right)/2;
 | ||
| //	const int cy = (top+bottom)/2; verificare
 | ||
| 
 | ||
| 	const int ico = item.enabled() ? item.icon() : 0;
 | ||
| 	const int ix = cx-16;
 | ||
| 	const int iy = top+2;
 | ||
|   if (item.is_submenu())
 | ||
| 	{
 | ||
|  		xvt_dwin_draw_icon(w, ix, iy, 10202);
 | ||
| 		if (ico > 0)
 | ||
| 			xvt_dwin_draw_icon(w, ix, iy+4, ico);
 | ||
| 	}
 | ||
| 	else
 | ||
| 	{
 | ||
| 		xvt_dwin_draw_icon(w, ix, iy, ico > 0 ? ico : ICON_RSRC);
 | ||
|   }
 | ||
| 
 | ||
|   TString80 str = item.caption();
 | ||
|   if (i == 0 && _can_go_back)
 | ||
| 		str = "(..)";
 | ||
| 
 | ||
| 	// const int maxchars = (right-left)/CHARX - 1;
 | ||
|   int maxchars = 24;
 | ||
|   const int ll = xvt_dwin_get_text_width(w, str, -1);
 | ||
|   if (ll >= (right-left))
 | ||
|     maxchars = (right-left) * str.len() / ll - 1;
 | ||
| 
 | ||
| 	TParagraph_string para(str, maxchars);
 | ||
| 	int y = iy + 32 + CHARY-1;
 | ||
| 	FOR_EACH_TOKEN(para, line)
 | ||
| 	{
 | ||
| 		const int ll = xvt_dwin_get_text_width(w, line, -1);
 | ||
| 		const int x = cx - ll/2;
 | ||
| 		xvt_dwin_draw_text(w, x, y, line, -1);
 | ||
| 		y += CHARY-2;
 | ||
| 	}
 | ||
| 	if (item.disabled())
 | ||
|   {
 | ||
|     RCT rct; xvt_rect_set(&rct, ix+16, iy+16, ix+32, iy+32);
 | ||
| 		xvt_dwin_draw_icon_rect(w, &rct, 10203); // Stop icon
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| //scrive la voce di menu corrente a video
 | ||
| void TMenulist_window::draw_menu_caption()
 | ||
| {
 | ||
|   const char* caption = "";
 | ||
|   if (_sorted.items() > 1)
 | ||
|   {
 | ||
|     const TMenuitem& mi = (const TMenuitem&)_sorted[1];
 | ||
|     const TSubmenu& sm = mi.submenu();
 | ||
|     caption = sm.caption();
 | ||
|   }
 | ||
|   else
 | ||
|   {
 | ||
|     const TMenuitem& mi = (const TMenuitem&)_sorted[0];
 | ||
|     caption = mi.caption();
 | ||
|   }
 | ||
|   xvt_pane_set_title(win(), caption);
 | ||
|   xvtil_statbar_set(caption);
 | ||
| }
 | ||
| 
 | ||
| void TMenulist_window::update()
 | ||
| { 
 | ||
|   TField_window::update();
 | ||
|   if (_tree == NULL)
 | ||
| 		return; // Nothing to draw
 | ||
| 
 | ||
|   const bool db = ADVANCED_GRAPHICS;
 | ||
|   TImage* img = db ? _images.image(_image_name) : NULL; // 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
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| #define DLG_TREE 301
 | ||
| #define DLG_LIST 302
 | ||
| #define DLG_LOOK 303
 | ||
| 
 | ||
| void draw_spider(WINDOW w, int mode, const PNT& mouse)
 | ||
| {
 | ||
|   static bool _spider = ADVANCED_GRAPHICS && is_power_reseller(true); // 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)
 | ||
|   {
 | ||
|     const TMask_field& f = fld(pos);
 | ||
|     if (f.is_kind_of(CLASS_WINDOWED_FIELD))
 | ||
|       w = ((const TWindowed_field&)f).win().win();
 | ||
|   }
 | ||
|   return w;
 | ||
| }
 | ||
| 
 | ||
| bool TSpidey_mask::stop_run(KEY k)
 | ||
| {
 | ||
|   if (k == K_CTRL+'R')
 | ||
|     return TWindow::stop_run(k);
 | ||
| 
 | ||
|   if (k == K_QUIT)
 | ||
|   {
 | ||
|     if (ADVANCED_GRAPHICS)
 | ||
|     {
 | ||
|       const int divider = 8;
 | ||
|       const WINDOW window[4] = { win(), dlg2win(101), dlg2win(102), dlg2win(103) };
 | ||
|       XVT_IMAGE image[4]; memset(image, 0, sizeof(image));
 | ||
|       int i;
 | ||
|       for (i = 0; i < 4; i++)
 | ||
|       {
 | ||
|         const WINDOW& w = window[i];
 | ||
|         if (w != NULL_WIN)
 | ||
|         {
 | ||
|           RCT rct; xvt_vobj_get_client_rect(w, &rct);
 | ||
|           RCT irct = rct; irct.right /= divider; irct.bottom /= divider;
 | ||
|           XVT_IMAGE cap = xvt_image_capture(w, &rct);
 | ||
|           XVT_IMAGE img = xvt_image_create(XVT_IMAGE_RGB, irct.right, irct.bottom, 0);
 | ||
|           xvt_image_transfer(img, cap, &irct, &rct);
 | ||
|           xvt_image_destroy(cap);
 | ||
| 
 | ||
|           for (int y = 0; y < irct.bottom; y++)
 | ||
|           {
 | ||
|             for (int x = 0; x < irct.right; x++)
 | ||
|             {
 | ||
|               COLOR rgb = xvt_image_get_pixel(img, x, y);
 | ||
|               const unsigned int r = XVT_COLOR_GET_RED(rgb)   / 2;
 | ||
|               const unsigned int g = XVT_COLOR_GET_GREEN(rgb) / 2;
 | ||
|               const unsigned int b = XVT_COLOR_GET_BLUE(rgb)  / 2;
 | ||
|               xvt_image_set_pixel(img, x, y, XVT_MAKE_COLOR(r, g, b));
 | ||
|             }
 | ||
|           }
 | ||
|           image[i] = img;
 | ||
|         }
 | ||
|       }
 | ||
|       for (i = 3; i >= 0; i--) if (image[i] != NULL)
 | ||
|       {
 | ||
|         const WINDOW& w = window[i];
 | ||
|         if (w != NULL_WIN)
 | ||
|         {
 | ||
|           RCT rct; xvt_vobj_get_client_rect(w, &rct);
 | ||
|           RCT irct = rct; irct.right /= divider; irct.bottom /= divider;
 | ||
|           xvt_dwin_draw_image(w, image[i], &rct, &irct);
 | ||
|         }
 | ||
|       }
 | ||
|       // Butto via le immagini dopo averle disegnate tutte
 | ||
|       for (i = 3; i >= 0; i--)
 | ||
|         xvt_image_destroy(image[i]);
 | ||
| 
 | ||
|       if (installing())  //se e' stata lanciata la installazione moduli...
 | ||
| 			{
 | ||
|         xvt_sys_sleep(1); //..aspetta un attimo poi forza l'uscita
 | ||
| 			}
 | ||
|       else
 | ||
|       {
 | ||
|         if (!yesno_box(TR("Si desidera uscire?")))  //..altrimenti chiede educatamente se si desidera uscire
 | ||
|         {
 | ||
|           for (i = 0; i < 3; i++)
 | ||
|           {
 | ||
|             if (window[i] != NULL)
 | ||
|               xvt_dwin_invalidate_rect(window[i], NULL);
 | ||
|           }
 | ||
|           return false;
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   return TMask::stop_run(k);
 | ||
| }
 | ||
| 
 | ||
| bool TSpidey_mask::on_key(KEY k)
 | ||
| {
 | ||
|   if (k == K_FORCE_CLOSE || k == K_QUIT)
 | ||
|     return stop_run(k);
 | ||
| 
 | ||
| 	return TMask::on_key(k);
 | ||
| }
 | ||
| 
 | ||
| TSpidey_mask::TSpidey_mask() : TAutomask ("Menu", 1, 0, 0, 0, 0)
 | ||
| { }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TExplorer_mask
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| void TExplorer_mask::update()
 | ||
| {
 | ||
|   TMask::update();
 | ||
| 
 | ||
|   if (ADVANCED_GRAPHICS)
 | ||
|   {
 | ||
|     WINDOW w = toolwin();
 | ||
| 	  RCT client; xvt_vobj_get_client_rect(w, &client);
 | ||
|     const TString& ragsoc = prefix().firm().ragione_sociale();
 | ||
| 	  const int len = xvt_dwin_get_text_width(w, ragsoc, -1);
 | ||
|     xvt_dwin_draw_text(w, (client.right-len)/2, client.bottom-2, ragsoc, -1);
 | ||
| 
 | ||
|     const PNT pnt = { 0, 0 };
 | ||
|     draw_spider(w, 0x3, pnt);
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| long TExplorer_mask::handler(WINDOW win, EVENT* ep)
 | ||
| {
 | ||
|   if (ep->type == E_MOUSE_MOVE)
 | ||
|     draw_spider(toolwin(), 0x3, ep->v.mouse.where);
 | ||
|   return TSpidey_mask::handler(win, ep);
 | ||
| }
 | ||
| 
 | ||
| void TExplorer_mask::select_tree_current()
 | ||
| {
 | ||
|   TTree_field& tf = tfield(DLG_TREE);
 | ||
| 	TMenulist_field& mf = (TMenulist_field&)field(DLG_LIST);
 | ||
|   TMenu_tree& mt = (TMenu_tree&)*tf.tree();
 | ||
|   mf.set_menu(mt);
 | ||
| 	synchronize_tree_field(tf);
 | ||
| 	mf.set_focus();
 | ||
| }
 | ||
| 
 | ||
| bool TExplorer_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | ||
| {
 | ||
|   switch(o.dlg())
 | ||
|   {
 | ||
|   case DLG_TREE:
 | ||
|     if (e == fe_modify)
 | ||
|     {
 | ||
|       TTree_field& tf = (TTree_field&)o;
 | ||
|       TMenu_tree& mt = *(TMenu_tree*)tf.tree();
 | ||
|       if (!_sincronaising)
 | ||
|       {
 | ||
|         const TMenuitem& mi = mt.curr_item();
 | ||
| 		    if (mi.perform() && mt.goto_firstson())
 | ||
| 		    {
 | ||
| 			    TMenulist_field& mf = (TMenulist_field&)field(DLG_LIST);
 | ||
| 	        mf.set_menu(mt);
 | ||
| 		    }
 | ||
|       }
 | ||
|       else
 | ||
|       {
 | ||
|   	    TMenulist_field& mf = (TMenulist_field&)field(DLG_LIST);
 | ||
|         mf.set_menu(mt);
 | ||
|       }
 | ||
|     }
 | ||
|     break;
 | ||
|   case DLG_SHRINK:
 | ||
|     if (e == fe_button)
 | ||
|     {
 | ||
|       TTree_field& tf = tfield(DLG_TREE);
 | ||
|       TTree& mt = *tf.tree();
 | ||
|       mt.shrink_all();
 | ||
|       mt.goto_root();
 | ||
|       select_tree_current();
 | ||
|     }
 | ||
|     break;
 | ||
|   case DLG_FINDREC:
 | ||
|     if (e == fe_button)
 | ||
|     {
 | ||
|       TString80 str = _last_search_string;
 | ||
|       const char* s = xvt_dm_post_string_prompt(TR("Testo"), str.get_buffer(), str.size());
 | ||
|       if (s && *s)
 | ||
|       {
 | ||
|         _last_search_string = s;
 | ||
|         send_key(K_F3, 0);
 | ||
|       }
 | ||
|     }     
 | ||
|     break;
 | ||
|   case DLG_CONFIG:
 | ||
|     dispatch_e_menu(TASK_WIN, MENU_ITEM_ID(2));
 | ||
|     break;
 | ||
|   case DLG_ADDPREF:
 | ||
|     dispatch_e_menu(TASK_WIN, MENU_ITEM_ID(5));
 | ||
|     break;
 | ||
|   case DLG_PREF:
 | ||
|     dispatch_e_menu(TASK_WIN, MENU_ITEM_ID(6));
 | ||
|     break;
 | ||
|   case DLG_USER:
 | ||
|     dispatch_e_menu(TASK_WIN, MENU_ITEM_ID(7));
 | ||
|     break;
 | ||
|   default:
 | ||
|     break;
 | ||
|   }
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| bool TExplorer_mask::on_key(KEY k)
 | ||
| {
 | ||
|   if (k == K_F3 || k == K_F8)
 | ||
| 	{
 | ||
|     TTree_field& tf = tfield(DLG_TREE);
 | ||
|     TMenu_tree& mt = *(TMenu_tree*)tf.tree();
 | ||
|     if (_last_search_string.full() && mt.find_string(_last_search_string))
 | ||
|       select_tree_current();
 | ||
|     else
 | ||
|       beep();
 | ||
| 		return true;
 | ||
| 	}
 | ||
| 	return TSpidey_mask::on_key(k);
 | ||
| }
 | ||
| 
 | ||
| TExplorer_mask::TExplorer_mask(TMenu& menu) : _tree(menu)
 | ||
| {
 | ||
|   add_button_tool(DLG_SHRINK,   TR("Menu Iniziale"), TOOL_FIRSTREC);  
 | ||
|   add_button_tool(DLG_FINDREC,  TR("Ricerca"),       TOOL_FINDREC);
 | ||
|   add_button_tool(DLG_NULL, "", 0);
 | ||
|   add_button_tool(DLG_CONFIG,   TR("Opzioni"),       TOOL_CONFIG);
 | ||
|   add_button_tool(DLG_USER,     TR("Utente"),        TOOL_PERMISSIONS);
 | ||
|   add_button_tool(DLG_SETPRINT, TR("Imposta"),       TOOL_SETPRINT);
 | ||
|   add_button_tool(DLG_NULL, "", 0);
 | ||
|   add_button_tool(DLG_PREF,     TR("Preferiti"),     TOOL_PREF);
 | ||
|   add_button_tool(DLG_ADDPREF,  TR("Aggiungi"),      TOOL_ADDPREF);
 | ||
|   add_button_tool(DLG_NULL, "", 0);
 | ||
|   add_button_tool(DLG_INFO,     TR("Info"),          TOOL_INFO);
 | ||
|   add_button_tool(DLG_HELP,     TR("Help"),          TOOL_HELP);
 | ||
|   add_button_tool(DLG_QUIT,     TR(""),              TOOL_QUIT);  
 | ||
| 
 | ||
|   WINDOW panel = page_win(0);
 | ||
| 
 | ||
|   // Tree view
 | ||
|   TTree_field& trifola = add_tree(DLG_TREE, 0, 0, 0, 32, 0);
 | ||
|   trifola.set_tree(&_tree);
 | ||
|   trifola.hide_leaves(true); // Nascondo le foglie che vengono gestite dal TMenulist_field
 | ||
| 
 | ||
|   // List view
 | ||
|   TMenulist_field* mf = new TMenulist_field(this);
 | ||
|   mf->create(DLG_LIST, 48, 0, 0, 0, panel);
 | ||
|   mf->set_menu(*(TMenu_tree*)trifola.tree());
 | ||
|   add_field(mf);
 | ||
| 	
 | ||
|   xvt_pane_add(panel, dlg2win(DLG_LIST), "Main", 0, 0); // Right pane
 | ||
|   xvt_pane_change_flags(dlg2win(DLG_LIST), 1<<10,0);
 | ||
|   xvt_pane_add(panel, dlg2win(DLG_TREE), "Menu", 1, 0); // Left pane
 | ||
|   set_handlers();
 | ||
| }
 | ||
| 
 | ||
| const TString& get_logo()
 | ||
| {
 | ||
|   static TFilename currlogo;
 | ||
| 
 | ||
|   if (currlogo.blank())
 | ||
|   {
 | ||
|     // Controllo se il cliente ha un menulogo,jpg nella cartella custom
 | ||
|     currlogo = "menulogo.jpg";
 | ||
|     if (currlogo.custom_path())
 | ||
|     {
 | ||
|       currlogo.lower();
 | ||
|       if (currlogo.find("custom") < 0)
 | ||
|         currlogo.cut(0);
 | ||
|     }
 | ||
|     else
 | ||
|       currlogo.cut(0);  //deve azzerarlo senn<6E> resta menulogo.jpg
 | ||
| 
 | ||
|     if (currlogo.blank())
 | ||
|     {
 | ||
|       //seleziona il logo da usare in base al producer!!
 | ||
|       currlogo = get_oem_info("Logo");
 | ||
|       currlogo.insert("setup/");
 | ||
|       if (!currlogo.exist())
 | ||
|         currlogo.cut(0);
 | ||
|     }
 | ||
|     
 | ||
|     if (currlogo.blank())
 | ||
|     {
 | ||
|       //se non trova il logo del producer usa il logo standard
 | ||
|       currlogo = "sirio_logo.jpg";
 | ||
|     }
 | ||
|   }
 | ||
|  
 | ||
|   return currlogo;
 | ||
| }
 |