2 * AxWin3 Interface Library
3 * - By John Hodge (thePowersGang)
6 * - Widget window type interface
8 #include <axwin3/axwin.h>
9 #include <axwin3/widget.h>
10 #include "include/internal.h"
12 #include <widget_messages.h>
15 //static const int ciBaseElementCount = 16;
16 static const int ciStepElementCount = 16;
24 tAxWin3_Widget_FireCb Fire;
25 tAxWin3_Widget_KeyUpDownCb KeyUpDown;
26 tAxWin3_Widget_KeyFireCb KeyFire;
27 tAxWin3_Widget_MouseMoveCb MouseMove;
28 tAxWin3_Widget_MouseBtnCb MouseButton;
34 tAxWin3_Widget **Elements;
36 tAxWin3_Widget RootElement;
37 // Callbacks for each element
41 tAxWin3_Widget *AxWin3_Widget_int_GetElementByID(tHWND Window, uint32_t ID)
43 tWidgetWindowInfo *info;
44 if(!Window) return NULL;
46 info = AxWin3_int_GetDataPtr(Window);
47 if(ID >= info->nElements) return NULL;
49 return info->Elements[ID];
52 uint32_t AxWin3_Widget_int_AllocateID(tWidgetWindowInfo *Info)
55 // BUG BUG BUG - Double Allocations! (citation needed)
57 for( newID = Info->FirstFreeID; newID < Info->nElements; newID ++ )
59 if( Info->Elements[newID] == NULL )
62 if( newID == Info->nElements )
64 Info->nElements += ciStepElementCount;
65 Info->Elements = realloc(Info->Elements, sizeof(*Info->Elements)*Info->nElements);
66 newID = Info->nElements - ciStepElementCount;
67 memset( &Info->Elements[newID+1], 0, (ciStepElementCount-1)*sizeof(Info->Elements));
68 _SysDebug("Widget: Expanded to %i and allocated %i", Info->nElements, newID);
71 _SysDebug("Widget: Allocated %i", newID);
72 Info->Elements[newID] = (void*)-1;
78 int AxWin3_Widget_MessageHandler(tHWND Window, int MessageID, int Size, void *Data)
80 tAxWin3_Widget *widget;
84 // case WNDMSG_DESTROY: {
86 case MSG_WIDGET_FIRE: {
87 tWidgetMsg_Fire *msg = Data;
88 if(Size < sizeof(*msg)) return -1;
89 widget = AxWin3_Widget_int_GetElementByID(Window, msg->WidgetID);
90 if(widget->Fire) widget->Fire(widget);
93 case MSG_WIDGET_KEYPRESS: {
95 case MSG_WIDGET_MOUSEBTN: {
103 tHWND AxWin3_Widget_CreateWindow(tHWND Parent, int W, int H, int RootEleFlags)
106 tWidgetWindowInfo *info;
108 ret = AxWin3_CreateWindow(
109 Parent, "Widget", RootEleFlags,
110 sizeof(*info) + sizeof(tAxWin3_Widget), AxWin3_Widget_MessageHandler
112 info = AxWin3_int_GetDataPtr(ret);
114 info->RootElement.Window = ret;
115 info->RootElement.ID = -1;
117 AxWin3_ResizeWindow(ret, W, H);
122 void AxWin3_Widget_DestroyWindow(tHWND Window)
124 // Free all element structures
128 // Request window to be destroyed (will clean up any data stored in tHWND)
131 tAxWin3_Widget *AxWin3_Widget_GetRoot(tHWND Window)
133 tWidgetWindowInfo *info = AxWin3_int_GetDataPtr(Window);
134 return &info->RootElement;
137 tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Flags, const char *DebugName)
140 tWidgetWindowInfo *info;
143 if(!Parent) return NULL;
145 info = AxWin3_int_GetDataPtr(Parent->Window);
147 newID = AxWin3_Widget_int_AllocateID(info);
149 // Create new widget structure
150 ret = calloc(sizeof(tAxWin3_Widget), 1);
151 ret->Window = Parent->Window;
154 info->Elements[newID] = ret;
156 // Send create widget message
158 char tmp[sizeof(tWidgetIPC_Create)+1];
159 tWidgetIPC_Create *msg = (void*)tmp;
160 msg->Parent = Parent->ID;
164 msg->DebugName[0] = '\0';
165 AxWin3_SendIPC(ret->Window, IPC_WIDGET_CREATE, sizeof(tmp), tmp);
171 tAxWin3_Widget *AxWin3_Widget_AddWidget_SubWindow(tAxWin3_Widget *Parent, tHWND Window, int Flags, const char *DbgName)
173 tWidgetWindowInfo *info = AxWin3_int_GetDataPtr(Parent->Window);
174 int newID = AxWin3_Widget_int_AllocateID(info);
176 tAxWin3_Widget *ret = calloc(sizeof(tAxWin3_Widget), 1);
177 ret->Window = Parent->Window;
179 info->Elements[newID] = ret;
183 char tmp[sizeof(tWidgetIPC_CreateSubWin)+1];
184 tWidgetIPC_CreateSubWin *msg = (void*)tmp;
185 msg->Parent = Parent->ID;
187 msg->Type = ELETYPE_SUBWIN;
188 msg->Flags = Flags; // TODO: Flags
189 msg->WindowHandle = AxWin3_int_GetWindowID(Window);
190 msg->DebugName[0] = '\0';
191 AxWin3_SendIPC(ret->Window, IPC_WIDGET_CREATESUBWIN, sizeof(tmp), tmp);
198 void AxWin3_Widget_DelWidget(tAxWin3_Widget *Widget)
200 tWidgetIPC_Delete msg;
201 tWidgetWindowInfo *info = AxWin3_int_GetDataPtr(Widget->Window);
203 msg.WidgetID = Widget->ID;
204 AxWin3_SendIPC(Widget->Window, IPC_WIDGET_DELETE, sizeof(msg), &msg);
206 info->Elements[Widget->ID] = NULL;
207 if(Widget->ID < info->FirstFreeID)
208 info->FirstFreeID = Widget->ID;
213 void AxWin3_Widget_SetFireHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_FireCb Callback)
216 Widget->Fire = Callback;
219 void AxWin3_Widget_SetKeyHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_KeyUpDownCb Callback)
222 Widget->KeyUpDown = Callback;
225 void AxWin3_Widget_SetKeyFireHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_KeyFireCb Callback)
228 Widget->KeyFire = Callback;
231 void AxWin3_Widget_SetMouseMoveHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_MouseMoveCb Callback)
234 Widget->MouseMove = Callback;
237 void AxWin3_Widget_SetMouseButtonHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_MouseBtnCb Callback)
240 Widget->MouseButton = Callback;
244 void AxWin3_Widget_SetFlags(tAxWin3_Widget *Widget, int FlagSet, int FlagMask)
246 tWidgetIPC_SetFlags msg;
247 msg.WidgetID = Widget->ID;
251 AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETFLAGS, sizeof(msg), &msg);
254 void AxWin3_Widget_SetSize(tAxWin3_Widget *Widget, int Size)
256 tWidgetIPC_SetSize msg;
258 msg.WidgetID = Widget->ID;
260 AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETSIZE, sizeof(msg), &msg);
263 void AxWin3_Widget_SetText(tAxWin3_Widget *Widget, const char *Text)
265 char buf[sizeof(tWidgetIPC_SetText) + strlen(Text) + 1];
266 tWidgetIPC_SetText *msg = (void*)buf;
268 msg->WidgetID = Widget->ID;
269 strcpy(msg->Text, Text);
271 AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETTEXT, sizeof(buf), buf);
274 char *AxWin3_Widget_GetText(tAxWin3_Widget *Widget)
276 char buf[sizeof(tWidgetIPC_SetText)];
277 tWidgetIPC_SetText *msg = (void*)buf;
280 msg->WidgetID = Widget->ID;
282 AxWin3_SendIPC(Widget->Window, IPC_WIDGET_GETTEXT, sizeof(buf), buf);
284 msg = AxWin3_WaitIPCMessage(Widget->Window, IPC_WIDGET_GETTEXT, &retmsg_size);
285 if( retmsg_size < sizeof(*msg) ) {
290 char *ret = strndup(msg->Text, retmsg_size - sizeof(*msg));
295 void AxWin3_Widget_SetColour(tAxWin3_Widget *Widget, int Index, tAxWin3_Colour Colour)
297 tWidgetIPC_SetColour msg;
299 msg.WidgetID = Widget->ID;
302 AxWin3_SendIPC(Widget->Window, IPC_WIDGET_SETCOLOUR, sizeof(msg), &msg);