Usermode/AxWin3 - Managed to pass input all the way back to client code :)
[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  * main.c
6  * - Entrypoint and setup
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                 info->nElements ++;
122                 info->Elements = realloc(info->Elements, sizeof(*info->Elements)*info->nElements);
123                 newID = info->nElements - 1;
124                 _SysDebug("Expanded and allocated %i", newID);
125         }
126         else
127                 _SysDebug("Allocated %i", newID);
128         info->Elements[newID] = (void*)-1;
129         
130         // Create new widget structure
131         ret = calloc(sizeof(tAxWin3_Widget), 1);
132         ret->Window = Parent->Window;
133         ret->ID = newID;
134
135         info->Elements[newID] = ret;
136
137         // Send create widget message
138         {
139                 char    tmp[sizeof(tWidgetMsg_Create)+1];
140                 tWidgetMsg_Create       *msg = (void*)tmp;
141                 msg->Parent = Parent->ID;
142                 msg->NewID = newID;
143                 msg->Type = Type;
144                 msg->Flags = Flags;
145                 msg->DebugName[0] = '\0';
146                 AxWin3_SendMessage(ret->Window, ret->Window, MSG_WIDGET_CREATE, sizeof(tmp), tmp);
147         }
148
149         return ret;
150 }
151
152 void AxWin3_Widget_DelWidget(tAxWin3_Widget *Widget)
153 {
154         tWidgetMsg_Delete       msg;
155         tWidgetWindowInfo       *info = AxWin3_int_GetDataPtr(Widget->Window);
156         
157         msg.WidgetID = Widget->ID;
158         AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_DELETE, sizeof(msg), &msg);
159         
160         info->Elements[Widget->ID] = NULL;
161         if(Widget->ID < info->FirstFreeID)
162                 info->FirstFreeID = Widget->ID;
163         free(Widget);
164 }
165
166 // --- Callbacks
167 void AxWin3_Widget_SetFireHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_FireCb Callback)
168 {
169         if(!Widget)     return;
170         Widget->Fire = Callback;
171 }
172
173 void AxWin3_Widget_SetKeyHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_KeyUpDownCb Callback)
174 {
175         if(!Widget)     return;
176         Widget->KeyUpDown = Callback;
177 }
178
179 void AxWin3_Widget_SetKeyFireHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_KeyFireCb Callback)
180 {
181         if(!Widget)     return;
182         Widget->KeyFire = Callback;
183 }
184
185 void AxWin3_Widget_SetMouseMoveHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_MouseMoveCb Callback)
186 {
187         if(!Widget)     return;
188         Widget->MouseMove = Callback;
189 }
190
191 void AxWin3_Widget_SetMouseButtonHandler(tAxWin3_Widget *Widget, tAxWin3_Widget_MouseBtnCb Callback)
192 {
193         if(!Widget)     return;
194         Widget->MouseButton = Callback;
195 }
196
197 // --- Manipulation
198 void AxWin3_Widget_SetFlags(tAxWin3_Widget *Widget, int FlagSet, int FlagMask)
199 {
200         tWidgetMsg_SetFlags     msg;
201         msg.WidgetID = Widget->ID;
202         msg.Value = FlagSet;
203         msg.Mask = FlagMask;
204         
205         AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETFLAGS, sizeof(msg), &msg);
206 }
207
208 void AxWin3_Widget_SetSize(tAxWin3_Widget *Widget, int Size)
209 {
210         tWidgetMsg_SetSize      msg;
211         
212         msg.WidgetID = Widget->ID;
213         msg.Value = Size;
214         AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETSIZE, sizeof(msg), &msg);
215 }
216
217 void AxWin3_Widget_SetText(tAxWin3_Widget *Widget, const char *Text)
218 {
219         char    buf[sizeof(tWidgetMsg_SetText) + strlen(Text) + 1];
220         tWidgetMsg_SetText      *msg = (void*)buf;
221         
222         msg->WidgetID = Widget->ID;
223         strcpy(msg->Text, Text);
224         
225         AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETTEXT, sizeof(buf), buf);
226 }
227
228 void AxWin3_Widget_SetColour(tAxWin3_Widget *Widget, int Index, tAxWin3_Colour Colour)
229 {
230         tWidgetMsg_SetColour    msg;
231         
232         msg.WidgetID = Widget->ID;
233         msg.Index = Index;
234         msg.Colour = Colour;
235         AxWin3_SendMessage(Widget->Window, Widget->Window, MSG_WIDGET_SETCOLOUR, sizeof(msg), &msg);
236 }

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