1 #include <string.h>
2 
3 #include "GUI.h"
4 #include "GUI_font.h"
5 #include "GUI_button.h"
6 #include "GUI_menu.h"
7 
8 
9 ////////////////////////////////////////////////////////////////////////////////////////////////////
10 //  so far, only 10 submenus each with 10 items can be used  //
11 //  a dynamical allocation will follow in future //
12 ///////////////////////////////////////////////////////////////////////
13 
14 
15 /* The default callback quits the GUI */
Default_MenuActiveProc(int caller_id,int is_checked,void * unused)16 static GUI_status Default_MenuActiveProc(int caller_id, int is_checked, void *unused)
17 {
18   return(GUI_QUIT);
19 }
20 
21 
GUI_Submenu(GUI_Menu * Aparent,int Asubmenuid,int x,int y,char * Atext,GUI_Font * Afont,int is_checkmenu)22 GUI_Submenu::GUI_Submenu(GUI_Menu *Aparent, int Asubmenuid, int x, int y,
23 			 char *Atext, GUI_Font *Afont, int is_checkmenu)
24   : GUI_Button(NULL,x,y,(strlen(Atext)+is_checkmenu*2)*Afont->CharWidth()+(MENU_OVERSIZE << 1),
25 	       Afont->CharHeight()+MENU_OVERSIZE,Atext,Afont,
26 	       BUTTON_TEXTALIGN_LEFT,is_checkmenu,NULL,1)
27 {
28   submenuid=Asubmenuid;
29   id=-1;
30   numitems=0;
31   strcpy(Text,Atext);
32   parent=Aparent;
33 }
34 
~GUI_Submenu()35 GUI_Submenu::~GUI_Submenu()
36 {
37 // future: free dynamic items array
38 }
39 
AddSubitem(GUI_Menuitem * newitem)40 void GUI_Submenu::AddSubitem(GUI_Menuitem *newitem)
41 {
42   if (numitems<10)
43   {
44     int maxLength=0;
45     int i;
46 
47     for (i=0;i<numitems;i++)
48       if (items[i]->GetLength()>maxLength)
49         maxLength=items[i]->GetLength();
50 
51     items[numitems++]=newitem;
52     if (newitem->GetLength()+newitem->IsCheckButton()*2>maxLength)
53     {
54       for (i=0;i<numitems;i++)
55         items[i]->ChangeTextButton(-1,-1,(newitem->GetLength()+newitem->IsCheckButton()*2)*
56 			 buttonFont->CharWidth()+MENU_OVERSIZE,
57 			 -1,items[i]->GetText(), BUTTON_TEXTALIGN_LEFT);
58     }
59     if (newitem->GetLength()+newitem->IsCheckButton()*2<maxLength)
60     {
61       newitem->ChangeTextButton(-1,-1,maxLength*
62 		 buttonFont->CharWidth()+MENU_OVERSIZE,
63 		 -1,newitem->GetText(), BUTTON_TEXTALIGN_LEFT);
64     }
65     newitem->Hide();
66   }
67 }
68 
GetSubItem(int Aid)69 GUI_Menuitem* GUI_Submenu::GetSubItem(int Aid)
70 {
71   int i=0;
72   while ((i<numitems) && (items[i]->GetId()!=Aid))
73     i++;
74 
75   if (i>=numitems) return NULL;
76   return items[i];
77 }
78 
79 /* Mouse hits activate us */
MouseDown(int x,int y,int button)80 GUI_status GUI_Submenu:: MouseDown(int x, int y, int button)
81 {
82   if (enabled &&(button==1))
83   {
84     parent->SetCommonClickState(submenuid,1,1);
85     pressed[0]=1;
86     Redraw();
87   }
88   return GUI_PASS;
89 }
90 
MouseUp(int x,int y,int button)91 GUI_status GUI_Submenu::MouseUp(int x,int y,int button)
92 {
93   if ((button==1) && (pressed[0]==1))
94   {
95     parent->SetCommonClickState(submenuid,1,0);
96     if ((x>=0) && (y>=0))
97     {
98     if (is_checkable)
99       checked=!checked;
100     if ((id>=0) &&(MenuActiveProc!=Default_MenuActiveProc))
101       if (MenuActiveProc(id,checked,widget_data)==GUI_QUIT)
102         return GUI_QUIT;
103     }
104 /************ see comment below **********************************************/
105     return GUI_REDRAW;
106   }
107   return GUI_PASS;
108 }
109 
MouseMotion(int x,int y,Uint8 state)110 GUI_status GUI_Submenu::MouseMotion(int x,int y,Uint8 state)
111 {
112   if ((pressed[0]==2) && (x>=0) && (y>=0))
113   {
114     parent->SetCommonClickState(submenuid,1,1);
115     pressed[0]=1;
116 /* Unfortunately, here a complete GUI redraw is necessary because of the *********
117 ** background restauration. In future there should be a background backup facility **
118 ** in widgets. But to what extent? In a SDL program there should be action so any **
119 ** background backup would certainly be out of date... ***************************/
120     return GUI_REDRAW;
121   }
122   return GUI_PASS;
123 }
124 
SetItemsClickState(int button,int value)125 void GUI_Submenu::SetItemsClickState(int button, int value)
126 {
127   for (int i=0;i<numitems;i++)
128   {
129     items[i]->SetClickState(button,value);
130     if (value)
131       items[i]->Show();
132     else
133       items[i]->Hide();
134     items[i]->Redraw();
135   }
136 }
137 
138 //////////////////////////////////////////////////////////////////////////////////////
139 
GUI_Menuitem(GUI_Menu * Aparent,int Asubmenuid,int Aid,int x,int y,char * Atext,GUI_Font * Afont,GUI_MenuActiveProc activeproc,int is_checkmenu)140 GUI_Menuitem::GUI_Menuitem(GUI_Menu *Aparent,int Asubmenuid, int Aid,
141 			   int x, int y, char *Atext, GUI_Font *Afont,
142 			   GUI_MenuActiveProc activeproc, int is_checkmenu)
143   : GUI_Submenu(Aparent,Asubmenuid,x,y,Atext,Afont,is_checkmenu)
144 {
145   id=Aid;
146   if (activeproc==NULL)
147   {
148     MenuActiveProc=Default_MenuActiveProc;
149   }
150   else
151   {
152     MenuActiveProc=activeproc;
153   }
154 }
155 
SetCheck(int flag)156 void GUI_Menuitem::SetCheck(int flag)
157 {
158   checked=flag;
159 }
160 
161 ///////////////////////////////////////////////////////////////////////////////////////
162 
GUI_Menu(GUI * Agui,int width,GUI_Font * Afont)163 GUI_Menu::GUI_Menu(GUI *Agui, int width, GUI_Font *Afont)
164   : GUI_Area(0,0,width,
165        (Afont==NULL)?(8+MENU_OVERSIZE):(Afont->CharHeight()+MENU_OVERSIZE),
166        BF_R,BF_G,BF_B)
167 {
168   gui=Agui;
169   numitems=0;
170   if (Afont==NULL)
171     font=new GUI_Font();
172   else
173     font=Afont;
174 }
175 
~GUI_Menu()176 GUI_Menu::~GUI_Menu()
177 {
178 // future: free dynamic items array
179 }
180 
AddSubmenu(int Asubmenuid,char * Atext)181 void GUI_Menu::AddSubmenu(int Asubmenuid, char *Atext)
182 {
183   int newpos=0;
184 
185   if (numitems<10)
186   {
187     for (int i=0;i<numitems;i++)
188       newpos+=items[i]->W();
189 
190     items[numitems]=new GUI_Submenu(this,Asubmenuid,newpos,0,Atext,font,0);
191     gui->AddWidget(items[numitems++]);
192   }
193 }
194 
AddMenuitem(int Asubmenuid,int Aid,char * Atext,GUI_MenuActiveProc Aactiveproc,int is_checkmenu)195 void GUI_Menu::AddMenuitem(int Asubmenuid, int Aid, char *Atext,
196 	       GUI_MenuActiveProc Aactiveproc, int is_checkmenu)
197 {
198   GUI_Submenu *temp=NULL;
199 
200   for (int i=0;i<numitems;i++)
201     if (items[i]->GetSubmenuId()==Asubmenuid)
202       temp=items[i];
203 
204   if (temp!=NULL)
205   {
206     GUI_Menuitem *newitem=new GUI_Menuitem(this,Asubmenuid, Aid, temp->X(),
207        temp->GetNumSubitems()*(font->CharHeight()+MENU_OVERSIZE)+temp->H(),
208        Atext,font,Aactiveproc,is_checkmenu);
209     temp->AddSubitem(newitem);
210     gui->AddWidget(newitem);
211   }
212 }
213 
SetCommonClickState(int submenuid,int button,int value)214 void GUI_Menu::SetCommonClickState(int submenuid,int button, int value)
215 {
216   if ((button>0) && (button<=3))
217     pressed[button-1]=value;
218 
219   for (int i=0;i<numitems;i++)
220   {
221     if ((items[i]->GetSubmenuId()==submenuid) && (value>0))
222     {
223       items[i]->SetItemsClickState(button,2);
224       items[i]->SetClickState(button,1);
225       items[i]->Redraw();
226     }
227     else
228     {
229       items[i]->SetItemsClickState(button,0);
230       items[i]->SetClickState(button,(value>0)?2:0);
231       items[i]->Redraw();
232     }
233   }
234 }
235