2 * Acess GUI (AxWin) Version 2
3 * By John Hodge (thePowersGang)
5 * Window Manager and Widget Control
11 #include <acess/sys.h> // _SysDebug
14 extern void Video_GetTextDims(tFont *Font, const char *Text, int *W, int *H);
17 tApplication *AxWin_RegisterClient(tIPC_Type *IPCType, void *Ident, const char *Name);
18 void AxWin_DeregisterClient(tApplication *App);
19 tApplication *AxWin_GetClient(tIPC_Type *Method, void *Ident);
20 tElement *AxWin_CreateElement(tElement *Parent, int Type, int Flags, const char *DebugName);
21 void AxWin_DeleteElement(tElement *Element);
22 void AxWin_SetFlags(tElement *Element, int Flags);
23 void AxWin_SetSize(tElement *Element, int Size);
24 void AxWin_SetText(tElement *Element, const char *Text);
27 // - TODO: Handle windows by having multiple root elements
28 tElement gWM_RootElement = {
31 tWindow *gWM_WindowFirst;
32 tWindow *gWM_WindowLast;
33 tApplication *gWM_Applications;
34 int giWM_MaxAreaX = 0;
35 int giWM_MaxAreaY = 0;
36 int giWM_MaxAreaW = -1;
37 int giWM_MaxAreaH = -1;
39 // --- Element type flags
41 void (*Init)(tElement *This);
42 void (*Delete)(tElement *This);
43 void (*UpdateFlags)(tElement *This);
44 void (*UpdateSize)(tElement *This);
45 void (*UpdateText)(tElement *This);
46 } gaWM_WidgetTypes[MAX_ELETYPES] = {
47 {NULL, NULL, NULL, NULL, NULL}, // NULL
48 {NULL, NULL, NULL, NULL, NULL}, // Window
49 {NULL, NULL, NULL, NULL, NULL} // Box
51 const int ciWM_NumWidgetTypes = sizeof(gaWM_WidgetTypes)/sizeof(gaWM_WidgetTypes[0]);
54 tApplication *AxWin_RegisterClient(tIPC_Type *Method, void *Ident, const char *Name)
56 int identlen = Method->GetIdentSize(Ident);
57 // Structure, empty string, Name, Ident
58 tApplication *ret = calloc( 1, sizeof(tApplication) + 1 + strlen(Name) + 1 + identlen );
63 ret->Name = &ret->MetaElement.DebugName[1];
64 strcpy(ret->Name, Name);
66 ret->Ident = ret->Name + strlen(Name) + 1;
67 memcpy(ret->Ident, Ident, identlen);
69 ret->IPCType = Method;
72 ret->MaxElementIndex = DEFAULT_ELEMENTS_PER_APP;
73 ret->EleIndex = calloc( 1, ret->MaxElementIndex * sizeof(*ret->EleIndex) );
76 ret->Next = gWM_Applications;
77 gWM_Applications = ret;
79 // TODO: Inform listeners of the new application
84 void AxWin_DeregisterClient(tApplication *App)
86 // TODO: Complete implementing DeregisterClient
89 for( win = App->MetaElement.FirstChild; win; win = next )
91 next = win->NextSibling;
92 AxWin_DeleteElement(win);
95 // TODO: Inform listeners of deleted application
99 tApplication *app, *prev = NULL;
100 for( app = gWM_Applications; app; app = app->Next )
102 if( app == App ) break;
109 prev->Next = App->Next;
111 gWM_Applications = App->Next;
119 * \brief Get an application handle from a client identifier
121 tApplication *AxWin_GetClient(tIPC_Type *Method, void *Ident)
123 // TODO: Faster and smarter technique
125 for( app = gWM_Applications; app; app = app->Next )
127 if( app->IPCType != Method ) continue;
128 if( Method->CompareIdent( app->Ident, Ident ) != 0 ) continue;
134 tElement *AxWin_CreateAppWindow(tApplication *App, const char *Name)
139 win = calloc(1, sizeof(tWindow) + 1);
140 if(!win) return NULL;
142 ret = &win->RootElement;
143 ret->Type = ELETYPE_WINDOW;
145 ret->Parent = &App->MetaElement;
147 // Add to parent list
148 if(ret->Parent->LastChild)
149 ret->Parent->LastChild->NextSibling = ret;
150 ret->Parent->LastChild = ret;
151 if(!ret->Parent->FirstChild)
152 ret->Parent->FirstChild = ret;
154 ret->Text = strdup(Name);
159 // --- Widget Creation and Control ---
160 tAxWin_Element *AxWin_CreateElement(tElement *Parent, int Type, int Flags, const char *DebugName)
163 const char *dbgName = DebugName ? DebugName : "";
165 ret = calloc(sizeof(tElement)+strlen(dbgName)+1, 1);
166 if(!ret) return NULL;
170 strcpy(ret->DebugName, dbgName);
171 if(Parent == NULL) Parent = &gWM_RootElement;
172 ret->Parent = Parent;
175 // Append to parent's list
176 if(Parent->LastChild)
177 Parent->LastChild->NextSibling = ret;
178 Parent->LastChild = ret;
179 if(!Parent->FirstChild) Parent->FirstChild = ret;
186 if( Type < ciWM_NumWidgetTypes && gaWM_WidgetTypes[Type].Init )
187 gaWM_WidgetTypes[Type].Init(ret);
189 WM_UpdateMinDims(ret->Parent);
195 * \brief Delete an element
197 void AxWin_DeleteElement(tElement *Element)
199 tElement *child, *next;
201 for(child = Element->FirstChild; child; child = next)
203 next = child->NextSibling;
204 AxWin_DeleteElement(child);
207 // TODO: Implement AxWin_DeleteElement
208 // TODO: Clean up related data.
209 if( Element->Type < ciWM_NumWidgetTypes && gaWM_WidgetTypes[Element->Type].Delete )
210 gaWM_WidgetTypes[Element->Type].Delete(Element);
213 Element->Owner->EleIndex[ Element->ApplicationID ] = NULL;
223 * \brief Alter an element's flags
225 void AxWin_SetFlags(tElement *Element, int Flags)
227 // Permissions are handled in the message handler
229 gWM_RootElement.Flags = Flags;
233 Element->Flags = Flags;
238 * \brief Set the fixed lenghthways size of an element
240 void AxWin_SetSize(tElement *Element, int Size)
242 if(!Element) return ;
243 Element->FixedWith = Size;
248 * \brief Set the text field of an element
249 * \note Used for the image path on ELETYPE_IMAGE
251 void AxWin_SetText(tElement *Element, const char *Text)
253 if(!Element) return ;
254 if(Element->Text) free(Element->Text);
255 Element->Text = strdup(Text);
257 switch(Element->Type)
260 if(Element->Data) free(Element->Data);
261 Element->Data = Image_Load( Element->Text );
263 Element->Flags &= ~ELEFLAG_FIXEDSIZE;
267 //Element->Flags |= ELEFLAG_FIXEDSIZE;
268 Element->CachedW = ((tImage*)Element->Data)->Width;
269 Element->CachedH = ((tImage*)Element->Data)->Height;
271 if(Element->Parent && Element->Parent->Flags & ELEFLAG_VERTICAL) {
272 Element->MinCross = ((tImage*)Element->Data)->Width;
273 Element->MinWith = ((tImage*)Element->Data)->Height;
276 Element->MinWith = ((tImage*)Element->Data)->Width;
277 Element->MinCross = ((tImage*)Element->Data)->Height;
284 Video_GetTextDims(NULL, Element->Text, &w, &h);
285 if(Element->Parent && Element->Parent->Flags & ELEFLAG_VERTICAL) {
286 Element->MinCross = w;
287 Element->MinWith = h;
290 Element->MinWith = w;
291 Element->MinCross = h;
295 default: // Any other, no special case