2 * Acess GUI (AxWin) Version 2
3 * By John Hodge (thePowersGang)
11 #include <acess/sys.h> // _SysDebug
14 extern void Decorator_RenderWidget(tElement *Element);
15 extern tElement gWM_RootElement;
16 extern tApplication *gWM_Applications;
17 extern int giWM_MaxAreaX;
18 extern int giWM_MaxAreaY;
19 extern int giWM_MaxAreaW;
20 extern int giWM_MaxAreaH;
23 void WM_UpdateMinDims(tElement *Element);
24 void WM_UpdateDimensions(tElement *Element, int Pass);
25 void WM_UpdatePosition(tElement *Element);
26 void WM_RenderWidget(tElement *Element);
31 * \brief Updates the dimensions of an element
32 * \todo What is the \a Pass parameter for
34 * The dimensions of an element are calculated from the parent's
35 * cross dimension (the side at right angles to the alignment) sans some
38 void WM_UpdateDimensions(tElement *Element, int Pass)
45 int fullCross, dynWith;
47 _SysDebug("WM_UpdateDimensions %p'%s'", Element, Element->DebugName);
48 _SysDebug(" -> Flags = 0x%x", Element->Flags);
49 _SysDebug(" ->CachedH = %i, ->PaddingT = %i, ->PaddingB = %i",
50 Element->CachedH, Element->PaddingT, Element->PaddingB
52 _SysDebug(" ->CachedW = %i, ->PaddingL = %i, ->PaddingR = %i",
53 Element->CachedW, Element->PaddingL, Element->PaddingR
57 for( child = Element->FirstChild; child; child = child->NextSibling )
59 if( child->Flags & ELEFLAG_ABSOLUTEPOS )
62 _SysDebug(" > %p'%s' ->FixedWith = %i", child, child->DebugName, child->FixedWith);
63 if( child->FixedWith )
66 fixedSize += child->FixedWith;
69 if( child->FixedCross && maxCross < child->FixedCross )
70 maxCross = child->FixedCross;
71 if( child->MinCross && maxCross < child->MinCross )
72 maxCross = child->MinCross;
76 _SysDebug(" - nChildren = %i, nFixed = %i", Element, nChildren, nFixed);
77 if( nChildren > nFixed ) {
78 if( Element->Flags & ELEFLAG_VERTICAL )
79 dynWith = Element->CachedH - Element->PaddingT
82 dynWith = Element->CachedW - Element->PaddingL
85 if( dynWith < 0 ) return ;
86 dynWith /= nChildren - nFixed;
87 _SysDebug(" - dynWith = %i", dynWith);
90 if( Element->Flags & ELEFLAG_VERTICAL )
91 fullCross = Element->CachedW - Element->PaddingL - Element->PaddingR;
93 fullCross = Element->CachedH - Element->PaddingT - Element->PaddingB;
95 _SysDebug(" - fullCross = %i", Element, fullCross);
97 // Pass 2 - Set sizes and recurse
98 for( child = Element->FirstChild; child; child = child->NextSibling )
102 _SysDebug(" > %p'%s' ->MinCross = %i", child, child->DebugName, child->MinCross);
105 // --- Cross Size ---
106 if( child->FixedCross )
107 cross = child->FixedCross;
109 // TODO: Extra flag so options are (Expand, Equal, Wrap)
110 else if( child->Flags & ELEFLAG_NOEXPAND )
111 cross = child->MinCross;
114 _SysDebug(" > %p'%s' - cross = %i", child, child->DebugName, cross);
115 if( Element->Flags & ELEFLAG_VERTICAL )
116 child->CachedW = cross;
118 child->CachedH = cross;
121 if( child->FixedWith)
122 with = child->FixedWith;
123 else if( child->Flags & ELEFLAG_NOSTRETCH )
124 with = child->MinWith;
127 _SysDebug(" > %p'%s' - with = %i", child, child->DebugName, with);
128 if( Element->Flags & ELEFLAG_VERTICAL )
129 child->CachedH = with;
131 child->CachedW = with;
133 WM_UpdateDimensions(child, Pass);
136 _SysDebug("%p'%s' Done", Element, Element->DebugName);
140 * \brief Updates the position of an element
142 * The parent element sets the positions of its children
144 void WM_UpdatePosition(tElement *Element)
148 static int depth = 0;
149 char indent[depth+1];
151 if( Element->Flags & ELEFLAG_NORENDER ) return ;
153 memset(indent, ' ', depth);
154 indent[depth] = '\0';
157 _SysDebug("%sWM_UpdatePosition %p'%s'{PaddingL:%i, PaddingT:%i}",
158 indent, Element, Element->DebugName, Element->PaddingL, Element->PaddingT);
161 x = Element->CachedX + Element->PaddingL;
162 y = Element->CachedY + Element->PaddingT;
164 _SysDebug("%s- Alignment = %s", indent,
165 (Element->Flags & ELEFLAG_VERTICAL) ? "vertical" : "horizontal");
168 for(child = Element->FirstChild; child; child = child->NextSibling)
170 _SysDebug("%s- x = %i, y = %i", indent, x, y);
175 if( Element->Flags & ELEFLAG_ALIGN_CENTER ) {
176 _SysDebug("%sChild being aligned to center", indent);
177 if(Element->Flags & ELEFLAG_VERTICAL)
178 child->CachedX += Element->CachedW/2 - child->CachedW/2;
180 child->CachedY += Element->CachedH/2 - child->CachedH/2;
182 else if( Element->Flags & ELEFLAG_ALIGN_END) {
183 _SysDebug("%sChild being aligned to end", indent);
184 if(Element->Flags & ELEFLAG_VERTICAL )
185 child->CachedX += Element->CachedW
186 - Element->PaddingL - Element->PaddingR
189 child->CachedY += Element->CachedH
195 _SysDebug("%s> %p'%s' at (%i,%i)", indent, child, child->DebugName,
196 child->CachedX, child->CachedY);
198 // Update child's children positions
199 WM_UpdatePosition(child);
202 if(Element->Flags & ELEFLAG_VERTICAL ) {
203 y += child->CachedH + Element->GapSize;
206 x += child->CachedW + Element->GapSize;
210 _SysDebug("%sElement %p'%s' (%i,%i)",
211 indent, Element, Element->DebugName, Element->CachedX, Element->CachedY
217 * \brief Update the minimum dimensions of the element
218 * \note Called after a child's minimum dimensions have changed
220 void WM_UpdateMinDims(tElement *Element)
226 Element->MinCross = 0;
227 Element->MinWith = 0;
229 for(child = Element->FirstChild; child; child = child->NextSibling)
231 if( Element->Parent &&
232 (Element->Flags & ELEFLAG_VERTICAL) == (Element->Parent->Flags & ELEFLAG_VERTICAL)
235 if(child->FixedCross)
236 Element->MinCross += child->FixedCross;
238 Element->MinCross += child->MinCross;
240 Element->MinWith += child->FixedWith;
242 Element->MinWith += child->MinWith;
246 if(child->FixedCross)
247 Element->MinWith += child->FixedCross;
249 Element->MinWith += child->MinCross;
251 Element->MinCross += child->FixedWith;
253 Element->MinCross += child->MinWith;
258 WM_UpdateMinDims(Element->Parent);
262 void WM_RenderWidget(tElement *Element)
266 if( Element->Flags & ELEFLAG_NORENDER ) return ;
267 if( Element->Flags & ELEFLAG_INVISIBLE ) return ;
269 Decorator_RenderWidget(Element);
271 for(child = Element->FirstChild; child; child = child->NextSibling)
273 WM_RenderWidget(child);
277 void WM_UpdateWindow(tElement *Ele)
279 WM_UpdateDimensions( Ele, 0 );
280 WM_UpdatePosition( Ele );
281 WM_RenderWidget( Ele );
289 for( app = gWM_Applications; app; app = app->Next )
291 for( ele = app->MetaElement.FirstChild; ele; ele = ele->NextSibling ) {
292 if( ele->Flags & ELEFLAG_WINDOW_MAXIMISED ) {
293 ele->CachedX = giWM_MaxAreaX;
294 ele->CachedY = giWM_MaxAreaY;
295 ele->CachedW = giWM_MaxAreaW;
296 ele->CachedH = giWM_MaxAreaH;
298 ele->Flags |= ELEFLAG_NOEXPAND|ELEFLAG_ABSOLUTEPOS|ELEFLAG_FIXEDSIZE;
299 WM_UpdateWindow(ele);
303 gWM_RootElement.CachedX = 0;
304 gWM_RootElement.CachedY = 0;
305 gWM_RootElement.CachedW = giScreenWidth;
306 gWM_RootElement.CachedH = giScreenHeight;
307 gWM_RootElement.Flags |= ELEFLAG_NOEXPAND|ELEFLAG_ABSOLUTEPOS|ELEFLAG_FIXEDSIZE;
309 WM_UpdateWindow( &gWM_RootElement );