TODO
[tpg/acess2.git] / Usermode / Applications / axwin3_src / libaxwin3.so_src / r_widget.c
1 /*
2  * AxWin3 Interface Library
3  * - By John Hodge (thePowersGang)
4  *
5  * r_widget.c
6  * - Widget window type interface
7  */
8 #include <axwin3/axwin.h>
9 #include <axwin3/widget.h>
10 #include "include/internal.h"
11 #include "include/ipc.h"
12 #include <stdlib.h>
13 #include <widget_messages.h>
14 #include <string.h>
15
16 // === STRUCTURES ===
17 struct sAxWin3_Widget
18 {
19         tHWND   Window;
20         uint32_t        ID;
21         // Callbacks
22         tAxWin3_Widget_FireCb   Fire;
23         tAxWin3_Widget_KeyUpDownCb      KeyUpDown;
24         tAxWin3_Widget_KeyFireCb        KeyFire;
25         tAxWin3_Widget_MouseMoveCb      MouseMove;
26         tAxWin3_Widget_MouseBtnCb       MouseButton;
27 };
28
29 typedef struct
30 {
31          int    nElements;
32         tAxWin3_Widget  **Elements;
33          int    FirstFreeID;
34         tAxWin3_Widget  RootElement;
35         // Callbacks for each element
36 } tWidgetWindowInfo;
37
38 // === CODE ===
39 tAxWin3_Widget *AxWin3_Widget_int_GetElementByID(tHWND Window, uint32_t ID)
40 {
41         tWidgetWindowInfo       *info;
42         if(!Window)     return NULL;
43         
44         info = AxWin3_int_GetDataPtr(Window);
45         if(ID >= info->nElements)       return NULL;
46         
47         return info->Elements[ID];
48 }
49
50 int AxWin3_Widget_MessageHandler(tHWND Window, int MessageID, int Size, void *Data)
51 {
52         tAxWin3_Widget  *widget;
53
54         switch(MessageID)
55         {
56         case MSG_WIDGET_FIRE: {
57                 tWidgetMsg_Fire *msg = Data;
58                 if(Size < sizeof(*msg)) return -1;
59                 widget = AxWin3_Widget_int_GetElementByID(Window, msg->WidgetID);
60                 if(widget->Fire)        widget->Fire(widget);
61                 
62                 return 0; }
63         default:
64                 return 0;
65         }
66 }
67
68 tHWND AxWin3_Widget_CreateWindow(tHWND Parent, int W, int H, int RootEleFlags)
69 {
70         tHWND   ret;
71         tWidgetWindowInfo       *info;
72         
73         ret = AxWin3_CreateWindow(
74                 Parent, "Widget", RootEleFlags,
75                 sizeof(*info) + sizeof(tAxWin3_Widget), AxWin3_Widget_MessageHandler
76                 );
77         info = AxWin3_int_GetDataPtr(ret);
78
79         info->RootElement.Window = ret;
80         info->RootElement.ID = -1;
81
82         AxWin3_ResizeWindow(ret, W, H);
83         
84         return ret;
85 }
86
87 void AxWin3_Widget_DestroyWindow(tHWND Window)
88 {
89         // Free all element structures
90         
91         // Free array
92         
93         // Request window to be destroyed (will clean up any data stored in tHWND)
94 }
95
96 tAxWin3_Widget *AxWin3_Widget_GetRoot(tHWND Window)
97 {
98         tWidgetWindowInfo       *info = AxWin3_int_GetDataPtr(Window);
99         return &info->RootElement;
100 }
101
102 tAxWin3_Widget *AxWin3_Widget_AddWidget(tAxWin3_Widget *Parent, int Type, int Flags, const char *DebugName)
103 {
104          int    newID;
105         tWidgetWindowInfo       *info;
106         tAxWin3_Widget  *ret;
107
108         if(!Parent)     return NULL;
109
110         info = AxWin3_int_GetDataPtr(Parent->Window);
111         
112         // Assign ID
113         // BUG BUG BUG - Double Allocations!
114         // TODO: Atomicity
115         for( newID = info->FirstFreeID; newID < info->nElements; newID ++ )
116         {
117                 if( info->Elements[newID] == NULL )
118                         break;
119         }
120         if( newID == info->nElements )
121         {
122                 const int size_step = 4;
123                 info->nElements += 4;
124                 info->Elements = realloc(info->Elements, sizeof(*info->Elements)*info->nElements);
125                 newID = info->nElements - 4;
126                 memset( &info->Elements[newID+1], 0, (size_step-1)*sizeof(info->Elements));
127                 _SysDebug("Expanded to %i and allocated %i", info->nElements, newID);
128         }
129         else
130                 _SysDebug("Allocated %i", newID);
131         info->Elements[newID] = (void*)-1;
132         
133         // Create new widget structure
134         ret = calloc(sizeof(tAxWin3_Widget), 1);
135         ret->Window = Parent->Window;
136         ret->ID = newID;
137
138         info->Elements[newID] = ret;
139
140         // Send create widget message
141         {
142                 char    tmp[sizeof(tWidgetMsg_Create)+1];
143                 tWidgetMsg_Create       *msg = (void*)tmp;
144                 msg->Parent = Parent->ID;
145                 msg->NewID = newID;
146                 msg->Type = Type;
147                 msg->Flags = Flags;
148                 msg->DebugName[0] = '\0';
149                 AxWin3_SendMessage(ret->Window, ret->Window, MSG_WIDGET_CREATE, sizeof(tmp), tmp);
150         }
151
152         return ret;
153 }
154
155 void AxWin3_Widget_DelWidget(tAxWin3_Widget *Widget)
156 {
157         tWidgetMsg_Delete       msg;
158         tWidgetWindowInfo       *info = AxWin3_int_GetDataPtr(Widget->Window);
159         
160         msg.WidgetID = Widget->ID;
161         AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_DELETE, sizeof(msg), &msg);
162         
163         info->Elements[Widget->ID] = NULL;
164         if(Widget->ID < info->FirstFreeID)
165                 info->FirstFreeID = Widget->ID;
166         free(Widget);
167 }
168
169 // --- Callbacks
170 void AxWin3_Widget_SetFireHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_FireCb Callback)
171 {
172         if(!Widget)     return;
173         Widget->Fire = Callback;
174 }
175
176 void AxWin3_Widget_SetKeyHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_KeyUpDownCb Callback)
177 {
178         if(!Widget)     return;
179         Widget->KeyUpDown = Callback;
180 }
181
182 void AxWin3_Widget_SetKeyFireHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_KeyFireCb Callback)
183 {
184         if(!Widget)     return;
185         Widget->KeyFire = Callback;
186 }
187
188 void AxWin3_Widget_SetMouseMoveHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_MouseMoveCb Callback)
189 {
190         if(!Widget)     return;
191         Widget->MouseMove = Callback;
192 }
193
194 void AxWin3_Widget_SetMouseButtonHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_MouseBtnCb Callback)
195 {
196         if(!Widget)     return;
197         Widget->MouseButton = Callback;
198 }
199
200 // --- Manipulation
201 void AxWin3_Widget_SetFlags(tAxWin3_Widget *Widget, int FlagSet, int FlagMask)
202 {
203         tWidgetMsg_SetFlags     msg;
204         msg.WidgetID = Widget->ID;
205         msg.Value = FlagSet;
206         msg.Mask = FlagMask;
207         
208         AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETFLAGS, sizeof(msg), &msg);
209 }
210
211 void AxWin3_Widget_SetSize(tAxWin3_Widget *Widget, int Size)
212 {
213         tWidgetMsg_SetSize      msg;
214         
215         msg.WidgetID = Widget->ID;
216         msg.Value = Size;
217         AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETSIZE, sizeof(msg), &msg);
218 }
219
220 void AxWin3_Widget_SetText(tAxWin3_Widget *Widget, const char *Text)
221 {
222         char    buf[sizeof(tWidgetMsg_SetText) + strlen(Text) + 1];
223         tWidgetMsg_SetText      *msg = (void*)buf;
224         
225         msg->WidgetID = Widget->ID;
226         strcpy(msg->Text, Text);
227         
228         AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETTEXT, sizeof(buf), buf);
229 }
230
231 char *AxWin3_Widget_GetText(tAxWin3_Widget *Widget)
232 {
233         char    buf[sizeof(tWidgetMsg_SetText)];
234         tWidgetMsg_SetText      *msg = (void*)buf;
235         tAxWin_IPCMessage       *retmsg;
236         char    *ret;
237         
238         msg->WidgetID = Widget->ID;
239
240         AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf);
241
242         retmsg = AxWin3_int_WaitIPCMessage(MSG_WIDGET_GETTEXT);
243         msg = (void*)retmsg->Data;
244
245         if( retmsg->Size < sizeof(*msg) ) {
246                 free(retmsg);
247                 return NULL;
248         }
249
250         ret = strndup(msg->Text, retmsg->Size - sizeof(*msg));
251         free(retmsg);
252         return ret;
253 }
254
255 void AxWin3_Widget_SetColour(tAxWin3_Widget *Widget, int Index, tAxWin3_Colour Colour)
256 {
257         tWidgetMsg_SetColour    msg;
258         
259         msg.WidgetID = Widget->ID;
260         msg.Index = Index;
261         msg.Colour = Colour;
262         AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETCOLOUR, sizeof(msg), &msg);
263 }

UCC git Repository :: git.ucc.asn.au