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