1 |
#include <Posix.h> |
2 |
#include <App.h> |
3 |
#include <X11.h> |
4 |
#include <X11/IntrinsicP.h> |
5 |
#include <X11/StringDefs.h> |
6 |
#include <debug.h> |
7 |
|
8 |
#include <CrListP.h> |
9 |
#include <CrUtil.h> |
10 |
|
11 |
/********************************************************************** |
12 |
* resources |
13 |
**********************************************************************/ |
14 |
|
15 |
#define Offset(field) XtOffsetOf(CrListRec,crList.field) |
16 |
static XtResource resources[] = { |
17 |
|
18 |
{ XtNselectCallback,XtCSelectCallback,XtRCallback,sizeof(XtPointer), |
19 |
Offset(selectCallbacks),XtRCallback,NULL }, |
20 |
|
21 |
{ XtNinsertCallback,XtCInsertCallback,XtRCallback,sizeof(XtPointer), |
22 |
Offset(insertCallbacks),XtRCallback,NULL }, |
23 |
|
24 |
{ XtNdeleteCallback,XtCDeleteCallback,XtRCallback,sizeof(XtPointer), |
25 |
Offset(deleteCallbacks),XtRCallback,NULL }, |
26 |
|
27 |
{ XtNnext, XtCNext,XtRPointer,sizeof(XtPointer), |
28 |
Offset(next),XtRPointer,NULL }, |
29 |
|
30 |
{ XtNpackage,XtCPackage,XtRPointer,sizeof(XtPointer), |
31 |
Offset(caller),XtRPointer,NULL }, |
32 |
|
33 |
{ XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), |
34 |
Offset(font),XtRString, XtDefaultFont}, |
35 |
|
36 |
{ XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), |
37 |
Offset(foreground), XtRString, XtDefaultForeground}, |
38 |
}; |
39 |
#undef Offset |
40 |
|
41 |
/********************************************************************** |
42 |
* declarations |
43 |
**********************************************************************/ |
44 |
|
45 |
static void ClassInitialize(); |
46 |
static void Initialize(Widget req,Widget new,Arg args[],Cardinal *num); |
47 |
static void Destroy(Widget w); |
48 |
static void Resize(Widget w); |
49 |
static void Redisplay(Widget w,XEvent *event,Region region); |
50 |
static Boolean SetValues(Widget cur,Widget req,Widget new, |
51 |
Arg args[],Cardinal *num); |
52 |
static void Insert(Widget,XEvent*,String*,Cardinal*); |
53 |
static void Select(Widget,XEvent*,String*,Cardinal*); |
54 |
static void Delete(Widget,XEvent*,String*,Cardinal*); |
55 |
|
56 |
/********************************************************************** |
57 |
* actions & translations |
58 |
**********************************************************************/ |
59 |
|
60 |
static XtActionsRec actionsList[] = { |
61 |
{"insert", Insert}, |
62 |
{"select", Select}, |
63 |
{"delete", Delete}, |
64 |
}; |
65 |
|
66 |
static char defaultTranslations[] = "\ |
67 |
<Btn1Up>: insert() \n\ |
68 |
<Btn2Up>: select() \n\ |
69 |
<Btn3Up>: delete() \n\ |
70 |
"; |
71 |
|
72 |
/********************************************************************** |
73 |
* class |
74 |
**********************************************************************/ |
75 |
|
76 |
CrListClassRec crListClassRec = { |
77 |
{ /*** Core ***/ |
78 |
/* superclass */ (WidgetClass) &widgetClassRec, |
79 |
/* class_name */ "CrList", |
80 |
/* widget_size */ sizeof(CrListRec) , |
81 |
/* class_initialize */ ClassInitialize , |
82 |
/* class_part_initialize */ NULL , |
83 |
/* class_inited */ FALSE , |
84 |
/* initialize */ Initialize, |
85 |
/* initialize_hook */ NULL, |
86 |
/* realize */ XtInheritRealize, |
87 |
/* actions */ actionsList, |
88 |
/* num_actions */ XtNumber(actionsList), |
89 |
/* resources */ resources, |
90 |
/* num_resources */ XtNumber(resources), |
91 |
/* xrm_class */ NULLQUARK, |
92 |
/* compress_motion */ TRUE, |
93 |
/* compress_exposure */ TRUE, |
94 |
/* compress_enterleave */ TRUE, |
95 |
/* visible_interest */ FALSE, |
96 |
/* destroy */ Destroy, |
97 |
/* resize */ Resize, |
98 |
/* expose */ Redisplay, |
99 |
/* set_values */ SetValues, |
100 |
/* set_values_hook */ NULL, |
101 |
/* set_values_almost */ XtInheritSetValuesAlmost, |
102 |
/* get_values_hook */ NULL, |
103 |
/* accept_focus */ NULL, |
104 |
/* version */ XtVersion, |
105 |
/* callback_private */ NULL, |
106 |
/* tm_table */ defaultTranslations, |
107 |
/* query_geometry */ XtInheritQueryGeometry, |
108 |
/* display_accelerator */ XtInheritDisplayAccelerator, |
109 |
/* extension */ NULL |
110 |
}, |
111 |
{ /*** CrList ***/ |
112 |
/* empty */ 0, |
113 |
} |
114 |
}; |
115 |
|
116 |
WidgetClass crListWidgetClass = (WidgetClass)&crListClassRec; |
117 |
|
118 |
/********************************************************************** |
119 |
* privates |
120 |
**********************************************************************/ |
121 |
|
122 |
static void SetSize(Widget w) |
123 |
{ |
124 |
CrListWidget self = (CrListWidget)w; |
125 |
int i = 0; |
126 |
Dimension width,height,rWidth,rHeight; |
127 |
CrListNode node = 0; |
128 |
|
129 |
/*** find out size ***/ |
130 |
if (!self->crList.next) { |
131 |
debug ("No Next function for CrListWidget!\n"); |
132 |
return; |
133 |
} |
134 |
|
135 |
do { |
136 |
node = self->crList.next |
137 |
((XtPointer)self->crList.caller, (XtPointer)node); |
138 |
i++; |
139 |
} while (node); |
140 |
|
141 |
height = --i * FontSize; |
142 |
width = self->core.width; |
143 |
|
144 |
/*** do request from parent container ***/ |
145 |
switch(XtMakeResizeRequest(w,width,height,&rWidth,&rHeight)) { |
146 |
case XtGeometryYes: |
147 |
case XtGeometryNo: |
148 |
break; |
149 |
case XtGeometryAlmost: |
150 |
width = rWidth; |
151 |
height = rHeight; |
152 |
XtMakeResizeRequest(w,width,height,&rWidth,&rHeight); |
153 |
break; |
154 |
default: |
155 |
XtAppWarning(XtWidgetToApplicationContext(w), |
156 |
"CrList: unknown geometry return"); |
157 |
break; |
158 |
} |
159 |
debug3("CrList-%s-Setting size to %dx%d\n", |
160 |
XtName(w), |
161 |
self->core.width, |
162 |
self->core.height); |
163 |
} |
164 |
|
165 |
/* |
166 |
* function: get y's node in list from top |
167 |
* y : index |
168 |
* return : |
169 |
*/ |
170 |
CrListNode GetYNode (Widget w, int y) |
171 |
{ |
172 |
CrListWidget self = (CrListWidget)w; |
173 |
CrListNode node = NULL; |
174 |
int i = 0; |
175 |
|
176 |
if (!self->crList.next) { |
177 |
debug ("No Next function for CrListWidget!\n"); |
178 |
return 0; |
179 |
} |
180 |
|
181 |
node = self->crList.next ((XtPointer)self->crList.caller, (XtPointer)0); |
182 |
for (i = 0; node && i < y; i++) |
183 |
node = self->crList.next |
184 |
((XtPointer)self->crList.caller, (XtPointer)node); |
185 |
|
186 |
return (node); |
187 |
} |
188 |
|
189 |
/* hmm */ |
190 |
CrListCall GetYCall (Widget w, int y) |
191 |
{ |
192 |
CrListNode node = GetYNode (w, y); |
193 |
static struct _CrListCall ret; |
194 |
|
195 |
ret.index = -1; /* empty list */ |
196 |
ret.node = NULL; |
197 |
if (!node) |
198 |
return &ret; |
199 |
ret.index = y; |
200 |
ret.node = node->ptr; |
201 |
return &ret; |
202 |
} |
203 |
|
204 |
/********************************************************************** |
205 |
* actions procedures |
206 |
**********************************************************************/ |
207 |
|
208 |
static void Insert(Widget w,XEvent *e,String *argv,Cardinal *argc) |
209 |
{ |
210 |
CrListWidget self = (CrListWidget)w; |
211 |
CrListCall ret = GetYCall(w, e->xbutton.y / FontSize); |
212 |
|
213 |
if (!self->crList.insertCallbacks) |
214 |
return; |
215 |
debug2("CrList-%s-Insert() %d\n",XtName(w),ret->index); |
216 |
|
217 |
XtCallCallbackList (w,self->crList.insertCallbacks, (XtPointer) ret); |
218 |
SetSize(w); |
219 |
Redisplay(w,e,NULL); |
220 |
} |
221 |
|
222 |
static void Select(Widget new,XEvent *e,String *argv,Cardinal *argc) |
223 |
{ |
224 |
CrListWidget self = (CrListWidget)new; |
225 |
CrListCall ret = GetYCall(new, e->xbutton.y / FontSize); |
226 |
|
227 |
if (ret->index < 0) return; |
228 |
debug1("%s-Select()\n",self->core.name); |
229 |
XtCallCallbackList (new,self->crList.selectCallbacks, (XtPointer) ret); |
230 |
} |
231 |
|
232 |
static void Delete(Widget new,XEvent *e,String *argv,Cardinal *argc) |
233 |
{ |
234 |
CrListWidget self = (CrListWidget)new; |
235 |
CrListCall ret = GetYCall(new, e->xbutton.y / FontSize); |
236 |
|
237 |
if (ret->index < 0 || !self->crList.deleteCallbacks) |
238 |
return; |
239 |
debug2("CrList-%s-Delete() %d\n",XtName(new),ret->index); |
240 |
XtCallCallbackList (new,self->crList.deleteCallbacks, (XtPointer) ret); |
241 |
SetSize(new); |
242 |
Redisplay(new,e,NULL); |
243 |
} |
244 |
|
245 |
/********************************************************************** |
246 |
* members |
247 |
**********************************************************************/ |
248 |
|
249 |
static void ClassInitialize() |
250 |
{ |
251 |
debug0("CrList-ClassInitialize()\n"); |
252 |
} |
253 |
|
254 |
static void Initialize(Widget req,Widget new,Arg args[],Cardinal *num) |
255 |
{ |
256 |
CrListWidget w = (CrListWidget)new; |
257 |
XGCValues values; |
258 |
|
259 |
debug1("CrList-%s-Initialize()\n",XtName(new)); |
260 |
if(w->crList.caller == NULL) |
261 |
CnvDie(new,"Object has no container"); |
262 |
|
263 |
if (!w->core.width) |
264 |
w->core.width++; |
265 |
SetSize(new); |
266 |
w->crList.gc = GCCreate (new); |
267 |
values.font = w->crList.font->fid; |
268 |
values.foreground = w->crList.foreground; |
269 |
w->crList.normal_GC = XtGetGC |
270 |
(new, (unsigned) (GCForeground | GCFont), &values); |
271 |
} |
272 |
|
273 |
static void Destroy(Widget w) |
274 |
{ |
275 |
/* CrListWidget self = (CrListWidget)w; */ |
276 |
debug1("CrList-%s-Destroy()\n",XtName(w)); |
277 |
} |
278 |
|
279 |
static void Resize(Widget w) |
280 |
{ |
281 |
/* CrListWidget self = (CrListWidget)w; */ |
282 |
debug0("Resize()\n"); |
283 |
} |
284 |
|
285 |
|
286 |
static void Redisplay(Widget w,XEvent *event,Region region) |
287 |
{ |
288 |
CrListWidget self = (CrListWidget)w; |
289 |
CrListNode node; |
290 |
int y; |
291 |
XRectangle rect; |
292 |
|
293 |
debug0("CrList-Redisplay()\n"); |
294 |
|
295 |
if (region) { |
296 |
XClipBox(region,&rect); |
297 |
rect.height = rect.height / FontSize + 2; |
298 |
rect.y /= FontSize; |
299 |
XClearArea(XtDisplay(w),XtWindow(w), 0, rect.y * FontSize, |
300 |
0, rect.height * FontSize - 1, False); |
301 |
} else { |
302 |
rect.y = 0; |
303 |
XClearWindow (XtDisplay(w),XtWindow(w)); |
304 |
} |
305 |
node = (CrListNode)GetYNode(w, rect.y); |
306 |
|
307 |
for (y = rect.y; node && (!region || rect.height--); y++) { |
308 |
debug2 ("%s Drawing %s\n", self->core.name,node->name); |
309 |
/*DrawObject(w,0,y,node);*/ |
310 |
DrawFacePart(w, self->crList.gc, node->face, 0, y * FontSize, 0, 0); |
311 |
XDrawString(XtDisplay(w),XtWindow(w), |
312 |
self->crList.normal_GC |
313 |
/*DefaultGCOfScreen(XtScreen(w))*/, |
314 |
FontSize + 8, y * FontSize + 16, |
315 |
node->name,strlen(node->name)); |
316 |
node = self->crList.next |
317 |
((XtPointer)self->crList.caller, (XtPointer)node); |
318 |
} |
319 |
} |
320 |
|
321 |
static Boolean SetValues(Widget cur,Widget req,Widget new, |
322 |
Arg args[],Cardinal *num) |
323 |
{ |
324 |
/* CrListWidget self = (CrListWidget)new; */ |
325 |
debug0("SetValues()\n"); |
326 |
SetSize(new); |
327 |
return True; |
328 |
} |
329 |
|
330 |
/********************************************************************** |
331 |
* public |
332 |
**********************************************************************/ |
333 |
|
334 |
/*** end of CrList.c ***/ |
335 |
|
336 |
|
337 |
|
338 |
|
339 |
|
340 |
|
341 |
|
342 |
|