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

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