1 #include "apricot.h"
2 #include "Application.h"
3 #include "Icon.h"
4 #include "Popup.h"
5 #include "Region.h"
6 #include "Widget.h"
7 #include "Window.h"
8 #include <Widget.inc>
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13
14 #undef set_text
15 #undef get_text
16 #undef my
17 #define inherited CDrawable
18 #define enter_method PWidget_vmt selfvmt = ((( PWidget) self)-> self)
19 #define my selfvmt
20 #define var (( PWidget) self)
21
22 typedef Bool ActionProc ( Handle self, Handle item, void * params);
23 typedef ActionProc *PActionProc;
24 #define his (( PWidget) child)
25
26 /* local defines */
27 typedef struct _SingleColor
28 {
29 Color color;
30 int index;
31 } SingleColor, *PSingleColor;
32
33 static Bool find_dup_msg( PEvent event, int * cmd);
34 static Bool pquery ( Handle window, Handle self, void * v);
35 static Bool get_top_current( Handle self);
36 static Bool sptr( Handle window, Handle self, void * v);
37 static Handle find_tabfoc( Handle self);
38 static Bool showhint_notify ( Handle self, Handle child, void * data);
39 static Bool hint_notify ( Handle self, Handle child, SV * hint);
40
41 extern void Widget_pack_slaves( Handle self);
42 extern void Widget_place_slaves( Handle self);
43 extern Bool Widget_size_notify( Handle self, Handle child, const Rect* metrix);
44 extern Bool Widget_move_notify( Handle self, Handle child, Point * moveTo);
45
46 /* init, done & update_sys_handle */
47 void
Widget_init(Handle self,HV * profile)48 Widget_init( Handle self, HV * profile)
49 {
50 dPROFILE;
51 enter_method;
52 SV * sv;
53 int geometry;
54
55 opt_set(optSystemDrawable);
56 inherited-> init( self, profile);
57
58 list_create( &var-> widgets, 0, 8);
59 var-> tabOrder = -1;
60
61 var-> geomInfo. side = 3; /* default pack side is 'top', anchor ='center' */
62 var-> geomInfo. anchorx = var-> geomInfo. anchory = 1;
63
64 my-> update_sys_handle( self, profile);
65 /* props init */
66 /* font and colors */
67 SvHV_Font( pget_sv( font), &Font_buffer, "Widget::init");
68 my-> set_widgetClass ( self, pget_i( widgetClass ));
69 my-> set_color ( self, pget_i( color ));
70 my-> set_backColor ( self, pget_i( backColor ));
71 my-> set_font ( self, Font_buffer);
72 opt_assign( optOwnerBackColor, pget_B( ownerBackColor));
73 opt_assign( optOwnerColor , pget_B( ownerColor));
74 opt_assign( optOwnerFont , pget_B( ownerFont));
75 opt_assign( optOwnerHint , pget_B( ownerHint));
76 opt_assign( optOwnerShowHint , pget_B( ownerShowHint));
77 opt_assign( optOwnerPalette , pget_B( ownerPalette));
78 my-> colorIndex( self, true, ciHiliteText, pget_i( hiliteColor) );
79 my-> colorIndex( self, true, ciHilite, pget_i( hiliteBackColor) );
80 my-> colorIndex( self, true, ciDisabledText, pget_i( disabledColor) );
81 my-> colorIndex( self, true, ciDisabled, pget_i( disabledBackColor));
82 my-> colorIndex( self, true, ciLight3DColor, pget_i( light3DColor) );
83 my-> colorIndex( self, true, ciDark3DColor, pget_i( dark3DColor) );
84 my-> set_palette( self, pget_sv( palette));
85
86 /* light props */
87 my-> set_autoEnableChildren ( self, pget_B( autoEnableChildren));
88 my-> set_briefKeys ( self, pget_B( briefKeys));
89 my-> set_buffered ( self, pget_B( buffered));
90 my-> set_clipChildren ( self, pget_B( clipChildren));
91 my-> set_cursorVisible ( self, pget_B( cursorVisible));
92 my-> set_dndAware ( self, pget_sv( dndAware));
93 my-> set_growMode ( self, pget_i( growMode));
94 my-> set_helpContext ( self, pget_sv( helpContext));
95 my-> set_hint ( self, pget_sv( hint));
96 my-> set_firstClick ( self, pget_B( firstClick));
97 {
98 Point hotSpot;
99 Handle icon = pget_H( pointerIcon);
100 prima_read_point( pget_sv( pointerHotSpot), (int*)&hotSpot, 2, "Array panic on 'pointerHotSpot'");
101 if ( icon != NULL_HANDLE && !kind_of( icon, CIcon)) {
102 warn("Illegal object reference passed to Widget::pointerIcon");
103 icon = NULL_HANDLE;
104 }
105 apc_pointer_set_user( self, icon, hotSpot);
106 }
107 my-> set_pointerType ( self, pget_i( pointerType));
108 my-> set_selectingButtons ( self, pget_i( selectingButtons));
109 my-> set_selectable ( self, pget_B( selectable));
110 my-> set_showHint ( self, pget_B( showHint));
111 my-> set_tabOrder ( self, pget_i( tabOrder));
112 my-> set_tabStop ( self, pget_B( tabStop));
113 my-> set_text ( self, pget_sv( text));
114
115 opt_assign( optScaleChildren, pget_B( scaleChildren));
116
117 /* subcomponents props */
118 my-> popupColorIndex( self, true, ciFore, pget_i( popupColor) );
119 my-> popupColorIndex( self, true, ciBack, pget_i( popupBackColor) );
120 my-> popupColorIndex( self, true, ciHiliteText, pget_i( popupHiliteColor) );
121 my-> popupColorIndex( self, true, ciHilite, pget_i( popupHiliteBackColor) );
122 my-> popupColorIndex( self, true, ciDisabledText, pget_i( popupDisabledColor) );
123 my-> popupColorIndex( self, true, ciDisabled, pget_i( popupDisabledBackColor) );
124 my-> popupColorIndex( self, true, ciLight3DColor, pget_i( popupLight3DColor) );
125 my-> popupColorIndex( self, true, ciDark3DColor, pget_i( popupDark3DColor) );
126 SvHV_Font( pget_sv( popupFont), &Font_buffer, "Widget::init");
127 my-> set_popup_font ( self, Font_buffer);
128 if ( SvTYPE( sv = pget_sv( popupItems)) != SVt_NULL)
129 my-> set_popupItems( self, sv);
130 if ( SvTYPE( sv = pget_sv( accelItems)) != SVt_NULL)
131 my-> set_accelItems( self, sv);
132
133 /* size, position, enabling, visibliity etc. runtime */
134 {
135 Point set, set2;
136 AV * av;
137 SV ** holder;
138 NPoint ds = {1,1};
139
140 prima_read_point( pget_sv( sizeMin), (int*)&set, 2, "Array panic on 'sizeMin'");
141 prima_read_point( pget_sv( sizeMax), (int*)&set2, 2, "Array panic on 'sizeMax'");
142 var-> sizeMax = set2;
143 my-> set_sizeMin( self, set);
144 my-> set_sizeMax( self, set2);
145 prima_read_point( pget_sv( cursorSize), (int*)&set, 2, "Array panic on 'cursorSize'");
146 my-> set_cursorSize( self, set);
147 prima_read_point( pget_sv( cursorPos), (int*)&set, 2, "Array panic on 'cursorPos'");
148 my-> set_cursorPos( self, set);
149
150 av = ( AV *) SvRV( pget_sv( designScale));
151 holder = av_fetch( av, 0, 0);
152 ds. x = holder ? SvNV( *holder) : 1;
153 if ( !holder) warn("Array panic on 'designScale'");
154 holder = av_fetch( av, 1, 0);
155 ds. y = holder ? SvNV( *holder) : 1;
156 if ( !holder) warn("Array panic on 'designScale'");
157 my-> set_designScale( self, ds);
158 }
159 my-> set_enabled ( self, pget_B( enabled));
160 if ( !pexist( originDontCare) || !pget_B( originDontCare)) {
161 Point pos;
162 pos. x = pget_i( left);
163 pos. y = pget_i( bottom);
164 my-> set_origin( self, pos);
165 } else
166 var-> pos = my-> get_origin( self);
167
168 if ( !pexist( sizeDontCare ) || !pget_B( sizeDontCare )) {
169 Point size;
170 size. x = pget_i( width);
171 size. y = pget_i( height);
172 my-> set_size( self, size);
173 } else
174 var-> virtualSize = my-> get_size( self);
175 var-> geomSize = var-> virtualSize;
176
177 geometry = pget_i(geometry);
178 if ( geometry == gtGrowMode ) {
179 Bool x = 0, y = 0;
180 if ( pget_B( centered)) { x = 1; y = 1; };
181 if ( pget_B( x_centered) || ( var-> growMode & gmXCenter)) x = 1;
182 if ( pget_B( y_centered) || ( var-> growMode & gmYCenter)) y = 1;
183 if ( x || y) my-> set_centered( self, x, y);
184 var-> geomInfo. x = x;
185 var-> geomInfo. y = y;
186 }
187
188 opt_assign( optPackPropagate, pget_B( packPropagate));
189 my-> set_packInfo( self, pget_sv( packInfo));
190 my-> set_placeInfo( self, pget_sv( placeInfo));
191 my-> set_geometry( self, geometry);
192
193 my-> set_shape ( self, pget_H( shape));
194 my-> set_visible ( self, pget_B( visible));
195 if ( pget_B( capture)) my-> set_capture( self, 1, NULL_HANDLE);
196 if ( pget_B( current)) my-> set_current( self, 1);
197 CORE_INIT_TRANSIENT(Widget);
198
199 {
200 SV * widgets = pget_sv( widgets);
201 if ( SvTYPE( widgets) != SVt_NULL) {
202 dSP;
203 ENTER;
204 SAVETMPS;
205 PUSHMARK( sp);
206 XPUSHs( var-> mate);
207 XPUSHs( sv_2mortal( newSVsv( widgets)));
208 PUTBACK;
209 perl_call_method( "widgets", G_DISCARD);
210 SPAGAIN;
211 PUTBACK;
212 FREETMPS;
213 LEAVE;
214 }
215 }
216 }
217
218 void
Widget_update_sys_handle(Handle self,HV * profile)219 Widget_update_sys_handle( Handle self, HV * profile)
220 {
221 dPROFILE;
222 enter_method;
223 Handle owner;
224 Bool clipOwner, layered, syncPaint, transparent;
225 ApiHandle parentHandle;
226 if (!(
227 pexist( owner) ||
228 pexist( syncPaint) ||
229 pexist( clipOwner) ||
230 pexist( layered) ||
231 pexist( transparent)
232 )) return;
233
234 owner = pexist( owner) ? pget_H( owner) : var-> owner;
235 clipOwner = pexist( clipOwner) ? pget_B( clipOwner) : my-> get_clipOwner( self);
236 parentHandle = pexist( parentHandle) ? pget_i( parentHandle) : apc_widget_get_parent_handle( self);
237 layered = pexist( layered) ? pget_B( layered) : my-> get_layered(self);
238 syncPaint = pexist( syncPaint) ? pget_B( syncPaint) : my-> get_syncPaint( self);
239 transparent = pexist( transparent) ? pget_B( transparent) : my-> get_transparent( self);
240
241 if ( parentHandle) {
242 if (( owner != application) && clipOwner)
243 croak("Cannot accept 'parentHandle' for non-application child and clip-owner widget");
244 }
245
246 if ( !apc_widget_create( self, owner, syncPaint, clipOwner, transparent, parentHandle, layered))
247 croak( "Cannot create widget");
248
249 pdelete( transparent);
250 pdelete( syncPaint);
251 pdelete( clipOwner);
252 pdelete( parentHandle);
253 pdelete( layered);
254 }
255
256 void
Widget_done(Handle self)257 Widget_done( Handle self)
258 {
259 if ( var-> dndAware != NULL ) {
260 free( var-> dndAware );
261 var-> dndAware = NULL;
262 }
263 if ( var-> text ) sv_free( var->text);
264 var-> text = NULL;
265 apc_widget_destroy( self);
266 if ( var-> hint ) sv_free( var->hint);
267 var-> hint = NULL;
268 free( var-> helpContext);
269 var-> helpContext = NULL;
270
271 if ( var-> owner) {
272 Handle * enum_lists = PWidget( var-> owner)-> enum_lists;
273 while ( enum_lists) {
274 unsigned int i, count;
275 count = (unsigned int) enum_lists[1];
276 for ( i = 2; i < count + 2; i++) {
277 if ( self == enum_lists[i])
278 enum_lists[i] = NULL_HANDLE;
279 }
280 enum_lists = ( Handle*) enum_lists[0];
281 }
282 }
283
284 list_destroy( &var-> widgets);
285 inherited-> done( self);
286 }
287
288 /* ::a */
289 void
Widget_attach(Handle self,Handle objectHandle)290 Widget_attach( Handle self, Handle objectHandle)
291 {
292 if ( objectHandle == NULL_HANDLE) return;
293 if ( var-> stage > csNormal) return;
294 if ( kind_of( objectHandle, CWidget)) {
295 if ( list_index_of( &var-> widgets, objectHandle) >= 0) {
296 warn( "Object attach failed");
297 return;
298 }
299 list_add( &var-> widgets, objectHandle);
300 }
301 inherited-> attach( self, objectHandle);
302 }
303
304 /*::b */
305 Bool
Widget_begin_paint(Handle self)306 Widget_begin_paint( Handle self)
307 {
308 Bool ok;
309 if ( !inherited-> begin_paint( self))
310 return false;
311 if ( !( ok = apc_widget_begin_paint( self, false))) {
312 inherited-> end_paint( self);
313 perl_error();
314 }
315 return ok;
316 }
317
318 Bool
Widget_begin_paint_info(Handle self)319 Widget_begin_paint_info( Handle self)
320 {
321 Bool ok;
322 if ( is_opt( optInDraw)) return true;
323 if ( !inherited-> begin_paint_info( self))
324 return false;
325 if ( !( ok = apc_widget_begin_paint_info( self))) {
326 inherited-> end_paint_info( self);
327 perl_error();
328 }
329 return ok;
330 }
331
332
333 void
Widget_bring_to_front(Handle self)334 Widget_bring_to_front( Handle self)
335 {
336 if ( opt_InPaint) return;
337 apc_widget_set_z_order( self, NULL_HANDLE, true);
338 }
339
340 /*::c */
341 Bool
Widget_can_close(Handle self)342 Widget_can_close( Handle self)
343 {
344 enter_method;
345 Event ev = { cmClose};
346 return ( var-> stage <= csNormal) ? my-> message( self, &ev) : true;
347 }
348
349 Bool
Widget_can_propagate_key(Handle self)350 Widget_can_propagate_key( Handle self)
351 {
352 return true;
353 }
354
355 void
Widget_cleanup(Handle self)356 Widget_cleanup( Handle self)
357 {
358 Handle ptr;
359 enter_method;
360
361 /* disconnect all geometry slaves */
362 ptr = var-> packSlaves;
363 while ( ptr) {
364 PWidget( ptr)-> geometry = gtDefault;
365 ptr = PWidget( ptr)-> geomInfo. next;
366 }
367 var-> packSlaves = NULL_HANDLE;
368 ptr = var-> placeSlaves;
369 while ( ptr) {
370 PWidget( ptr)-> geometry = gtDefault;
371 ptr = PWidget( ptr)-> geomInfo. next;
372 }
373 var-> placeSlaves = NULL_HANDLE;
374
375 my-> set_geometry( self, gtDefault);
376
377 if ( application && (( PApplication) application)-> hintUnder == self)
378 my-> set_hintVisible( self, 0);
379
380 {
381 int i;
382 for ( i = 0; i < var-> widgets. count; i++)
383 Object_destroy( var-> widgets. items[i]);
384 }
385
386 if ( var-> accelTable) {
387 unprotect_object(var-> accelTable);
388 //my-> detach( self, var-> accelTable, true);
389 var-> accelTable = NULL_HANDLE;
390 }
391
392 if ( var-> popupMenu ) {
393 unprotect_object(var-> popupMenu);
394 //my-> detach( self, var-> popupMenu, true);
395 var-> popupMenu = NULL_HANDLE;
396 }
397
398 inherited-> cleanup( self);
399 }
400
401
402 Bool
Widget_close(Handle self)403 Widget_close( Handle self)
404 {
405 Bool canClose;
406 enter_method;
407 if ( var-> stage > csNormal) return true;
408 if (( canClose = my-> can_close( self))) {
409 Object_destroy( self);
410 }
411 return canClose;
412 }
413
414 Bool
Widget_custom_paint(Handle self)415 Widget_custom_paint( Handle self)
416 {
417 PList list;
418 void * ret;
419 enter_method;
420 if ( my-> on_paint != Widget_on_paint) return true;
421 if ( var-> eventIDs == NULL) return false;
422 ret = hash_fetch( var-> eventIDs, "Paint", 5);
423 if ( ret == NULL) return false;
424 list = var-> events + PTR2UV( ret) - 1;
425 return list-> count > 0;
426 }
427
428 /*::d */
429 void
Widget_detach(Handle self,Handle objectHandle,Bool kill)430 Widget_detach( Handle self, Handle objectHandle, Bool kill)
431 {
432 enter_method;
433 if ( kind_of( objectHandle, CWidget)) {
434 list_delete( &var-> widgets, objectHandle);
435 if ( var-> currentWidget == objectHandle && objectHandle != NULL_HANDLE)
436 my-> set_currentWidget( self, NULL_HANDLE);
437 }
438 inherited-> detach( self, objectHandle, kill);
439 }
440
441 DNDResp
Widget_dnd_start(Handle self,int dnd_actions,Bool default_pointers)442 Widget_dnd_start(Handle self, int dnd_actions, Bool default_pointers)
443 {
444 DNDResp ret;
445 ret.action = apc_dnd_start( self, dnd_actions, default_pointers, &ret.counterpart);
446 return ret;
447 }
448
449 /*::e */
450 void
Widget_end_paint(Handle self)451 Widget_end_paint( Handle self)
452 {
453 if ( !is_opt( optInDraw)) return;
454 apc_widget_end_paint( self);
455 inherited-> end_paint( self);
456 }
457
458 void
Widget_end_paint_info(Handle self)459 Widget_end_paint_info( Handle self)
460 {
461 if ( !is_opt( optInDrawInfo)) return;
462 apc_widget_end_paint_info( self);
463 inherited-> end_paint_info( self);
464 }
465
466
467 /*::f */
468
469 SV*
Widget_fetch_resource(char * className,char * name,char * classRes,char * res,Handle owner,int resType)470 Widget_fetch_resource( char *className, char *name, char *classRes, char *res, Handle owner, int resType)
471 {
472 char *str = NULL;
473 Color clr;
474 void *parm;
475 Font font;
476 SV * ret = NULL_SV;
477 char *r_className, *r_name, *r_classRes, *r_res;
478
479 switch ( resType) {
480 case frColor:
481 parm = &clr; break;
482 case frFont:
483 parm = &font;
484 bzero( &font, sizeof( font));
485 break;
486 default:
487 parm = &str;
488 resType = frString;
489 }
490
491 r_className = duplicate_string(className);
492 r_name = duplicate_string(name);
493 r_classRes = duplicate_string(classRes);
494 r_res = duplicate_string(res);
495
496 if ( !apc_fetch_resource(
497 prima_normalize_resource_string( r_className, true),
498 prima_normalize_resource_string( r_name, false),
499 prima_normalize_resource_string( r_classRes, true),
500 prima_normalize_resource_string( r_res, false),
501 owner, resType, parm))
502 goto FAIL;
503
504 switch ( resType) {
505 case frColor:
506 ret = newSViv( clr);
507 break;
508 case frFont:
509 ret = sv_Font2HV( &font);
510 break;
511 default:
512 ret = str ? newSVpv( str, 0) : NULL_SV;
513 free( str);
514 }
515
516 FAIL:
517 free(r_className);
518 free(r_name);
519 free(r_classRes);
520 free(r_res);
521
522 return ret;
523 }
524
525 Handle
Widget_first(Handle self)526 Widget_first( Handle self)
527 {
528 return apc_widget_get_z_order( self, zoFirst);
529 }
530
531 Handle
Widget_first_that(Handle self,void * actionProc,void * params)532 Widget_first_that( Handle self, void * actionProc, void * params)
533 {
534 Handle child = NULL_HANDLE;
535 int i, count = var-> widgets. count;
536 Handle * list;
537 if ( actionProc == NULL || count == 0) return NULL_HANDLE;
538 if (!(list = allocn( Handle, count + 2))) return NULL_HANDLE;
539
540 list[0] = (Handle)( var-> enum_lists);
541 list[1] = (Handle)( count);
542 var-> enum_lists = list;
543 memcpy( list + 2, var-> widgets. items, sizeof( Handle) * count);
544
545 for ( i = 2; i < count + 2; i++)
546 {
547 if ( list[i] && (( PActionProc) actionProc)( self, list[ i], params))
548 {
549 child = list[ i];
550 break;
551 }
552 }
553 var-> enum_lists = (Handle*)(*list);
554 free( list);
555 return child;
556 }
557
558 /*::g */
559
560 /*::h */
561
562 #define evOK ( var-> evStack[ var-> evPtr - 1])
563 #define objCheck if ( var-> stage > csNormal) return
564
565 static Bool
dnd_event_wanted(Handle self,PEvent event)566 dnd_event_wanted(Handle self, PEvent event)
567 {
568 Bool r;
569 SV * ret;
570 if ( var-> dndAware == NULL) return false;
571 if ( strcmp(var->dndAware, "1") == 0) return true;
572 ENTER;
573 SAVETMPS;
574 ret = call_perl( event->dnd.clipboard, "has_format", "<s", var->dndAware);
575 r = ret ? SvTRUE( ret) : false;
576 FREETMPS;
577 LEAVE;
578 return r;
579 }
580
581 static void
handle_drag_begin(Handle self,PEvent event)582 handle_drag_begin( Handle self, PEvent event)
583 {
584 enter_method;
585 if ( !dnd_event_wanted(self, event)) {
586 opt_clear(optDropSession);
587 return;
588 }
589 opt_set(optDropSession);
590 my-> notify( self, "<sHiiPH", "DragBegin",
591 event-> dnd. clipboard,
592 event-> dnd. action,
593 event-> dnd. modmap,
594 event-> dnd. where,
595 event-> dnd. counterpart
596 );
597 }
598
599 static void
handle_drag_over(Handle self,PEvent event)600 handle_drag_over( Handle self, PEvent event)
601 {
602 dPROFILE;
603 enter_method;
604 HV * profile;
605 SV * ref;
606
607 if ( !is_opt(optDropSession)) {
608 Point size = apc_widget_get_size(self);
609 event-> dnd.allow = 0;
610 event-> dnd.pad.x = event-> dnd.pad.y = 0;
611 event-> dnd.pad.width = size.x;
612 event-> dnd.pad.height = size.y;
613 return;
614 }
615
616 profile = newHV();
617 ref = newRV_noinc((SV*) profile);
618
619 pset_i(allow,1);
620 pset_i(action,dndCopy);
621 my-> notify( self, "<sHiiPHS", "DragOver",
622 event-> dnd. clipboard,
623 event-> dnd. action,
624 event-> dnd. modmap,
625 event-> dnd. where,
626 event-> dnd. counterpart,
627 ref
628 );
629
630 event-> dnd. allow = pexist(allow) ? pget_i(allow) : 1;
631 event-> dnd. action = pexist(action) ? pget_i(action) : dndCopy;
632 memset( &event-> dnd.pad, 0, sizeof(Rect));
633 if ( pexist(pad)) {
634 int rect[4];
635 prima_read_point( pget_sv(pad), rect, 4, "Array panic on 'pad'");
636 event->dnd.pad.x = rect[0];
637 event->dnd.pad.y = rect[1];
638 event->dnd.pad.width = rect[2];
639 event->dnd.pad.height = rect[3];
640 }
641
642 sv_free(ref);
643 }
644
645 static void
handle_drag_end(Handle self,PEvent event)646 handle_drag_end( Handle self, PEvent event)
647 {
648 dPROFILE;
649 enter_method;
650 HV * profile;
651 SV * ref;
652
653 if ( !is_opt(optDropSession)) {
654 event-> dnd. allow = 0;
655 return;
656 }
657 opt_clear(optDropSession);
658
659 profile = newHV();
660 ref = newRV_noinc((SV*) profile);
661
662 pset_i(allow, 1);
663 pset_i(action, event->dnd.action);
664 my-> notify( self, "<sHiiPHS", "DragEnd",
665 event-> dnd. allow ? event-> dnd.clipboard : NULL_HANDLE,
666 event-> dnd. action,
667 event-> dnd. modmap,
668 event-> dnd. where,
669 event-> dnd. counterpart,
670 ref
671 );
672 event-> dnd. allow = pexist(allow) ? pget_i(allow) : 1;
673 event-> dnd. action = pexist(action) ? pget_i(action) : dndCopy;
674
675 sv_free(ref);
676 }
677
678 static void
handle_drag_query(Handle self,PEvent event)679 handle_drag_query( Handle self, PEvent event)
680 {
681 dPROFILE;
682 enter_method;
683 HV * profile = newHV();
684 SV * ref = newRV_noinc((SV*) profile);
685 pset_i(allow, event->dnd.allow);
686 my-> notify( self, "<siHS", "DragQuery", event->dnd.modmap, event->dnd.counterpart, ref);
687 if (pexist(allow))
688 event-> dnd.allow = pget_i(allow);
689 event-> dnd.action = pexist(action) ? pget_i(action) : 0;
690 sv_free(ref);
691 }
692
693 static void
handle_key_down(Handle self,PEvent event)694 handle_key_down( Handle self, PEvent event)
695 {
696 enter_method;
697 int i;
698 int rep = event-> key. repeat;
699 Handle next = NULL_HANDLE;
700 if ( is_opt( optBriefKeys))
701 rep = 1;
702 else
703 event-> key. repeat = 1;
704 for ( i = 0; i < rep; i++) {
705 my-> notify( self, "<siiii", "KeyDown",
706 event-> key.code, event-> key. key, event-> key. mod, event-> key. repeat);
707 objCheck;
708 if ( evOK) {
709 Event ev = *event;
710 ev. key. source = self;
711 ev. cmd = var-> owner ? cmDelegateKey : cmTranslateAccel;
712 ev. key. subcmd = 0;
713 if ( !my-> message( self, &ev)) {
714 my-> clear_event( self);
715 return;
716 }
717 objCheck;
718 }
719 if ( !evOK) break;
720
721 switch( event-> key. key) {
722 case kbF1:
723 case kbHelp:
724 my-> help( self);
725 my-> clear_event( self);
726 return;
727 case kbLeft:
728 next = my-> next_positional( self, -1, 0);
729 break;
730 case kbRight:
731 next = my-> next_positional( self, 1, 0);
732 break;
733 case kbUp:
734 next = my-> next_positional( self, 0, 1);
735 break;
736 case kbDown:
737 next = my-> next_positional( self, 0, -1);
738 break;
739 case kbTab:
740 next = my-> next_tab( self, true);
741 break;
742 case kbBackTab:
743 next = my-> next_tab( self, false);
744 break;
745 default:;
746 }
747 if ( next) {
748 CWidget( next)-> set_selected( next, true);
749 objCheck;
750 my-> clear_event( self);
751 return;
752 }
753 }
754 }
755
756 static void
handle_delegate_key(Handle self,PEvent event)757 handle_delegate_key( Handle self, PEvent event)
758 {
759 enter_method;
760 switch ( event-> key. subcmd) {
761 case 0: {
762 Event ev = *event;
763 ev. cmd = cmTranslateAccel;
764 if ( !my-> message( self, &ev)) {
765 my-> clear_event( self);
766 return;
767 }
768 objCheck;
769
770 if ( my-> first_that( self, (void*)prima_accel_notify, &ev)) {
771 my-> clear_event( self);
772 return;
773 }
774 objCheck;
775 ev. cmd = cmDelegateKey;
776 ev. key. subcmd = 1;
777 if ( my-> first_that( self, (void*)prima_accel_notify, &ev)) {
778 my-> clear_event( self);
779 return;
780 }
781 if ( var-> owner && my->can_propagate_key(self))
782 {
783 if ( var-> owner == application)
784 ev. cmd = cmTranslateAccel;
785 else
786 ev. key. subcmd = 0;
787 ev. key. source = self;
788 if (!(((( PWidget) var-> owner)-> self)-> message( var-> owner, &ev))) {
789 objCheck;
790 my-> clear_event( self);
791 return;
792 }
793 }
794 }
795 break;
796 case 1: {
797 Event ev = *event;
798 ev. cmd = cmTranslateAccel;
799 if ( my-> first_that( self, (void*)prima_accel_notify, &ev)) {
800 my-> clear_event( self);
801 return;
802 }
803 objCheck;
804 ev = *event;
805 if ( my-> first_that( self, (void*)prima_accel_notify, &ev)) {
806 my-> clear_event( self);
807 return;
808 }
809 }
810 break;
811 }
812 }
813
814 static void
handle_move(Handle self,PEvent event)815 handle_move( Handle self, PEvent event)
816 {
817 enter_method;
818 Bool doNotify = false;
819 Point oldP;
820 if ( var-> stage == csNormal && var-> evQueue == NULL) {
821 doNotify = true;
822 } else if ( var-> stage > csNormal) {
823 return;
824 } else if ( var-> evQueue != NULL) {
825 int i = list_first_that( var-> evQueue, (void*)find_dup_msg, &event-> cmd);
826 PEvent n;
827 if ( i < 0) {
828 if ( !( n = alloc1( Event))) goto MOVE_EVENT;
829 memcpy( n, event, sizeof( Event));
830 n-> gen. B = 1;
831 n-> gen. R. left = n-> gen. R. bottom = 0;
832 list_add( var-> evQueue, ( Handle) n);
833 } else
834 n = ( PEvent) list_at( var-> evQueue, i);
835 n-> gen. P = event-> gen. P;
836 }
837 MOVE_EVENT:;
838 if ( !event-> gen. B)
839 my-> first_that( self, (void*) Widget_move_notify, &event-> gen. P);
840 if ( doNotify) oldP = var-> pos;
841 var-> pos = event-> gen. P;
842 if ( doNotify &&
843 (oldP. x != event-> gen. P. x ||
844 oldP. y != event-> gen. P. y)) {
845 my-> notify( self, "<sPP", "Move", oldP, event-> gen. P);
846 objCheck;
847 if ( var->geometry == gtGrowMode && var-> growMode & gmCenter)
848 my-> set_centered( self, var-> growMode & gmXCenter, var-> growMode & gmYCenter);
849 }
850 }
851
852 static void
handle_popup(Handle self,PEvent event)853 handle_popup( Handle self, PEvent event)
854 {
855 enter_method;
856 Handle org = self;
857 my-> notify( self, "<siP", "Popup", event-> gen. B, event-> gen. P. x, event-> gen. P. y);
858 objCheck;
859 if ( evOK) {
860 while ( self) {
861 PPopup p = ( PPopup) CWidget( self)-> get_popup( self);
862 if ( p && p-> self-> get_autoPopup(( Handle) p)) {
863 Point px = event-> gen. P;
864 apc_widget_map_points( org, true, 1, &px);
865 apc_widget_map_points( self, false, 1, &px);
866 p-> self-> popup(( Handle) p, px. x, px. y ,0,0,0,0);
867 CWidget( org)-> clear_event( org);
868 return;
869 }
870 self = var-> owner;
871 }
872 }
873 }
874
875 static void
handle_size(Handle self,PEvent event)876 handle_size( Handle self, PEvent event)
877 {
878 enter_method;
879 /* expecting new size in P, old & new size in R. */
880 Bool doNotify = false;
881 if ( var-> stage == csNormal && var-> evQueue == NULL) {
882 doNotify = true;
883 } else if ( var-> stage > csNormal) {
884 return;
885 } else if ( var-> evQueue != NULL) {
886 int i = list_first_that( var-> evQueue, (void*)find_dup_msg, &event-> cmd);
887 PEvent n;
888 if ( i < 0) {
889 if ( !( n = alloc1( Event))) goto SIZE_EVENT;
890 memcpy( n, event, sizeof( Event));
891 n-> gen. B = 1;
892 n-> gen. R. left = n-> gen. R. bottom = 0;
893 list_add( var-> evQueue, ( Handle) n);
894 } else
895 n = ( PEvent) list_at( var-> evQueue, i);
896 n-> gen. P. x = n-> gen. R. right = event-> gen. P. x;
897 n-> gen. P. y = n-> gen. R. top = event-> gen. P. y;
898 }
899 SIZE_EVENT:;
900 if ( var->geometry == gtGrowMode && var-> growMode & gmCenter)
901 my-> set_centered( self, var-> growMode & gmXCenter, var-> growMode & gmYCenter);
902 if ( !event-> gen. B)
903 my-> first_that( self, (void*) Widget_size_notify, &event-> gen. R);
904 if ( doNotify) {
905 Point oldSize;
906 oldSize. x = event-> gen. R. left;
907 oldSize. y = event-> gen. R. bottom;
908 my-> notify( self, "<sPP", "Size", oldSize, event-> gen. P);
909 }
910 Widget_pack_slaves( self);
911 Widget_place_slaves( self) ;
912 }
913
Widget_handle_event(Handle self,PEvent event)914 void Widget_handle_event( Handle self, PEvent event)
915 {
916 enter_method;
917 inherited-> handle_event ( self, event);
918 objCheck;
919 switch ( event-> cmd)
920 {
921 case cmCalcBounds:
922 {
923 Point min, max;
924 min = var-> sizeMin;
925 max = var-> sizeMax;
926 if (( min. x > 0) && ( min. x > event-> gen. R. right )) event-> gen. R. right = min. x;
927 if (( min. y > 0) && ( min. y > event-> gen. R. top )) event-> gen. R. top = min. y;
928 if (( max. x > 0) && ( max. x < event-> gen. R. right )) event-> gen. R. right = max. x;
929 if (( max. y > 0) && ( max. y < event-> gen. R. top )) event-> gen. R. top = max. y;
930 }
931 break;
932 case cmSetup:
933 if ( !is_opt( optSetupComplete)) {
934 opt_set( optSetupComplete);
935 my-> notify( self, "<s", "Setup");
936 }
937 break;
938 case cmRepaint:
939 my-> repaint( self);
940 break;
941 case cmPaint :
942 if ( !opt_InPaint && !my-> get_locked( self))
943 if ( inherited-> begin_paint( self)) {
944 if ( apc_widget_begin_paint( self, true)) {
945 Bool flag = exception_block(true);
946 my-> notify( self, "<sH", "Paint", self);
947 exception_block(flag);
948 if ( var-> stage == csNormal ) apc_widget_end_paint( self);
949 EXCEPTION_CHECK_RAISE;
950 objCheck;
951 inherited-> end_paint( self);
952 } else
953 inherited-> end_paint( self);
954 }
955 break;
956 case cmEnable :
957 my-> notify( self, "<s", "Enable");
958 break;
959 case cmDisable :
960 my-> notify( self, "<s", "Disable");
961 break;
962 case cmReceiveFocus :
963 my-> notify( self, "<s", "Enter");
964 break;
965 case cmReleaseFocus :
966 my-> notify( self, "<s", "Leave");
967 break;
968 case cmShow :
969 my-> notify( self, "<s", "Show");
970 break;
971 case cmHide :
972 my-> notify( self, "<s", "Hide");
973 break;
974 case cmHint:
975 my-> notify( self, "<si", "Hint", event-> gen. B);
976 break;
977 case cmClose :
978 if ( my-> first_that( self, (void*)pquery, NULL)) {
979 my-> clear_event( self);
980 return;
981 }
982 objCheck;
983 my-> notify( self, "<s", "Close");
984 break;
985 case cmZOrderChanged:
986 my-> notify( self, "<s", "ZOrderChanged");
987 break;
988 case cmClick:
989 my-> notify( self, "<s", "Click");
990 break;
991 case cmColorChanged:
992 if ( !kind_of( event-> gen. source, CPopup))
993 my-> notify( self, "<si", "ColorChanged", event-> gen. i);
994 else
995 var-> popupColor[ event-> gen. i] =
996 apc_menu_get_color( event-> gen. source, event-> gen. i);
997 break;
998 case cmFontChanged:
999 if ( !kind_of( event-> gen. source, CPopup))
1000 my-> notify( self, "<s", "FontChanged");
1001 else
1002 apc_menu_get_font( event-> gen. source, &var-> popupFont);
1003 break;
1004 case cmMenu:
1005 if ( event-> gen. H) {
1006 char buffer[16], *context;
1007 context = ((( PAbstractMenu) event-> gen. H)-> self)-> make_id_context( event-> gen. H, event-> gen. i, buffer);
1008 my-> notify( self, "<sHs", "Menu", event-> gen. H, context);
1009 }
1010 break;
1011 case cmMouseClick:
1012 my-> notify( self, "<siiPi", "MouseClick",
1013 event-> pos. button, event-> pos. mod, event-> pos. where, event-> pos. dblclk);
1014 break;
1015 case cmMouseDown:
1016 if ((( PApplication) application)-> hintUnder == self)
1017 my-> set_hintVisible( self, 0);
1018 objCheck;
1019 if (((event-> pos. button & var-> selectingButtons) != 0) && my-> get_selectable( self))
1020 my-> set_selected( self, true);
1021 objCheck;
1022 my-> notify( self, "<siiP", "MouseDown",
1023 event-> pos. button, event-> pos. mod, event-> pos. where);
1024 break;
1025 case cmMouseUp:
1026 my-> notify( self, "<siiP", "MouseUp",
1027 event-> pos. button, event-> pos. mod, event-> pos. where);
1028 break;
1029 case cmMouseMove:
1030 if ((( PApplication) application)-> hintUnder == self)
1031 my-> set_hintVisible( self, -1);
1032 objCheck;
1033 my-> notify( self, "<siP", "MouseMove", event-> pos. mod, event -> pos. where);
1034 break;
1035 case cmMouseWheel:
1036 my-> notify( self, "<siPi", "MouseWheel",
1037 event-> pos. mod, event -> pos. where,
1038 event-> pos. button); /* +n*delta == up, -n*delta == down */
1039 break;
1040 case cmMouseEnter:
1041 my-> notify( self, "<siP", "MouseEnter", event-> pos. mod, event -> pos. where);
1042 objCheck;
1043 if ( application && is_opt( optShowHint) && ((( PApplication) application)-> options. optShowHint) && var-> hint && SvCUR(var-> hint))
1044 {
1045 PApplication app = ( PApplication) application;
1046 app-> self-> set_hint_action( application, self, true, true);
1047 }
1048 break;
1049 case cmMouseLeave:
1050 if ( application && is_opt( optShowHint)) {
1051 PApplication app = ( PApplication) application;
1052 app-> self-> set_hint_action( application, self, false, true);
1053 }
1054 my-> notify( self, "<s", "MouseLeave");
1055 break;
1056 case cmKeyDown:
1057 handle_key_down(self, event);
1058 break;
1059 case cmDelegateKey:
1060 handle_delegate_key( self, event );
1061 break;
1062 case cmTranslateAccel:
1063 {
1064 int key = CAbstractMenu-> translate_key( NULL_HANDLE, event-> key. code, event-> key. key, event-> key. mod);
1065 if ( my-> first_that_component( self, (void*)prima_find_accel, &key)) {
1066 my-> clear_event( self);
1067 return;
1068 }
1069 objCheck;
1070 my-> notify( self, "<siii", "TranslateAccel",
1071 event-> key.code, event-> key. key, event-> key. mod);
1072 break;
1073 }
1074 case cmKeyUp:
1075 my-> notify( self, "<siii", "KeyUp",
1076 event-> key.code, event-> key. key, event-> key. mod);
1077 break;
1078 case cmMenuCmd:
1079 if ( event-> gen. source)
1080 ((( PAbstractMenu) event-> gen. source)-> self)->
1081 sub_call_id( event-> gen. source, event-> gen. i);
1082 break;
1083 case cmMove:
1084 handle_move(self, event);
1085 break;
1086 case cmPopup:
1087 handle_popup(self, event);
1088 break;
1089 case cmSize:
1090 handle_size( self, event);
1091 break;
1092 case cmDragBegin :
1093 handle_drag_begin( self, event );
1094 break;
1095 case cmDragOver :
1096 handle_drag_over( self, event );
1097 break;
1098 case cmDragEnd :
1099 handle_drag_end( self, event );
1100 break;
1101 case cmDragQuery :
1102 handle_drag_query( self, event );
1103 break;
1104 case cmDragResponse :
1105 my-> notify( self, "<siiH", "DragResponse",
1106 event->dnd.allow, event->dnd.action, event->dnd.counterpart);
1107 break;
1108 case cmMenuItemMeasure :
1109 case cmMenuItemPaint :
1110 {
1111 Handle menu = event->gen.H;
1112 event->gen.H = self;
1113 PComponent(menu)->self->handle_event(menu, event);
1114 break;
1115 }
1116 }
1117 }
1118
1119 void
Widget_hide(Handle self)1120 Widget_hide( Handle self)
1121 {
1122 enter_method;
1123 my-> set_visible( self, false);
1124 }
1125
1126 void
Widget_hide_cursor(Handle self)1127 Widget_hide_cursor( Handle self)
1128 {
1129 enter_method;
1130 if ( my-> get_cursorVisible( self))
1131 my-> set_cursorVisible( self, false);
1132 else
1133 var-> cursorLock++;
1134 }
1135
1136 /*::i */
1137 void
Widget_insert_behind(Handle self,Handle widget)1138 Widget_insert_behind ( Handle self, Handle widget)
1139 {
1140 apc_widget_set_z_order( self, widget, 0);
1141 }
1142
1143 void
Widget_invalidate_rect(Handle self,Rect rect)1144 Widget_invalidate_rect( Handle self, Rect rect)
1145 {
1146 enter_method;
1147 if ( !opt_InPaint && ( var-> stage == csNormal) && !my-> get_locked( self))
1148 apc_widget_invalidate_rect( self, &rect);
1149 }
1150
1151
1152 Bool
Widget_is_child(Handle self,Handle owner)1153 Widget_is_child( Handle self, Handle owner)
1154 {
1155 if ( !owner)
1156 return false;
1157 while ( self) {
1158 if ( self == owner)
1159 return true;
1160 self = var-> owner;
1161 }
1162 return false;
1163 }
1164
1165 /*::j */
1166 /*::k */
1167 void
Widget_key_event(Handle self,int command,int code,int key,int mod,int repeat,Bool post)1168 Widget_key_event( Handle self, int command, int code, int key, int mod, int repeat, Bool post)
1169 {
1170 Event ev;
1171 if ( command != cmKeyDown && command != cmKeyUp) return;
1172 memset( &ev, 0, sizeof( ev));
1173 if ( repeat <= 0) repeat = 1;
1174 ev. cmd = command;
1175 ev. key. code = code;
1176 ev. key. key = key;
1177 ev. key. mod = mod;
1178 ev. key. repeat = repeat;
1179 apc_message( self, &ev, post);
1180 }
1181
1182 /*::l */
1183 Handle
Widget_last(Handle self)1184 Widget_last( Handle self)
1185 {
1186 return apc_widget_get_z_order( self, zoLast);
1187 }
1188
1189 Bool
Widget_lock(Handle self)1190 Widget_lock( Handle self)
1191 {
1192 var-> lockCount++;
1193 return true;
1194 }
1195
1196 /*::m */
1197 void
Widget_mouse_event(Handle self,int command,int button,int mod,int x,int y,Bool dbl,Bool post)1198 Widget_mouse_event( Handle self, int command, int button, int mod, int x, int y, Bool dbl, Bool post)
1199 {
1200 Event ev;
1201 if ( command != cmMouseDown
1202 && command != cmMouseUp
1203 && command != cmMouseClick
1204 && command != cmMouseMove
1205 && command != cmMouseWheel
1206 && command != cmMouseEnter
1207 && command != cmMouseLeave
1208 ) return;
1209
1210 memset( &ev, 0, sizeof( ev));
1211 ev. cmd = command;
1212 ev. pos. where. x = x;
1213 ev. pos. where. y = y;
1214 ev. pos. mod = mod;
1215 ev. pos. button = button;
1216 if ( command == cmMouseClick) ev. pos. dblclk = dbl;
1217 apc_message( self, &ev, post);
1218 }
1219
1220 /*::n */
1221 Handle
Widget_next(Handle self)1222 Widget_next( Handle self)
1223 {
1224 return apc_widget_get_z_order( self, zoNext);
1225 }
1226
1227 static void
fill_tab_candidates(PList list,Handle level)1228 fill_tab_candidates( PList list, Handle level)
1229 {
1230 int i;
1231 PList w = &(PWidget( level)-> widgets);
1232 for ( i = 0; i < w-> count; i++) {
1233 Handle x = w-> items[i];
1234 if ( CWidget( x)-> get_visible( x) && CWidget( x)-> get_enabled( x)) {
1235 if ( CWidget( x)-> get_selectable( x) && CWidget( x)-> get_tabStop( x))
1236 list_add( list, x);
1237 fill_tab_candidates( list, x);
1238 }
1239 }
1240 }
1241
1242 Handle
Widget_next_positional(Handle self,int dx,int dy)1243 Widget_next_positional( Handle self, int dx, int dy)
1244 {
1245 Handle horizon = self;
1246
1247 int i, maxDiff = INT_MAX;
1248 Handle max = NULL_HANDLE;
1249 List candidates;
1250 Point p[2];
1251
1252 int minor[2], major[2], axis, extraDiff, ir[4];
1253
1254 /*
1255 In order to compute positional difference, using four penalties.
1256 To simplify algorithm, Rect will be translated to int[4] and
1257 minor, major and extraDiff assigned to array indices for those
1258 steps - minor for first and third, major for second and extraDiff for last one.
1259 */
1260
1261 axis = ( dx == 0) ? dy : dx;
1262 minor[0] = ( dx == 0) ? 0 : 1;
1263 minor[1] = minor[0] + 2;
1264 extraDiff = major[(axis < 0) ? 0 : 1] = ( dx == 0) ? 1 : 0;
1265 major[(axis < 0) ? 1 : 0] = extraDiff + 2;
1266 extraDiff = ( dx == 0) ? (( axis < 0) ? 0 : 2) : (( axis < 0) ? 1 : 3);
1267
1268 while ( PWidget( horizon)-> owner) {
1269 if (
1270 ( PWidget( horizon)-> options. optSystemSelectable) || /* fast check for CWindow */
1271 ( PWidget( horizon)-> options. optModalHorizon)
1272 ) break;
1273 horizon = PWidget( horizon)-> owner;
1274 }
1275
1276 if ( !CWidget( horizon)-> get_visible( horizon) ||
1277 !CWidget( horizon)-> get_enabled( horizon)) return NULL_HANDLE;
1278
1279 list_create( &candidates, 64, 64);
1280 fill_tab_candidates( &candidates, horizon);
1281
1282 p[0].x = p[0].y = 0;
1283 p[1] = CWidget( self)-> get_size( self);
1284 apc_widget_map_points( self, true, 2, p);
1285 apc_widget_map_points( horizon, false, 2, p);
1286 ir[0] = p[0].x; ir[1] = p[0].y; ir[2] = p[1].x; ir[3] = p[1].y;
1287
1288 for ( i = 0; i < candidates. count; i++) {
1289 int diff, ix[4];
1290 Handle x = candidates. items[i];
1291
1292 if ( x == self) continue;
1293
1294 p[0].x = p[0].y = 0;
1295 p[1] = CWidget( x)-> get_size( x);
1296 apc_widget_map_points( x, true, 2, p);
1297 apc_widget_map_points( horizon, false, 2, p);
1298 ix[0] = p[0].x; ix[1] = p[0].y; ix[2] = p[1].x; ix[3] = p[1].y;
1299
1300 /* First step - checking if the widget is subject to comparison. It is not,
1301 if it's minor axis is not contiguous with self's */
1302
1303 if ( ix[ minor[0]] > ir[ minor[1]] || ix[ minor[1]] < ir[ minor[0]])
1304 continue;
1305
1306 /* Using x100 penalty for distance in major axis - and discarding those that
1307 of different sign */
1308 diff = ( ix[ major[ 1]] - ir[ major[0]]) * 100 * axis;
1309 if ( diff < 0)
1310 continue;
1311
1312 /* Adding x10 penalty for incomplete minor axis congruence. Addition goes in tenths,
1313 in a way to not allow congruence overweight major axis distance */
1314 if ( ix[ minor[0]] > ir[ minor[0]])
1315 diff += ( ix[ minor[0]] - ir[ minor[0]]) * 100 / ( ir[ minor[1]] - ir[ minor[0]]);
1316 if ( ix[ minor[1]] < ir[ minor[1]])
1317 diff += ( ir[ minor[1]] - ix[ minor[1]]) * 100 / ( ir[ minor[1]] - ir[ minor[0]]);
1318
1319 /* Adding 'distance from level' x1 penalty */
1320 if (( ix[ extraDiff] - ir[ extraDiff]) * axis < 0)
1321 diff += abs( ix[ extraDiff] - ir[ extraDiff]);
1322
1323 if ( diff < maxDiff) {
1324 max = x;
1325 maxDiff = diff;
1326 }
1327 }
1328
1329 list_destroy( &candidates);
1330
1331 return max;
1332 }
1333
compare_taborders_forward(const void * a,const void * b)1334 static int compare_taborders_forward( const void *a, const void *b)
1335 {
1336 if ((*(PWidget*) a)-> tabOrder < (*(PWidget*) b)-> tabOrder)
1337 return -1; else
1338 if ((*(PWidget*) a)-> tabOrder > (*(PWidget*) b)-> tabOrder)
1339 return 1;
1340 else
1341 return 0;
1342 }
1343
compare_taborders_backward(const void * a,const void * b)1344 static int compare_taborders_backward( const void *a, const void *b)
1345 {
1346 if ((*(PWidget*) a)-> tabOrder < (*(PWidget*) b)-> tabOrder)
1347 return 1; else
1348 if ((*(PWidget*) a)-> tabOrder > (*(PWidget*) b)-> tabOrder)
1349 return -1;
1350 else
1351 return 0;
1352 }
1353
1354 static int
do_taborder_candidates(Handle level,Handle who,int (* compareProc)(const void *,const void *),int * stage,Handle * result)1355 do_taborder_candidates( Handle level, Handle who,
1356 int (*compareProc)(const void *, const void *),
1357 int * stage, Handle * result)
1358 {
1359 int i, fsel = -1;
1360 PList w = &(PWidget( level)-> widgets);
1361 Handle * ordered;
1362
1363 if ( w-> count == 0) return true;
1364
1365 ordered = ( Handle *) malloc( w-> count * sizeof( Handle));
1366 if ( !ordered) return true;
1367
1368 memcpy( ordered, w-> items, w-> count * sizeof( Handle));
1369 qsort( ordered, w-> count, sizeof( Handle), compareProc);
1370
1371 /* finding current widget in the group */
1372 for ( i = 0; i < w-> count; i++) {
1373 Handle x = ordered[i];
1374 if ( CWidget( x)-> get_current( x)) {
1375 fsel = i;
1376 break;
1377 }
1378 }
1379 if ( fsel < 0) fsel = 0;
1380
1381 for ( i = 0; i < w-> count; i++) {
1382 int j;
1383 Handle x;
1384
1385 j = i + fsel;
1386 if ( j >= w-> count) j -= w-> count;
1387
1388 x = ordered[j];
1389 if ( CWidget( x)-> get_visible( x) && CWidget( x)-> get_enabled( x)) {
1390 if ( CWidget( x)-> get_selectable( x) && CWidget( x)-> get_tabStop( x)) {
1391 if ( *result == NULL_HANDLE) *result = x;
1392 switch( *stage) {
1393 case 0: /* nothing found yet */
1394 if ( x == who) *stage = 1;
1395 break;
1396 default:
1397 /* next widget after 'who' is ours */
1398 *result = x;
1399 free( ordered);
1400 return false;
1401 }
1402 }
1403 if ( !do_taborder_candidates( x, who, compareProc, stage, result)) {
1404 free( ordered);
1405 return false; /* fall through */
1406 }
1407 }
1408 }
1409 free( ordered);
1410 return true;
1411 }
1412
1413 Handle
Widget_next_tab(Handle self,Bool forward)1414 Widget_next_tab( Handle self, Bool forward)
1415 {
1416 Handle horizon = self, result = NULL_HANDLE;
1417 int stage = 0;
1418
1419 while ( PWidget( horizon)-> owner) {
1420 if (
1421 ( PWidget( horizon)-> options. optSystemSelectable) || /* fast check for CWindow */
1422 ( PWidget( horizon)-> options. optModalHorizon)
1423 ) break;
1424 horizon = PWidget( horizon)-> owner;
1425 }
1426
1427 if ( !CWidget( horizon)-> get_visible( horizon) ||
1428 !CWidget( horizon)-> get_enabled( horizon)) return NULL_HANDLE;
1429
1430 do_taborder_candidates( horizon, self,
1431 forward ? compare_taborders_forward : compare_taborders_backward,
1432 &stage, &result);
1433 if ( result == self) result = NULL_HANDLE;
1434 return result;
1435 }
1436
1437 /*::o */
1438 /*::p */
1439
1440
1441 void
Widget_post_message(Handle self,SV * info1,SV * info2)1442 Widget_post_message( Handle self, SV * info1, SV * info2)
1443 {
1444 PPostMsg p;
1445 Event ev = { cmPost};
1446 if ( var-> stage > csNormal) return;
1447 if (!( p = alloc1( PostMsg))) return;
1448 p-> info1 = newSVsv( info1);
1449 p-> info2 = newSVsv( info2);
1450 p-> h = self;
1451 if ( var-> postList == NULL)
1452 var-> postList = plist_create( 8, 8);
1453 list_add( var-> postList, ( Handle) p);
1454 ev. gen. p = p;
1455 ev. gen. source = ev. gen. H = self;
1456 apc_message( self, &ev, true);
1457 }
1458
1459 Handle
Widget_prev(Handle self)1460 Widget_prev( Handle self)
1461 {
1462 return apc_widget_get_z_order( self, zoPrev);
1463 }
1464
1465 Bool
Widget_process_accel(Handle self,int key)1466 Widget_process_accel( Handle self, int key)
1467 {
1468 enter_method;
1469 if ( my-> first_that_component( self, (void*)prima_find_accel, &key)) return true;
1470 return kind_of( var-> owner, CWidget) ?
1471 ((( PWidget) var-> owner)-> self)->process_accel( var-> owner, key) : false;
1472 }
1473
1474 /*::q */
1475 /*::r */
1476 void
Widget_repaint(Handle self)1477 Widget_repaint( Handle self)
1478 {
1479 enter_method;
1480 if ( !opt_InPaint && ( var-> stage == csNormal) && !my-> get_locked( self))
1481 apc_widget_invalidate_rect( self, NULL);
1482 }
1483
1484 /*::s */
1485 int
Widget_scroll(Handle self,int dx,int dy,Rect * confine,Rect * clip,Bool withChildren)1486 Widget_scroll( Handle self, int dx, int dy, Rect *confine, Rect *clip, Bool withChildren)
1487 {
1488 enter_method;
1489 if ( !opt_InPaint && ( var-> stage == csNormal) && !my-> get_locked( self))
1490 return apc_widget_scroll( self, dx, dy, confine, clip, withChildren);
1491 return scrError;
1492 }
1493
1494 int
Widget_scroll_REDEFINED(Handle self,int dx,int dy,Rect * confine,Rect * clip,Bool withChildren)1495 Widget_scroll_REDEFINED( Handle self, int dx, int dy, Rect *confine, Rect *clip, Bool withChildren)
1496 {
1497 warn("Invalid call of Widget::scroll");
1498 return scrError;
1499 }
1500
XS(Widget_scroll_FROMPERL)1501 XS( Widget_scroll_FROMPERL)
1502 {
1503 dPROFILE;
1504 dXSARGS;
1505 Handle self;
1506 int dx, dy, ret;
1507 Rect *confine = NULL;
1508 Rect *clip = NULL;
1509 Rect confine_rect, clip_rect;
1510 Bool withChildren = false;
1511 HV *profile;
1512 int rect[4];
1513
1514 if ( items < 3 || (items - 3) % 2) goto invalid_usage;
1515 if (!( self = gimme_the_mate( ST(0)))) goto invalid_usage;
1516 dx = SvIV( ST(1));
1517 dy = SvIV( ST(2));
1518 profile = parse_hv( ax, sp, items, mark, 3, "Widget::scroll");
1519 if ( pexist( confineRect)) {
1520 prima_read_point( pget_sv( confineRect), rect, 4, "Array panic on 'confineRect'");
1521 confine = &confine_rect;
1522 confine-> left = rect[0];
1523 confine-> bottom = rect[1];
1524 confine-> right = rect[2];
1525 confine-> top = rect[3];
1526 }
1527 if ( pexist( clipRect)) {
1528 prima_read_point( pget_sv( clipRect), rect, 4, "Array panic on 'clipRect'");
1529 clip = &clip_rect;
1530 clip-> left = rect[0];
1531 clip-> bottom = rect[1];
1532 clip-> right = rect[2];
1533 clip-> top = rect[3];
1534 }
1535 if ( pexist( withChildren)) withChildren = pget_B( withChildren);
1536 sv_free((SV*)profile);
1537 ret = Widget_scroll( self, dx, dy, confine, clip, withChildren);
1538 SPAGAIN;
1539 SP -= items;
1540 XPUSHs( sv_2mortal( newSViv( ret)));
1541 PUTBACK;
1542 return;
1543 invalid_usage:
1544 croak ("Invalid usage of %s", "Widget::scroll");
1545 }
1546
1547 void
Widget_send_to_back(Handle self)1548 Widget_send_to_back( Handle self)
1549 {
1550 apc_widget_set_z_order( self, NULL_HANDLE, false);
1551 }
1552
1553 void
Widget_set(Handle self,HV * profile)1554 Widget_set( Handle self, HV * profile)
1555 {
1556 dPROFILE;
1557 enter_method;
1558 Handle postOwner = NULL_HANDLE;
1559 AV *order = NULL;
1560 int geometry = gtDefault;
1561
1562 if ( pexist(__ORDER__)) order = (AV*)SvRV(pget_sv( __ORDER__));
1563
1564 if ( pexist( owner)) {
1565 if ( !my-> validate_owner( self, &postOwner, profile))
1566 croak( "Illegal 'owner' reference passed to %s::%s", my-> className, "set");
1567 if ( postOwner != var-> owner) {
1568 if ( is_opt( optOwnerColor)) {
1569 my-> set_color( self, CWidget( postOwner)-> get_color( postOwner));
1570 opt_set( optOwnerColor);
1571 }
1572 if ( is_opt( optOwnerBackColor)) {
1573 my-> set_backColor( self, CWidget( postOwner)-> get_backColor( postOwner));
1574 opt_set( optOwnerBackColor);
1575 }
1576 if ( is_opt( optOwnerShowHint)) {
1577 Bool newSH = ( postOwner == application) ? 1 :
1578 CWidget( postOwner)-> get_showHint( postOwner);
1579 my-> set_showHint( self, newSH);
1580 opt_set( optOwnerShowHint);
1581 }
1582 if ( is_opt( optOwnerHint)) {
1583 my-> set_hint( self, CWidget( postOwner)-> get_hint( postOwner));
1584 opt_set( optOwnerHint);
1585 }
1586 if ( is_opt( optOwnerFont)) {
1587 my-> set_font ( self, CWidget( postOwner)-> get_font( postOwner));
1588 opt_set( optOwnerFont);
1589 }
1590 }
1591 if ( var-> geometry != gtDefault) {
1592 geometry = var-> geometry;
1593 my-> set_geometry( self, gtDefault);
1594 }
1595 }
1596
1597 /* geometry manipulations */
1598 {
1599 #define iLEFT 0
1600 #define iRIGHT 1
1601 #define iTOP 2
1602 #define iBOTTOM 3
1603 #define iWIDTH 4
1604 #define iHEIGHT 5
1605 int i, count;
1606 Bool exists[ 6];
1607 int values[ 6];
1608
1609 bzero( values, sizeof(values));
1610 if ( pexist( origin))
1611 {
1612 int set[2];
1613 if (order && !pexist(left)) av_push( order, newSVpv("left",0));
1614 if (order && !pexist(bottom)) av_push( order, newSVpv("bottom",0));
1615 prima_read_point( pget_sv( origin), set, 2, "Array panic on 'origin'");
1616 pset_i( left, set[0]);
1617 pset_i( bottom, set[1]);
1618 pdelete( origin);
1619 }
1620 if ( pexist( rect))
1621 {
1622 int rect[4];
1623 if (order && !pexist(left)) av_push( order, newSVpv("left",0));
1624 if (order && !pexist(bottom)) av_push( order, newSVpv("bottom",0));
1625 if (order && !pexist(width)) av_push( order, newSVpv("width",0));
1626 if (order && !pexist(height)) av_push( order, newSVpv("height",0));
1627 prima_read_point( pget_sv( rect), rect, 4, "Array panic on 'rect'");
1628 pset_i( left, rect[0]);
1629 pset_i( bottom, rect[1]);
1630 pset_i( width, rect[2] - rect[0]);
1631 pset_i( height, rect[3] - rect[1]);
1632 pdelete( rect);
1633 }
1634 if ( pexist( size))
1635 {
1636 int set[2];
1637 if (order && !pexist(width)) av_push( order, newSVpv("width",0));
1638 if (order && !pexist(height)) av_push( order, newSVpv("height",0));
1639 prima_read_point( pget_sv( size), set, 2, "Array panic on 'size'");
1640 pset_i( width, set[0]);
1641 pset_i( height, set[1]);
1642 pdelete( size);
1643 }
1644
1645 if (( exists[ iLEFT] = pexist( left))) values[ iLEFT] = pget_i( left);
1646 if (( exists[ iRIGHT] = pexist( right))) values[ iRIGHT] = pget_i( right);
1647 if (( exists[ iTOP] = pexist( top))) values[ iTOP] = pget_i( top);
1648 if (( exists[ iBOTTOM] = pexist( bottom ))) values[ iBOTTOM] = pget_i( bottom);
1649 if (( exists[ iWIDTH] = pexist( width))) values[ iWIDTH] = pget_i( width);
1650 if (( exists[ iHEIGHT] = pexist( height))) values[ iHEIGHT] = pget_i( height);
1651
1652 count = 0;
1653 for ( i = 0; i < 6; i++) if ( exists[ i]) count++;
1654
1655 if ( count > 1) {
1656 if ( exists[ iWIDTH] && exists[ iRIGHT] && exists[ iLEFT]) {
1657 exists[ iRIGHT] = 0;
1658 count--;
1659 }
1660 if ( exists[ iHEIGHT] && exists[ iTOP] && exists[ iBOTTOM]) {
1661 exists[ iTOP] = 0;
1662 count--;
1663 }
1664 if ( exists[ iRIGHT] && exists[ iLEFT]) {
1665 exists[ iWIDTH] = 1;
1666 values[ iWIDTH] = values[ iRIGHT] - values[ iLEFT];
1667 exists[ iRIGHT] = 0;
1668 }
1669 if ( exists[ iTOP] && exists[ iBOTTOM]) {
1670 exists[ iHEIGHT] = 1;
1671 values[ iHEIGHT] = values[ iTOP] - values[ iBOTTOM];
1672 exists[ iTOP] = 0;
1673 }
1674
1675 if (
1676 ( count == 2) &&
1677 (
1678 ( exists[ iLEFT] && exists[ iBOTTOM]) ||
1679 ( exists[ iWIDTH] && exists[ iHEIGHT])
1680 )
1681 ) {
1682 Point p;
1683 if ( exists[ iLEFT]) {
1684 p. x = values[ iLEFT];
1685 p. y = values[ iBOTTOM];
1686 my-> set_origin( self, p);
1687 } else {
1688 p. x = values[ iWIDTH];
1689 p. y = values[ iHEIGHT];
1690 my-> set_size( self, p);
1691 }
1692 } else {
1693 Rect r;
1694 if ( !exists[ iWIDTH] || !exists[ iHEIGHT]) {
1695 Point sz;
1696 sz = my-> get_size( self);
1697 if ( !exists[ iWIDTH]) values[ iWIDTH] = sz. x;
1698 if ( !exists[ iHEIGHT]) values[ iHEIGHT] = sz. y;
1699 exists[ iWIDTH] = exists[ iHEIGHT] = 1;
1700 }
1701 if ( ( !exists[ iLEFT] && !exists[ iRIGHT]) ||
1702 ( !exists[ iBOTTOM] && !exists[ iTOP])) {
1703 Point pos;
1704 pos = my-> get_origin( self);
1705 if ( !exists[ iLEFT]) values[ iLEFT] = pos. x;
1706 if ( !exists[ iBOTTOM]) values[ iBOTTOM] = pos. y;
1707 exists[ iLEFT] = exists[ iBOTTOM] = 1;
1708 }
1709 if ( !exists[ iLEFT]) {
1710 exists[ iLEFT] = 1;
1711 values[ iLEFT] = values[ iRIGHT] - values[ iWIDTH];
1712 }
1713 if ( !exists[ iBOTTOM]) {
1714 exists[ iBOTTOM] = 1;
1715 values[ iBOTTOM] = values[ iTOP] - values[ iHEIGHT];
1716 }
1717 r. left = values[ iLEFT];
1718 r. bottom = values[ iBOTTOM];
1719 r. right = values[ iLEFT] + values[ iWIDTH];
1720 r. top = values[ iBOTTOM] + values[ iHEIGHT];
1721 my-> set_rect( self, r);
1722 }
1723 pdelete( left);
1724 pdelete( right);
1725 pdelete( top);
1726 pdelete( bottom);
1727 pdelete( width);
1728 pdelete( height);
1729 } /* count > 1 */
1730 }
1731 if ( pexist( popupFont))
1732 {
1733 SvHV_Font( pget_sv( popupFont), &Font_buffer, "Widget::set");
1734 my-> set_popup_font( self, Font_buffer);
1735 pdelete( popupFont);
1736 }
1737 if ( pexist( pointerIcon) && pexist( pointerHotSpot))
1738 {
1739 Point hotSpot;
1740 Handle icon = pget_H( pointerIcon);
1741 prima_read_point( pget_sv( pointerHotSpot), (int*)&hotSpot, 2, "Array panic on 'pointerHotSpot'");
1742 if ( icon != NULL_HANDLE && !kind_of( icon, CIcon)) {
1743 warn("Illegal object reference passed to Widget.set_pointer_icon");
1744 icon = NULL_HANDLE;
1745 }
1746 apc_pointer_set_user( self, icon, hotSpot);
1747 if ( var-> pointerType == crUser) my-> first_that( self, (void*)sptr, NULL);
1748 pdelete( pointerIcon);
1749 pdelete( pointerHotSpot);
1750 }
1751 if ( pexist( designScale))
1752 {
1753 AV * av = ( AV *) SvRV( pget_sv( designScale));
1754 SV ** holder = av_fetch( av, 0, 0);
1755 NPoint ds = {1,1};
1756 ds. x = holder ? SvNV( *holder) : 1;
1757 if ( !holder) warn("Array panic on 'designScale'");
1758 holder = av_fetch( av, 1, 0);
1759 ds. y = holder ? SvNV( *holder) : 1;
1760 if ( !holder) warn("Array panic on 'designScale'");
1761 my-> set_designScale( self, ds);
1762 pdelete( designScale);
1763 }
1764 if ( pexist( sizeMin)) {
1765 Point set;
1766 prima_read_point( pget_sv( sizeMin), (int*)&set, 2, "Array panic on 'sizeMin'");
1767 my-> set_sizeMin( self, set);
1768 pdelete( sizeMin);
1769 }
1770 if ( pexist( sizeMax)) {
1771 Point set;
1772 prima_read_point( pget_sv( sizeMax), (int*)&set, 2, "Array panic on 'sizeMax'");
1773 my-> set_sizeMax( self, set);
1774 pdelete( sizeMax);
1775 }
1776 if ( pexist( cursorSize)) {
1777 Point set;
1778 prima_read_point( pget_sv( cursorSize), (int*)&set, 2, "Array panic on 'cursorSize'");
1779 my-> set_cursorSize( self, set);
1780 pdelete( cursorSize);
1781 }
1782 if ( pexist( cursorPos)) {
1783 Point set;
1784 prima_read_point( pget_sv( cursorPos), (int*)&set, 2, "Array panic on 'cursorPos'");
1785 my-> set_cursorPos( self, set);
1786 pdelete( cursorPos);
1787 }
1788 if ( pexist( geomSize))
1789 {
1790 Point set;
1791 prima_read_point( pget_sv( geomSize), (int*)&set, 2, "Array panic on 'geomSize'");
1792 my-> set_geomSize( self, set);
1793 pdelete( geomSize);
1794 }
1795
1796 inherited-> set( self, profile);
1797 if ( postOwner) {
1798 my-> set_tabOrder( self, var-> tabOrder);
1799 my-> set_geometry( self, geometry);
1800 }
1801 }
1802
1803 void
Widget_setup(Handle self)1804 Widget_setup( Handle self)
1805 {
1806 enter_method;
1807 if ( var-> geometry == gtGrowMode && ( var-> geomInfo.x != 0 || var-> geomInfo. y != 0 ))
1808 my-> set_centered( self, var-> geomInfo. x, var-> geomInfo. y);
1809 if ( get_top_current( self) &&
1810 my-> get_enabled( self) &&
1811 my-> get_visible( self))
1812 my-> set_selected( self, true);
1813 inherited-> setup( self);
1814 }
1815
1816 void
Widget_show(Handle self)1817 Widget_show( Handle self)
1818 {
1819 enter_method;
1820 my-> set_visible( self, true);
1821 }
1822
1823 void
Widget_show_cursor(Handle self)1824 Widget_show_cursor( Handle self)
1825 {
1826 enter_method;
1827 if ( var-> cursorLock-- <= 0) {
1828 my-> set_cursorVisible( self, true);
1829 var-> cursorLock = 0;
1830 }
1831 }
1832
1833 /*::t */
1834 /*::u */
1835
1836 static Bool
repaint_all(Handle owner,Handle self,void * dummy)1837 repaint_all( Handle owner, Handle self, void * dummy)
1838 {
1839 enter_method;
1840 my-> repaint( self);
1841 my-> first_that( self, (void*)repaint_all, NULL);
1842 return false;
1843 }
1844
1845 Bool
Widget_unlock(Handle self)1846 Widget_unlock( Handle self)
1847 {
1848 if ( --var-> lockCount <= 0) {
1849 var-> lockCount = 0;
1850 repaint_all( var-> owner, self, NULL);
1851 }
1852 return true;
1853 }
1854
1855 void
Widget_update_view(Handle self)1856 Widget_update_view( Handle self)
1857 {
1858 if ( !opt_InPaint) apc_widget_update( self);
1859 }
1860
1861 /*::v */
1862
1863 Bool
Widget_validate_owner(Handle self,Handle * owner,HV * profile)1864 Widget_validate_owner( Handle self, Handle * owner, HV * profile)
1865 {
1866 dPROFILE;
1867 *owner = pget_H( owner);
1868 if ( !kind_of( *owner, CWidget)) return false;
1869 return inherited-> validate_owner( self, owner, profile);
1870 }
1871
1872 /*::w */
1873 /*::x */
1874 /*::y */
1875 /*::z */
1876
1877 /* get_props() */
1878
1879 Font
Widget_get_default_font(char * dummy)1880 Widget_get_default_font( char * dummy)
1881 {
1882 Font font;
1883 apc_widget_default_font( &font);
1884 return font;
1885 }
1886
1887 Font
Widget_get_default_popup_font(char * dummy)1888 Widget_get_default_popup_font( char * dummy)
1889 {
1890 Font f;
1891 apc_popup_default_font( &f);
1892 return f;
1893 }
1894
1895
1896 NPoint
Widget_designScale(Handle self,Bool set,NPoint designScale)1897 Widget_designScale( Handle self, Bool set, NPoint designScale)
1898 {
1899 if ( !set)
1900 return var-> designScale;
1901 if ( designScale. x < 0) designScale. x = 0;
1902 if ( designScale. y < 0) designScale. y = 0;
1903 var-> designScale = designScale;
1904 return designScale;
1905 }
1906
1907 int
Widget_growMode(Handle self,Bool set,int growMode)1908 Widget_growMode( Handle self, Bool set, int growMode)
1909 {
1910 enter_method;
1911 Bool x = false, y = false;
1912 if ( !set)
1913 return var-> growMode;
1914 var-> growMode = growMode;
1915 if ( var-> growMode & gmXCenter) x = true;
1916 if ( var-> growMode & gmYCenter) y = true;
1917 if ( var-> geometry == gtGrowMode && (x || y)) my-> set_centered( self, x, y);
1918 return var-> growMode;
1919 }
1920
1921 SV *
Widget_get_handle(Handle self)1922 Widget_get_handle( Handle self)
1923 {
1924 char buf[ 256];
1925 snprintf( buf, 256, PR_HANDLE_FMT, apc_widget_get_handle( self));
1926 return newSVpv( buf, 0);
1927 }
1928
1929 SV *
Widget_get_parent_handle(Handle self)1930 Widget_get_parent_handle( Handle self)
1931 {
1932 char buf[ 256];
1933 snprintf( buf, 256, PR_HANDLE_FMT, apc_widget_get_parent_handle( self));
1934 return newSVpv( buf, 0);
1935 }
1936
1937 int
Widget_hintVisible(Handle self,Bool set,int hintVisible)1938 Widget_hintVisible( Handle self, Bool set, int hintVisible)
1939 {
1940 Bool wantVisible;
1941 if ( !set)
1942 return PApplication( application)-> hintVisible;
1943 if ( var-> stage >= csDead) return false;
1944 wantVisible = ( hintVisible != 0);
1945 if ( wantVisible == PApplication( application)-> hintVisible) return false;
1946 if ( wantVisible) {
1947 if ( SvCUR( var-> hint) == 0) return false;
1948 if ( hintVisible > 0) PApplication(application)-> hintActive = -1; /* immediate */
1949 }
1950 CApplication( application)-> set_hint_action( application, self, wantVisible, false);
1951 return false;
1952 }
1953
1954 Bool
Widget_get_locked(Handle self)1955 Widget_get_locked( Handle self)
1956 {
1957 while ( self) {
1958 if ( var-> lockCount != 0) return true;
1959 self = var-> owner;
1960 }
1961 return false;
1962 }
1963
1964
1965 Handle
Widget_get_parent(Handle self)1966 Widget_get_parent( Handle self)
1967 {
1968 enter_method;
1969 return my-> get_clipOwner( self) ? var-> owner : application;
1970 }
1971
1972 Point
Widget_get_pointer_size(char * dummy)1973 Widget_get_pointer_size( char*dummy)
1974 {
1975 return apc_pointer_get_size( NULL_HANDLE);
1976 }
1977
1978 Font
Widget_get_popup_font(Handle self)1979 Widget_get_popup_font( Handle self)
1980 {
1981 return var-> popupFont;
1982 }
1983
1984 Handle
Widget_get_selectee(Handle self)1985 Widget_get_selectee( Handle self)
1986 {
1987 if ( var-> stage > csFrozen) return NULL_HANDLE;
1988 if ( is_opt( optSelectable))
1989 return self;
1990 else if ( var-> currentWidget) {
1991 PWidget w = ( PWidget) var-> currentWidget;
1992 if ( w-> options. optSystemSelectable && !w-> self-> get_clipOwner(( Handle) w))
1993 return ( Handle) w;
1994 else
1995 return w-> self-> get_selectee(( Handle) w);
1996 } else if ( is_opt( optSystemSelectable))
1997 return self;
1998 else
1999 return find_tabfoc( self);
2000 }
2001
2002 Point
Widget_get_virtual_size(Handle self)2003 Widget_get_virtual_size( Handle self)
2004 {
2005 return var-> virtualSize;
2006 }
2007
2008 /* set_props() */
2009
2010 Bool
Widget_set_capture(Handle self,Bool capture,Handle confineTo)2011 Widget_set_capture( Handle self, Bool capture, Handle confineTo)
2012 {
2013 if ( opt_InPaint) return false;
2014 return apc_widget_set_capture( self, capture, confineTo);
2015 }
2016
2017 void
Widget_set_centered(Handle self,Bool x,Bool y)2018 Widget_set_centered( Handle self, Bool x, Bool y)
2019 {
2020 enter_method;
2021 Handle parent = my-> get_parent( self);
2022 Point size = CWidget( parent)-> get_size( parent);
2023 Point mysize = my-> get_size ( self);
2024 Point mypos = my-> get_origin( self);
2025 Point delta = {0,0};
2026
2027 if ( !x && !y ) return;
2028
2029 if ( parent == application ) {
2030 int i, nrects = 0;
2031 Box *best = NULL, *rects = apc_application_get_monitor_rects( application, &nrects);
2032 for ( i = 0; i < nrects; i++) {
2033 Box * curr = rects + i;
2034 if ( best == NULL || best-> x > curr->x || best->y > curr->y)
2035 best = curr;
2036 }
2037 if ( best ) {
2038 delta.x = best->x;
2039 delta.y = best->y;
2040 size.x = best->width;
2041 size.y = best->height;
2042 }
2043 }
2044 if ( x) mypos. x = ( size. x - mysize. x) / 2 + delta.x;
2045 if ( y) mypos. y = ( size. y - mysize. y) / 2 + delta.y;
2046 my-> set_origin( self, mypos);
2047 }
2048
2049 void
Widget_set_font(Handle self,Font font)2050 Widget_set_font( Handle self, Font font)
2051 {
2052 enter_method;
2053 if ( var-> stage > csFrozen) return;
2054 if ( !opt_InPaint) my-> first_that( self, (void*)prima_font_notify, &font);
2055 if ( var-> handle == NULL_HANDLE) return; /* aware of call from Drawable::init */
2056 if ( opt_InPaint) {
2057 inherited->set_font(self, font);
2058 }
2059 else {
2060 apc_font_pick( self, &font, & var-> font);
2061 opt_clear( optOwnerFont);
2062 apc_widget_set_font( self, & var-> font);
2063 my-> repaint( self);
2064 }
2065 }
2066
2067 void
Widget_set_popup_font(Handle self,Font font)2068 Widget_set_popup_font( Handle self, Font font)
2069 {
2070 apc_font_pick( self, &font, &var-> popupFont);
2071 }
2072
2073 /* event handlers */
2074
2075 void
Widget_on_paint(Handle self,SV * canvas)2076 Widget_on_paint( Handle self, SV * canvas)
2077 {
2078 int i;
2079 dSP;
2080 ENTER;
2081 SAVETMPS;
2082 PUSHMARK( sp);
2083 XPUSHs( canvas);
2084 for ( i = 0; i < 4; i++)
2085 XPUSHs( sv_2mortal( newSViv( -1)));
2086 PUTBACK;
2087 PERL_CALL_METHOD( "clear", G_DISCARD);
2088 SPAGAIN;
2089 PUTBACK;
2090 FREETMPS;
2091 LEAVE;
2092 }
2093
2094 /*
2095 void Widget_on_click( Handle self) {}
2096 void Widget_on_change( Handle self) {}
2097 void Widget_on_close( Handle self) {}
2098 void Widget_on_colorchanged( Handle self, int colorIndex){}
2099 void Widget_on_disable( Handle self) {}
2100 void Widget_on_dragdrop( Handle self, Handle source , int x , int y ) {}
2101 void Widget_on_dragover( Handle self, Handle source , int x , int y , int state ) {}
2102 void Widget_on_enable( Handle self) {}
2103 void Widget_on_enddrag( Handle self, Handle target , int x , int y ) {}
2104 void Widget_on_fontchanged( Handle self) {}
2105 void Widget_on_enter( Handle self) {}
2106 void Widget_on_keydown( Handle self, int code , int key , int shiftState, int repeat ) {}
2107 void Widget_on_keyup( Handle self, int code , int key , int shiftState ) {}
2108 void Widget_on_menu( Handle self, Handle menu, char * variable) {}
2109 void Widget_on_setup( Handle self) {}
2110 void Widget_on_size( Handle self, Point oldSize, Point newSize) {}
2111 void Widget_on_move( Handle self, Point oldPos, Point newPos) {}
2112 void Widget_on_show( Handle self) {}
2113 void Widget_on_hide( Handle self) {}
2114 void Widget_on_hint( Handle self, Bool show) {}
2115 void Widget_on_translateaccel( Handle self, int code , int key , int shiftState ) {}
2116 void Widget_on_zorderchanged( Handle self) {}
2117 void Widget_on_popup( Handle self, Bool mouseDriven, int x, int y) {}
2118 void Widget_on_mouseclick( Handle self, int button , int shiftState , int x , int y , Bool dbl ) {}
2119 void Widget_on_mousedown( Handle self, int button , int shiftState , int x , int y ) {}
2120 void Widget_on_mouseup( Handle self, int button , int shiftState , int x , int y ) {}
2121 void Widget_on_mousemove( Handle self, int shiftState , int x , int y ) {}
2122 void Widget_on_mousewheel( Handle self, int shiftState , int x , int y, int z ) {}
2123 void Widget_on_mouseenter( Handle self, int shiftState , int x , int y ) {}
2124 void Widget_on_mouseleave( Handle self ) {}
2125 void Widget_on_leave( Handle self) {}
2126 */
2127
2128
2129 /* static iterators */
prima_kill_all_objects(Handle self,Handle child,void * dummy)2130 Bool prima_kill_all_objects( Handle self, Handle child, void * dummy)
2131 {
2132 Object_destroy( child); return 0;
2133 }
2134
find_dup_msg(PEvent event,int * cmd)2135 static Bool find_dup_msg( PEvent event, int * cmd) { return event-> cmd == *cmd; }
2136
2137 Bool
prima_accel_notify(Handle group,Handle self,PEvent event)2138 prima_accel_notify ( Handle group, Handle self, PEvent event)
2139 {
2140 enter_method;
2141 if (( self != event-> key. source) && my-> get_enabled( self))
2142 return ( var-> stage <= csNormal) ? !my-> message( self, event) : false;
2143 else
2144 return false;
2145 }
2146
2147 static Bool
pquery(Handle window,Handle self,void * v)2148 pquery ( Handle window, Handle self, void * v)
2149 {
2150 enter_method;
2151 Event ev = {cmClose};
2152 return ( var-> stage <= csNormal) ? !my-> message( self, &ev) : false;
2153 }
2154
2155 Bool
prima_find_accel(Handle self,Handle item,int * key)2156 prima_find_accel( Handle self, Handle item, int * key)
2157 {
2158 return ( kind_of( item, CAbstractMenu)
2159 && CAbstractMenu(item)-> sub_call_key( item, *key));
2160 }
2161
2162 static Handle
find_tabfoc(Handle self)2163 find_tabfoc( Handle self)
2164 {
2165 int i;
2166 Handle toRet;
2167 for ( i = 0; i < var-> widgets. count; i++) {
2168 PWidget w = ( PWidget)( var-> widgets. items[ i]);
2169 if (
2170 w-> self-> get_selectable(( Handle) w) &&
2171 w-> self-> get_enabled(( Handle) w)
2172 )
2173 return ( Handle) w;
2174 }
2175 for ( i = 0; i < var-> widgets. count; i++)
2176 if (( toRet = find_tabfoc( var-> widgets. items[ i])))
2177 return toRet;
2178 return NULL_HANDLE;
2179 }
2180
2181
2182 static Bool
get_top_current(Handle self)2183 get_top_current( Handle self)
2184 {
2185 PWidget o = ( PWidget) var-> owner;
2186 Handle me = self;
2187 while ( o) {
2188 if ( o-> currentWidget != me)
2189 return false;
2190 me = ( Handle) o;
2191 o = ( PWidget) o-> owner;
2192 }
2193 return true;
2194 }
2195
2196 static Bool
sptr(Handle window,Handle self,void * v)2197 sptr( Handle window, Handle self, void * v)
2198 {
2199 enter_method;
2200 /* does nothing but refreshes system pointer */
2201 if ( var-> pointerType == crDefault)
2202 my-> set_pointerType( self, crDefault);
2203 return false;
2204 }
2205
2206 /* static iterators for ownership notifications */
2207
2208 Bool
prima_font_notify(Handle self,Handle child,void * font)2209 prima_font_notify ( Handle self, Handle child, void * font)
2210 {
2211 if ( his-> options. optOwnerFont) {
2212 his-> self-> set_font ( child, *(( PFont) font));
2213 his-> options. optOwnerFont = 1;
2214 }
2215 return false;
2216 }
2217
2218 static Bool
showhint_notify(Handle self,Handle child,void * data)2219 showhint_notify ( Handle self, Handle child, void * data)
2220 {
2221 if ( his-> options. optOwnerShowHint) {
2222 his-> self-> set_showHint ( child, *(( Bool *) data));
2223 his-> options. optOwnerShowHint = 1;
2224 }
2225 return false;
2226 }
2227
2228 static Bool
hint_notify(Handle self,Handle child,SV * hint)2229 hint_notify ( Handle self, Handle child, SV * hint)
2230 {
2231 if ( his-> options. optOwnerHint) {
2232 his-> self-> set_hint( child, hint);
2233 his-> options. optOwnerHint = 1;
2234 }
2235 return false;
2236 }
2237
2238 Bool
prima_single_color_notify(Handle self,Handle child,void * color)2239 prima_single_color_notify ( Handle self, Handle child, void * color)
2240 {
2241 PSingleColor s = ( PSingleColor) color;
2242 if ( his-> options. optOwnerColor && ( s-> index == ciFore))
2243 {
2244 his-> self-> colorIndex ( child, true, s-> index, s-> color);
2245 his-> options. optOwnerColor = 1;
2246 } else if (( his-> options. optOwnerBackColor) && ( s-> index == ciBack))
2247 {
2248 his-> self-> colorIndex ( child, true, s-> index, s-> color);
2249 his-> options. optOwnerBackColor = 1;
2250 } else if ( s-> index > ciBack)
2251 his-> self-> colorIndex ( child, true, s-> index, s-> color);
2252 return false;
2253 }
2254
2255 static Bool
auto_enable_children(Handle self,Handle child,void * enable)2256 auto_enable_children( Handle self, Handle child, void * enable)
2257 {
2258 apc_widget_set_enabled( child, PTR2UV( enable) != 0);
2259 return false;
2260 }
2261 /* properties section */
2262
2263 SV *
Widget_accelItems(Handle self,Bool set,SV * accelItems)2264 Widget_accelItems( Handle self, Bool set, SV * accelItems)
2265 {
2266 dPROFILE;
2267 enter_method;
2268 if ( var-> stage > csFrozen) return NULL_SV;
2269 if ( !set)
2270 return var-> accelTable ?
2271 CAbstractMenu( var-> accelTable)-> get_items( var-> accelTable, "", true) : NULL_SV;
2272 if ( var-> accelTable == NULL_HANDLE) {
2273 HV * profile = newHV();
2274 if ( SvTYPE( accelItems)) pset_sv( items, accelItems);
2275 pset_H ( owner, self);
2276 my-> set_accelTable( self, create_instance( "Prima::AccelTable"));
2277 sv_free(( SV *) profile);
2278 } else
2279 CAbstractMenu( var-> accelTable)-> set_items( var-> accelTable, accelItems);
2280 return NULL_SV;
2281 }
2282
2283 Handle
Widget_accelTable(Handle self,Bool set,Handle accelTable)2284 Widget_accelTable( Handle self, Bool set, Handle accelTable)
2285 {
2286 if ( var-> stage > csFrozen) return NULL_HANDLE;
2287 if ( !set)
2288 return var-> accelTable;
2289 if ( accelTable && !kind_of( accelTable, CAbstractMenu)) return NULL_HANDLE;
2290 if ( var->accelTable ) unprotect_object(var-> accelTable);
2291 var-> accelTable = accelTable;
2292 if ( var->accelTable ) protect_object(var-> accelTable);
2293 return NULL_HANDLE;
2294 }
2295
2296 Color
Widget_backColor(Handle self,Bool set,Color color)2297 Widget_backColor( Handle self, Bool set, Color color)
2298 {
2299 enter_method;
2300 if (!set) return my-> colorIndex( self, false, ciBack, 0);
2301 my-> colorIndex( self, true, ciBack, color);
2302 return color;
2303 }
2304
2305 int
Widget_bottom(Handle self,Bool set,int bottom)2306 Widget_bottom( Handle self, Bool set, int bottom)
2307 {
2308 enter_method;
2309 Point p = my-> get_origin( self);
2310 if ( !set)
2311 return p. y;
2312 p. y = bottom;
2313 my-> set_origin( self, p);
2314 return 0;
2315 }
2316
2317 Bool
Widget_autoEnableChildren(Handle self,Bool set,Bool autoEnableChildren)2318 Widget_autoEnableChildren( Handle self, Bool set, Bool autoEnableChildren)
2319 {
2320 if ( !set)
2321 return is_opt( optAutoEnableChildren);
2322 opt_assign( optAutoEnableChildren, autoEnableChildren);
2323 return false;
2324 }
2325
2326 Bool
Widget_briefKeys(Handle self,Bool set,Bool briefKeys)2327 Widget_briefKeys( Handle self, Bool set, Bool briefKeys)
2328 {
2329 if ( !set)
2330 return is_opt( optBriefKeys);
2331 opt_assign( optBriefKeys, briefKeys);
2332 return false;
2333 }
2334
2335 Bool
Widget_buffered(Handle self,Bool set,Bool buffered)2336 Widget_buffered( Handle self, Bool set, Bool buffered)
2337 {
2338 if ( !set)
2339 return is_opt( optBuffered);
2340 if ( !opt_InPaint)
2341 opt_assign( optBuffered, buffered);
2342 return false;
2343 }
2344
2345 Bool
Widget_clipChildren(Handle self,Bool set,Bool clip_by_children)2346 Widget_clipChildren( Handle self, Bool set, Bool clip_by_children)
2347 {
2348 if ( set)
2349 return apc_widget_set_clip_by_children(self, clip_by_children);
2350 else
2351 return apc_widget_get_clip_by_children(self);
2352 }
2353
2354 Bool
Widget_clipOwner(Handle self,Bool set,Bool clipOwner)2355 Widget_clipOwner( Handle self, Bool set, Bool clipOwner)
2356 {
2357 HV * profile;
2358 enter_method;
2359 if ( !set)
2360 return apc_widget_get_clip_owner( self);
2361 profile = newHV();
2362 pset_i( clipOwner, clipOwner);
2363 my-> set( self, profile);
2364 sv_free(( SV *) profile);
2365 return false;
2366 }
2367
2368 Color
Widget_color(Handle self,Bool set,Color color)2369 Widget_color( Handle self, Bool set, Color color)
2370 {
2371 enter_method;
2372 if (!set)
2373 return my-> colorIndex( self, false, ciFore, 0);
2374 return my-> colorIndex( self, true, ciFore, color);
2375 }
2376
2377 Color
Widget_colorIndex(Handle self,Bool set,int index,Color color)2378 Widget_colorIndex( Handle self, Bool set, int index, Color color)
2379 {
2380 if ( !set) {
2381 if ( index < 0 || index > ciMaxId) return clInvalid;
2382 switch ( index) {
2383 case ciFore:
2384 return opt_InPaint ? inherited-> get_color ( self) : apc_widget_get_color( self, ciFore);
2385 case ciBack:
2386 return opt_InPaint ? inherited-> get_backColor ( self) : apc_widget_get_color( self, ciBack);
2387 default:
2388 return apc_widget_get_color( self, index);
2389 }
2390 } else {
2391 enter_method;
2392 SingleColor s;
2393 s. color = color;
2394 s. index = index;
2395 if (( index < 0) || ( index > ciMaxId)) return clInvalid;
2396 if ( !opt_InPaint) my-> first_that( self, (void*)prima_single_color_notify, &s);
2397
2398 if ( var-> handle == NULL_HANDLE) return clInvalid; /* aware of call from Drawable::init */
2399 if ((( color & clSysFlag) != 0) && (( color & wcMask) == 0))
2400 color |= var-> widgetClass;
2401 if ( opt_InPaint) {
2402 switch ( index) {
2403 case ciFore:
2404 inherited-> set_color ( self, color);
2405 break;
2406 case ciBack:
2407 inherited-> set_backColor ( self, color);
2408 break;
2409 default:
2410 apc_widget_set_color ( self, color, index);
2411 }
2412 } else {
2413 switch ( index) {
2414 case ciFore:
2415 opt_clear( optOwnerColor);
2416 break;
2417 case ciBack:
2418 opt_clear( optOwnerBackColor);
2419 break;
2420 }
2421 apc_widget_set_color( self, color, index);
2422 my-> repaint( self);
2423 }
2424 }
2425 return 0;
2426 }
2427
2428 Bool
Widget_current(Handle self,Bool set,Bool current)2429 Widget_current( Handle self, Bool set, Bool current)
2430 {
2431 PWidget o;
2432 if ( var-> stage > csFrozen) return false;
2433 if ( !set)
2434 return var-> owner && ( PWidget( var-> owner)-> currentWidget == self);
2435 o = ( PWidget) var-> owner;
2436 if ( o == NULL) return false;
2437 if ( current)
2438 o-> self-> set_currentWidget( var-> owner, self);
2439 else
2440 if ( o-> currentWidget == self)
2441 o-> self-> set_currentWidget( var-> owner, NULL_HANDLE);
2442 return current;
2443 }
2444
2445 Handle
Widget_currentWidget(Handle self,Bool set,Handle widget)2446 Widget_currentWidget( Handle self, Bool set, Handle widget)
2447 {
2448 enter_method;
2449 if ( var-> stage > csFrozen) return NULL_HANDLE;
2450 if ( !set)
2451 return var-> currentWidget;
2452 if ( widget) {
2453 if ( !widget || ( PWidget( widget)-> stage > csFrozen) ||
2454 ( PWidget( widget)-> owner != self)
2455 ) return NULL_HANDLE;
2456 var-> currentWidget = widget;
2457 } else
2458 var-> currentWidget = NULL_HANDLE;
2459
2460 /* adjust selection if we're in currently selected chain */
2461 if ( my-> get_selected( self))
2462 my-> set_selectedWidget( self, widget);
2463 return NULL_HANDLE;
2464 }
2465
2466 Point
Widget_cursorPos(Handle self,Bool set,Point cursorPos)2467 Widget_cursorPos( Handle self, Bool set, Point cursorPos)
2468 {
2469 if ( !set)
2470 return apc_cursor_get_pos( self);
2471 apc_cursor_set_pos( self, cursorPos. x, cursorPos. y);
2472 return cursorPos;
2473 }
2474
2475 Point
Widget_cursorSize(Handle self,Bool set,Point cursorSize)2476 Widget_cursorSize( Handle self, Bool set, Point cursorSize)
2477 {
2478 if ( !set)
2479 return apc_cursor_get_size( self);
2480 apc_cursor_set_size( self, cursorSize. x, cursorSize. y);
2481 return cursorSize;
2482 }
2483
2484 Bool
Widget_cursorVisible(Handle self,Bool set,Bool cursorVisible)2485 Widget_cursorVisible( Handle self, Bool set, Bool cursorVisible)
2486 {
2487 if ( !set)
2488 return apc_cursor_get_visible( self);
2489 return apc_cursor_set_visible( self, cursorVisible);
2490 }
2491
2492 SV *
Widget_dndAware(Handle self,Bool set,SV * dndAware)2493 Widget_dndAware( Handle self, Bool set, SV * dndAware)
2494 {
2495 if ( !set) {
2496 if ( var->dndAware == NULL)
2497 return &PL_sv_undef;
2498 else if ( strcmp(var->dndAware, "1") == 0)
2499 return newSViv(1);
2500 else
2501 return newSVpv(var->dndAware, 0);
2502 } else if ( var->dndAware == NULL && SvBOOL(dndAware)) {
2503 if ( apc_dnd_set_aware( self, true))
2504 var-> dndAware = duplicate_string( SvPV_nolen( dndAware));
2505 } else if ( var->dndAware != NULL ) {
2506 free(var-> dndAware);
2507 if ( !SvBOOL(dndAware)) {
2508 var->dndAware = NULL;
2509 apc_dnd_set_aware( self, false);
2510 } else
2511 var-> dndAware = duplicate_string( SvPV_nolen( dndAware));
2512 }
2513 return &PL_sv_undef;
2514 }
2515
2516 Bool
Widget_enabled(Handle self,Bool set,Bool enabled)2517 Widget_enabled( Handle self, Bool set, Bool enabled)
2518 {
2519 if ( !set) return apc_widget_is_enabled( self);
2520 if ( !apc_widget_set_enabled( self, enabled))
2521 return false;
2522 if ( is_opt( optAutoEnableChildren))
2523 CWidget(self)-> first_that( self, (void*)auto_enable_children, INT2PTR(void*,enabled));
2524 return true;
2525 }
2526
2527 Bool
Widget_firstClick(Handle self,Bool set,Bool firstClick)2528 Widget_firstClick( Handle self, Bool set, Bool firstClick)
2529 {
2530 return set ?
2531 apc_widget_set_first_click( self, firstClick) :
2532 apc_widget_get_first_click( self);
2533 }
2534
2535 Bool
Widget_focused(Handle self,Bool set,Bool focused)2536 Widget_focused( Handle self, Bool set, Bool focused)
2537 {
2538 enter_method;
2539 if ( var-> stage > csNormal) return false;
2540 if ( !set)
2541 return apc_widget_is_focused( self);
2542
2543 if ( focused) {
2544 PWidget x = ( PWidget)( var-> owner);
2545 Handle current = self;
2546 while ( x) {
2547 x-> currentWidget = current;
2548 current = ( Handle) x;
2549 x = ( PWidget) x-> owner;
2550 }
2551 var-> currentWidget = NULL_HANDLE;
2552 if ( var-> stage == csNormal)
2553 apc_widget_set_focused( self);
2554 } else
2555 if ( var-> stage == csNormal && my-> get_selected( self))
2556 apc_widget_set_focused( NULL_HANDLE);
2557 return focused;
2558 }
2559
2560 SV *
Widget_helpContext(Handle self,Bool set,SV * helpContext)2561 Widget_helpContext( Handle self, Bool set, SV *helpContext)
2562 {
2563 if ( set) {
2564 if ( var-> stage > csFrozen) return NULL_SV;
2565 free( var-> helpContext);
2566 var-> helpContext = NULL;
2567 var-> helpContext = duplicate_string( SvPV_nolen( helpContext));
2568 opt_assign( optUTF8_helpContext, prima_is_utf8_sv(helpContext));
2569 } else {
2570 helpContext = newSVpv( var-> helpContext ? var-> helpContext : "", 0);
2571 if ( is_opt( optUTF8_helpContext)) SvUTF8_on( helpContext);
2572 return helpContext;
2573 }
2574 return NULL_SV;
2575 }
2576
2577 SV *
Widget_get_hint(Handle self)2578 Widget_get_hint( Handle self)
2579 {
2580 return newSVsv(var->hint);
2581 }
2582
2583 void
Widget_set_hint(Handle self,SV * hint)2584 Widget_set_hint( Handle self, SV *hint)
2585 {
2586 enter_method;
2587 if ( var-> stage > csFrozen) return;
2588 my-> first_that( self, (void*)hint_notify, (void*)hint);
2589 if ( var-> hint ) sv_free( var-> hint );
2590 var-> hint = newSVsv( hint);
2591 if ( application && (( PApplication) application)-> hintVisible &&
2592 (( PApplication) application)-> hintUnder == self)
2593 {
2594 Handle hintWidget = (( PApplication) application)-> hintWidget;
2595 if ( SvLEN( var-> hint) == 0)
2596 my-> set_hintVisible( self, 0);
2597 if ( hintWidget)
2598 CWidget(hintWidget)-> set_text( hintWidget, my-> get_hint( self));
2599 }
2600 opt_clear( optOwnerHint);
2601 }
2602
2603 Bool
Widget_layered(Handle self,Bool set,Bool layered)2604 Widget_layered( Handle self, Bool set, Bool layered)
2605 {
2606 HV * profile;
2607 enter_method;
2608 if ( !set)
2609 return apc_widget_get_layered_request( self);
2610 profile = newHV();
2611 pset_i( layered, layered);
2612 my-> set( self, profile);
2613 sv_free(( SV *) profile);
2614 return false;
2615 }
2616
2617 int
Widget_left(Handle self,Bool set,int left)2618 Widget_left( Handle self, Bool set, int left)
2619 {
2620 enter_method;
2621 Point p = my-> get_origin( self);
2622 if ( !set)
2623 return p. x;
2624 p. x = left;
2625 my-> set_origin( self, p);
2626 return 0;
2627 }
2628
2629 Point
Widget_origin(Handle self,Bool set,Point origin)2630 Widget_origin( Handle self, Bool set, Point origin)
2631 {
2632 if ( !set)
2633 return apc_widget_get_pos( self);
2634 apc_widget_set_pos( self, origin.x, origin.y);
2635 return origin;
2636 }
2637
2638 Bool
Widget_ownerBackColor(Handle self,Bool set,Bool ownerBackColor)2639 Widget_ownerBackColor( Handle self, Bool set, Bool ownerBackColor)
2640 {
2641 enter_method;
2642 if ( !set)
2643 return is_opt( optOwnerBackColor);
2644 opt_assign( optOwnerBackColor, ownerBackColor);
2645 if ( is_opt( optOwnerBackColor) && var-> owner)
2646 {
2647 my-> set_backColor( self, ((( PWidget) var-> owner)-> self)-> get_backColor( var-> owner));
2648 opt_set( optOwnerBackColor);
2649 my-> repaint ( self);
2650 }
2651 return false;
2652 }
2653
2654 Bool
Widget_ownerColor(Handle self,Bool set,Bool ownerColor)2655 Widget_ownerColor( Handle self, Bool set, Bool ownerColor)
2656 {
2657 enter_method;
2658 if ( !set)
2659 return is_opt( optOwnerColor);
2660 opt_assign( optOwnerColor, ownerColor);
2661 if ( is_opt( optOwnerColor) && var-> owner)
2662 {
2663 my-> set_color( self, ((( PWidget) var-> owner)-> self)-> get_color( var-> owner));
2664 opt_set( optOwnerColor);
2665 my-> repaint( self);
2666 }
2667 return false;
2668 }
2669
2670 Bool
Widget_ownerFont(Handle self,Bool set,Bool ownerFont)2671 Widget_ownerFont( Handle self, Bool set, Bool ownerFont )
2672 {
2673 enter_method;
2674 if ( !set)
2675 return is_opt( optOwnerFont);
2676 opt_assign( optOwnerFont, ownerFont);
2677 if ( is_opt( optOwnerFont) && var-> owner)
2678 {
2679 my-> set_font ( self, ((( PWidget) var-> owner)-> self)-> get_font ( var-> owner));
2680 opt_set( optOwnerFont);
2681 my-> repaint ( self);
2682 }
2683 return false;
2684 }
2685
2686 Bool
Widget_ownerHint(Handle self,Bool set,Bool ownerHint)2687 Widget_ownerHint( Handle self, Bool set, Bool ownerHint )
2688 {
2689 enter_method;
2690 if ( !set)
2691 return is_opt( optOwnerHint);
2692 opt_assign( optOwnerHint, ownerHint);
2693 if ( is_opt( optOwnerHint) && var-> owner)
2694 {
2695 my-> set_hint( self, ((( PWidget) var-> owner)-> self)-> get_hint ( var-> owner));
2696 opt_set( optOwnerHint);
2697 }
2698 return false;
2699 }
2700
2701 Bool
Widget_ownerPalette(Handle self,Bool set,Bool ownerPalette)2702 Widget_ownerPalette( Handle self, Bool set, Bool ownerPalette)
2703 {
2704 enter_method;
2705 if ( !set)
2706 return is_opt( optOwnerPalette);
2707 if ( ownerPalette) my-> set_palette( self, NULL_SV);
2708 opt_assign( optOwnerPalette, ownerPalette);
2709 return false;
2710 }
2711
2712 Bool
Widget_ownerShowHint(Handle self,Bool set,Bool ownerShowHint)2713 Widget_ownerShowHint( Handle self, Bool set, Bool ownerShowHint )
2714 {
2715 enter_method;
2716 if ( !set)
2717 return is_opt( optOwnerShowHint);
2718 opt_assign( optOwnerShowHint, ownerShowHint);
2719 if ( is_opt( optOwnerShowHint) && var-> owner)
2720 {
2721 my-> set_showHint( self, CWidget( var-> owner)-> get_showHint ( var-> owner));
2722 opt_set( optOwnerShowHint);
2723 }
2724 return false;
2725 }
2726
2727 SV *
Widget_palette(Handle self,Bool set,SV * palette)2728 Widget_palette( Handle self, Bool set, SV * palette)
2729 {
2730 int colors;
2731 if ( !set)
2732 return inherited-> palette( self, set, palette);
2733
2734 if ( var-> stage > csFrozen) return NULL_SV;
2735 if ( var-> handle == NULL_HANDLE) return NULL_SV; /* aware of call from Drawable::init */
2736
2737 colors = var-> palSize;
2738 free( var-> palette);
2739 var-> palette = prima_read_palette( &var-> palSize, palette);
2740 opt_clear( optOwnerPalette);
2741 if ( colors == 0 && var-> palSize == 0)
2742 return NULL_SV; /* do not bother apc */
2743 if ( opt_InPaint)
2744 apc_gp_set_palette( self);
2745 else
2746 apc_widget_set_palette( self);
2747 return NULL_SV;
2748 }
2749
2750 Handle
Widget_pointerIcon(Handle self,Bool set,Handle icon)2751 Widget_pointerIcon( Handle self, Bool set, Handle icon)
2752 {
2753 enter_method;
2754 Point hotSpot;
2755
2756 if ( var-> stage > csFrozen) return NULL_HANDLE;
2757
2758 if ( !set) {
2759 HV * profile = newHV();
2760 Handle icon = Object_create( "Prima::Icon", profile);
2761 sv_free(( SV *) profile);
2762 apc_pointer_get_bitmap( self, icon);
2763 --SvREFCNT( SvRV((( PAnyObject) icon)-> mate));
2764 return icon;
2765 }
2766
2767 if ( icon != NULL_HANDLE && !kind_of( icon, CIcon)) {
2768 warn("Illegal object reference passed to Widget::pointerIcon");
2769 return NULL_HANDLE;
2770 }
2771 hotSpot = my-> get_pointerHotSpot( self);
2772 apc_pointer_set_user( self, icon, hotSpot);
2773 if ( var-> pointerType == crUser) my-> first_that( self, (void*)sptr, NULL);
2774 return NULL_HANDLE;
2775 }
2776
2777 Point
Widget_pointerHotSpot(Handle self,Bool set,Point hotSpot)2778 Widget_pointerHotSpot( Handle self, Bool set, Point hotSpot)
2779 {
2780 enter_method;
2781 Handle icon;
2782 if ( !set)
2783 return apc_pointer_get_hot_spot( self);
2784 if ( var-> stage > csFrozen) return hotSpot;
2785 icon = my-> get_pointerIcon( self);
2786 apc_pointer_set_user( self, icon, hotSpot);
2787 if ( var-> pointerType == crUser) my-> first_that( self, (void*)sptr, NULL);
2788 return hotSpot;
2789 }
2790
2791 int
Widget_pointerType(Handle self,Bool set,int type)2792 Widget_pointerType( Handle self, Bool set, int type)
2793 {
2794 enter_method;
2795 if ( var-> stage > csFrozen) return 0;
2796 if ( !set)
2797 return var-> pointerType;
2798 var-> pointerType = type;
2799 apc_pointer_set_shape( self, type);
2800 my-> first_that( self, (void*)sptr, NULL);
2801 return type;
2802 }
2803
2804 Point
Widget_pointerPos(Handle self,Bool set,Point p)2805 Widget_pointerPos( Handle self, Bool set, Point p)
2806 {
2807 if ( !set) {
2808 p = apc_pointer_get_pos( self);
2809 apc_widget_map_points( self, false, 1, &p);
2810 return p;
2811 }
2812 apc_widget_map_points( self, true, 1, &p);
2813 apc_pointer_set_pos( self, p. x, p. y);
2814 return p;
2815 }
2816
2817 Handle
Widget_popup(Handle self,Bool set,Handle popup)2818 Widget_popup( Handle self, Bool set, Handle popup)
2819 {
2820 if ( var-> stage > csFrozen) return NULL_HANDLE;
2821 if ( !set)
2822 return var-> popupMenu;
2823
2824 if ( popup && !kind_of( popup, CPopup)) return NULL_HANDLE;
2825 if ( var->popupMenu ) unprotect_object(var-> popupMenu);
2826 var-> popupMenu = popup;
2827 if ( var->popupMenu ) protect_object(var-> popupMenu);
2828 return NULL_HANDLE;
2829 }
2830
2831 Color
Widget_popupColorIndex(Handle self,Bool set,int index,Color color)2832 Widget_popupColorIndex( Handle self, Bool set, int index, Color color)
2833 {
2834 if (( index < 0) || ( index > ciMaxId)) return clInvalid;
2835 if ( !set)
2836 return var-> popupColor[ index];
2837 if ((( color & clSysFlag) != 0) && (( color & wcMask) == 0)) color |= wcPopup;
2838 var-> popupColor[ index] = color;
2839 return color;
2840 }
2841
2842 SV *
Widget_popupItems(Handle self,Bool set,SV * popupItems)2843 Widget_popupItems( Handle self, Bool set, SV * popupItems)
2844 {
2845 dPROFILE;
2846 enter_method;
2847 if ( var-> stage > csFrozen) return NULL_SV;
2848 if ( !set)
2849 return var-> popupMenu ?
2850 CAbstractMenu( var-> popupMenu)-> get_items( var-> popupMenu, "", true) : NULL_SV;
2851
2852 if ( var-> popupMenu == NULL_HANDLE) {
2853 if ( SvTYPE( popupItems)) {
2854 HV * profile = newHV();
2855 pset_sv( items, popupItems);
2856 pset_H ( owner, self);
2857 my-> set_popup( self, create_instance( "Prima::Popup"));
2858 sv_free(( SV *) profile);
2859 }
2860 }
2861 else
2862 CAbstractMenu(var-> popupMenu)-> set_items(var-> popupMenu, popupItems);
2863 return popupItems;
2864 }
2865
2866
2867 Rect
Widget_rect(Handle self,Bool set,Rect r)2868 Widget_rect( Handle self, Bool set, Rect r)
2869 {
2870 enter_method;
2871 if ( !set) {
2872 Point p = my-> get_origin( self);
2873 Point s = my-> get_size( self);
2874 r. left = p. x;
2875 r. bottom = p. y;
2876 r. right = p. x + s. x;
2877 r. top = p. y + s. y;
2878 } else
2879 apc_widget_set_rect( self, r. left, r. bottom, r. right - r. left, r. top - r. bottom);
2880 return r;
2881 }
2882
2883 int
Widget_right(Handle self,Bool set,int right)2884 Widget_right( Handle self, Bool set, int right)
2885 {
2886 enter_method;
2887 Point p;
2888 Rect r = my-> get_rect( self);
2889 if ( !set)
2890 return r. right;
2891 p. x = r. left - r. right + right;
2892 p. y = r. bottom;
2893 my-> set_origin( self, p);
2894 return 0;
2895 }
2896
2897 Bool
Widget_scaleChildren(Handle self,Bool set,Bool scaleChildren)2898 Widget_scaleChildren( Handle self, Bool set, Bool scaleChildren)
2899 {
2900 if ( !set)
2901 return is_opt( optScaleChildren);
2902 opt_assign( optScaleChildren, scaleChildren);
2903 return false;
2904 }
2905
2906 Bool
Widget_selectable(Handle self,Bool set,Bool selectable)2907 Widget_selectable( Handle self, Bool set, Bool selectable)
2908 {
2909 if ( !set)
2910 return is_opt( optSelectable);
2911 opt_assign( optSelectable, selectable);
2912 return false;
2913 }
2914
2915 Bool
Widget_selected(Handle self,Bool set,Bool selected)2916 Widget_selected( Handle self, Bool set, Bool selected)
2917 {
2918 enter_method;
2919 if ( !set)
2920 return my-> get_selectedWidget( self) != NULL_HANDLE;
2921
2922 if ( var-> stage > csFrozen) return selected;
2923 if ( selected) {
2924 if ( is_opt( optSelectable) && !is_opt( optSystemSelectable)) {
2925 my-> set_focused( self, true);
2926 } else
2927 if ( var-> currentWidget) {
2928 PWidget w = ( PWidget) var-> currentWidget;
2929 if ( w-> options. optSystemSelectable && !w-> self-> get_clipOwner(( Handle) w))
2930 w-> self-> bring_to_front(( Handle) w); /* <- very uncertain !!!! */
2931 else
2932 w-> self-> set_selected(( Handle) w, true);
2933 } else
2934 if ( is_opt( optSystemSelectable)) {
2935 /* nothing to do with Widget, reserved for Window */
2936 }
2937 else {
2938 PWidget toFocus = ( PWidget) find_tabfoc( self);
2939 if ( toFocus)
2940 toFocus-> self-> set_selected(( Handle) toFocus, 1);
2941 else {
2942 /* if group has no selectable widgets and cannot be selected by itself, */
2943 /* process chain of bring_to_front(), followed by set_focused(1) call, if available */
2944 PWidget x = ( PWidget) var-> owner;
2945 List lst;
2946 int i;
2947
2948 list_create( &lst, 8, 8);
2949 while ( x) {
2950 if ( !toFocus && x-> options. optSelectable) {
2951 toFocus = x; /* choose closest owner to focus */
2952 break;
2953 }
2954 if (( Handle) x != application && !kind_of(( Handle) x, CWindow))
2955 list_insert_at( &lst, ( Handle) x, 0);
2956 x = ( PWidget) x-> owner;
2957 }
2958
2959 if ( toFocus)
2960 toFocus-> self-> set_focused(( Handle) toFocus, 1);
2961
2962 for ( i = 0; i < lst. count; i++) {
2963 PWidget v = ( PWidget) list_at( &lst, i);
2964 v-> self-> bring_to_front(( Handle) v);
2965 }
2966 list_destroy( &lst);
2967 }
2968 } /* end set_selected( true); */
2969 } else
2970 my-> set_focused( self, false);
2971 return selected;
2972 }
2973
2974 Handle
Widget_selectedWidget(Handle self,Bool set,Handle widget)2975 Widget_selectedWidget( Handle self, Bool set, Handle widget)
2976 {
2977 if ( var-> stage > csFrozen) return NULL_HANDLE;
2978
2979 if ( !set) {
2980 if ( var-> stage <= csNormal) {
2981 Handle foc = apc_widget_get_focused();
2982 PWidget f = ( PWidget) foc;
2983 while( f) {
2984 if (( Handle) f == self) return foc;
2985 f = ( PWidget) f-> owner;
2986 }
2987 }
2988 return NULL_HANDLE;
2989
2990 /* classic solution should be recursive and inheritant call */
2991 /* of get_selected() here, when Widget would return state of */
2992 /* child-group selected state until Widget::selected() called; */
2993 /* thus, each of them would call apc_widget_get_focused - that's expensive, */
2994 /* so that's the reason not to use classic object model here. */
2995 }
2996
2997 if ( widget) {
2998 if ( PWidget( widget)-> owner == self)
2999 CWidget( widget)-> set_selected( widget, true);
3000 } else {
3001 /* give selection up to hierarchy chain */
3002 Handle s = self;
3003 while ( s) {
3004 if ( CWidget( s)-> get_selectable( s)) {
3005 CWidget( s)-> set_selected( s, true);
3006 break;
3007 }
3008 s = PWidget( s)-> owner;
3009 }
3010 }
3011 return NULL_HANDLE;
3012 }
3013
3014 int
Widget_selectingButtons(Handle self,Bool set,int sb)3015 Widget_selectingButtons( Handle self, Bool set, int sb)
3016 {
3017 if ( !set)
3018 return var-> selectingButtons;
3019 return var-> selectingButtons = sb;
3020 }
3021
3022 Handle
Widget_shape(Handle self,Bool set,Handle mask)3023 Widget_shape( Handle self, Bool set, Handle mask)
3024 {
3025 if ( var-> stage > csFrozen) return NULL_HANDLE;
3026
3027 if ( !set) {
3028 if ( apc_widget_get_shape( self, NULL_HANDLE)) {
3029 HV * profile = newHV();
3030 Handle i = Object_create( "Prima::Region", profile);
3031 sv_free(( SV *) profile);
3032 apc_widget_get_shape( self, i);
3033 --SvREFCNT( SvRV((( PAnyObject) i)-> mate));
3034 return i;
3035 } else
3036 return NULL_HANDLE;
3037 }
3038
3039 if ( mask && kind_of( mask, CRegion)) {
3040 apc_widget_set_shape( self, mask);
3041 return NULL_HANDLE;
3042 }
3043
3044 if ( mask && !kind_of( mask, CImage)) {
3045 warn("Illegal object reference passed to Drawable::region");
3046 return NULL_HANDLE;
3047 }
3048
3049 if ( mask ) {
3050 Handle region;
3051 HV * profile = newHV();
3052
3053 pset_H( image, mask );
3054 region = Object_create("Prima::Region", profile);
3055 sv_free(( SV *) profile);
3056
3057 apc_widget_set_shape( self, region);
3058 Object_destroy(region);
3059 } else
3060 apc_widget_set_shape( self, NULL_HANDLE);
3061
3062 return NULL_HANDLE;
3063 }
3064
3065 Bool
Widget_showHint(Handle self,Bool set,Bool showHint)3066 Widget_showHint( Handle self, Bool set, Bool showHint )
3067 {
3068 enter_method;
3069 Bool oldShowHint = is_opt( optShowHint);
3070 if ( !set)
3071 return oldShowHint;
3072 my-> first_that( self, (void*)showhint_notify, &showHint);
3073 opt_clear( optOwnerShowHint);
3074 opt_assign( optShowHint, showHint);
3075 if ( application && !is_opt( optShowHint) && oldShowHint) my-> set_hintVisible( self, 0);
3076 return false;
3077 }
3078
3079 Point
Widget_size(Handle self,Bool set,Point size)3080 Widget_size( Handle self, Bool set, Point size)
3081 {
3082 if ( !set)
3083 return apc_widget_get_size( self);
3084 apc_widget_set_size( self, size.x, size.y);
3085 return size;
3086 }
3087
3088 Bool
Widget_syncPaint(Handle self,Bool set,Bool syncPaint)3089 Widget_syncPaint( Handle self, Bool set, Bool syncPaint)
3090 {
3091 HV * profile;
3092 enter_method;
3093 if ( !set)
3094 return apc_widget_get_sync_paint( self);
3095 profile = newHV();
3096 pset_i( syncPaint, syncPaint);
3097 my-> set( self, profile);
3098 sv_free(( SV *) profile);
3099 return false;
3100 }
3101
3102 int
Widget_tabOrder(Handle self,Bool set,int tabOrder)3103 Widget_tabOrder( Handle self, Bool set, int tabOrder)
3104 {
3105 int count;
3106 PWidget owner;
3107
3108 if ( var-> stage > csFrozen) return 0;
3109 if ( !set)
3110 return var-> tabOrder;
3111
3112 owner = ( PWidget) var-> owner;
3113 count = owner-> widgets. count;
3114 if ( tabOrder < 0) {
3115 int i, maxOrder = -1;
3116 /* finding maximal tabOrder value among the siblings */
3117 for ( i = 0; i < count; i++) {
3118 PWidget ctrl = ( PWidget) owner-> widgets. items[ i];
3119 if ( self == ( Handle) ctrl) continue;
3120 if ( maxOrder < ctrl-> tabOrder) maxOrder = ctrl-> tabOrder;
3121 }
3122 if ( maxOrder < INT_MAX) {
3123 var-> tabOrder = maxOrder + 1;
3124 return 0;
3125 }
3126 /* maximal value found, but has no use; finding gaps */
3127 {
3128 int j = 0;
3129 Bool match = 1;
3130 while ( !match) {
3131 for ( i = 0; i < count; i++) {
3132 PWidget ctrl = ( PWidget) owner-> widgets. items[ i];
3133 if ( self == ( Handle) ctrl) continue;
3134 if ( ctrl-> tabOrder == j) {
3135 match = 1;
3136 break;
3137 }
3138 }
3139 j++;
3140 }
3141 var-> tabOrder = j - 1;
3142 }
3143 } else {
3144 int i;
3145 Bool match = 0;
3146 /* finding exact match among the siblings */
3147 for ( i = 0; i < count; i++) {
3148 PWidget ctrl = ( PWidget) owner-> widgets. items[ i];
3149 if ( self == ( Handle) ctrl) continue;
3150 if ( ctrl-> tabOrder == tabOrder) {
3151 match = 1;
3152 break;
3153 }
3154 }
3155 if ( match)
3156 /* incrementing all tabOrders that greater than ours */
3157 for ( i = 0; i < count; i++) {
3158 PWidget ctrl = ( PWidget) owner-> widgets. items[ i];
3159 if ( self == ( Handle) ctrl) continue;
3160 if ( ctrl-> tabOrder >= tabOrder) ctrl-> tabOrder++;
3161 }
3162 var-> tabOrder = tabOrder;
3163 }
3164 return 0;
3165 }
3166
3167 Bool
Widget_tabStop(Handle self,Bool set,Bool stop)3168 Widget_tabStop( Handle self, Bool set, Bool stop)
3169 {
3170 if ( !set)
3171 return is_opt( optTabStop);
3172 opt_assign( optTabStop, stop);
3173 return false;
3174 }
3175
3176 Bool
Widget_transparent(Handle self,Bool set,Bool transparent)3177 Widget_transparent( Handle self, Bool set, Bool transparent)
3178 {
3179 HV * profile;
3180 enter_method;
3181 if ( !set)
3182 return apc_widget_get_transparent( self);
3183 profile = newHV();
3184 pset_i( transparent, transparent);
3185 my-> set( self, profile);
3186 sv_free(( SV *) profile);
3187 return false;
3188 }
3189
3190 SV *
Widget_get_text(Handle self)3191 Widget_get_text( Handle self)
3192 {
3193 return newSVsv(var->text);
3194 }
3195
3196 void
Widget_set_text(Handle self,SV * text)3197 Widget_set_text( Handle self, SV *text)
3198 {
3199 if ( var-> stage > csFrozen) return;
3200 if ( var-> text ) sv_free( var-> text );
3201 var-> text = newSVsv(text);
3202 }
3203
3204 int
Widget_top(Handle self,Bool set,int top)3205 Widget_top( Handle self, Bool set, int top)
3206 {
3207 enter_method;
3208 Point p;
3209 Rect r = my-> get_rect( self);
3210 if ( !set)
3211 return r. top;
3212 p. x = r. left;
3213 p. y = r. bottom - r. top + top;
3214 my-> set_origin( self, p);
3215 return 0;
3216 }
3217
3218 Bool
Widget_visible(Handle self,Bool set,Bool visible)3219 Widget_visible( Handle self, Bool set, Bool visible)
3220 {
3221 return set ?
3222 apc_widget_set_visible( self, visible) :
3223 apc_widget_is_visible( self);
3224 }
3225
3226 int
Widget_widgetClass(Handle self,Bool set,int widgetClass)3227 Widget_widgetClass( Handle self, Bool set, int widgetClass)
3228 {
3229 enter_method;
3230 if ( !set)
3231 return var-> widgetClass;
3232 var-> widgetClass = widgetClass;
3233 my-> repaint( self);
3234 return 0;
3235 }
3236
3237 /* XS section */
XS(Widget_client_to_screen_FROMPERL)3238 XS( Widget_client_to_screen_FROMPERL)
3239 {
3240 dXSARGS;
3241 Handle self;
3242 int i, count;
3243 Point * points;
3244
3245 if (( items % 2) != 1)
3246 croak ("Invalid usage of Widget::client_to_screen");
3247 SP -= items;
3248 self = gimme_the_mate( ST( 0));
3249 if ( self == NULL_HANDLE)
3250 croak( "Illegal object reference passed to Widget::client_to_screen");
3251 count = ( items - 1) / 2;
3252 if ( !( points = allocn( Point, count))) {
3253 PUTBACK;
3254 return;
3255 }
3256 for ( i = 0; i < count; i++) {
3257 points[i]. x = SvIV( ST( i * 2 + 1));
3258 points[i]. y = SvIV( ST( i * 2 + 2));
3259 }
3260 apc_widget_map_points( self, true, count, points);
3261 EXTEND( sp, count * 2);
3262 for ( i = 0; i < count; i++) {
3263 PUSHs( sv_2mortal( newSViv( points[i].x)));
3264 PUSHs( sv_2mortal( newSViv( points[i].y)));
3265 }
3266 PUTBACK;
3267 free( points);
3268 return;
3269 }
3270
XS(Widget_screen_to_client_FROMPERL)3271 XS( Widget_screen_to_client_FROMPERL)
3272 {
3273 dXSARGS;
3274 Handle self;
3275 int i, count;
3276 Point * points;
3277
3278 if (( items % 2) != 1)
3279 croak ("Invalid usage of Widget::screen_to_client");
3280 SP -= items;
3281 self = gimme_the_mate( ST( 0));
3282 if ( self == NULL_HANDLE)
3283 croak( "Illegal object reference passed to Widget::screen_to_client");
3284 count = ( items - 1) / 2;
3285 if ( !( points = allocn( Point, count))) {
3286 PUTBACK;
3287 return;
3288 }
3289 for ( i = 0; i < count; i++) {
3290 points[i]. x = SvIV( ST( i * 2 + 1));
3291 points[i]. y = SvIV( ST( i * 2 + 2));
3292 }
3293 apc_widget_map_points( self, false, count, points);
3294 EXTEND( sp, count * 2);
3295 for ( i = 0; i < count; i++) {
3296 PUSHs( sv_2mortal( newSViv( points[i].x)));
3297 PUSHs( sv_2mortal( newSViv( points[i].y)));
3298 }
3299 PUTBACK;
3300 free( points);
3301 return;
3302 }
3303
3304
XS(Widget_get_widgets_FROMPERL)3305 XS( Widget_get_widgets_FROMPERL)
3306 {
3307 dXSARGS;
3308 Handle self;
3309 Handle * list;
3310 int i, count;
3311
3312 if ( items != 1)
3313 croak ("Invalid usage of Widget.get_widgets");
3314 SP -= items;
3315 self = gimme_the_mate( ST( 0));
3316 if ( self == NULL_HANDLE)
3317 croak( "Illegal object reference passed to Widget.get_widgets");
3318 count = var-> widgets. count;
3319 list = var-> widgets. items;
3320 EXTEND( sp, count);
3321 for ( i = 0; i < count; i++)
3322 PUSHs( sv_2mortal( newSVsv((( PAnyObject) list[ i])-> mate)));
3323 PUTBACK;
3324 return;
3325 }
3326
Widget_get_widgets(Handle self)3327 void Widget_get_widgets ( Handle self) { warn("Invalid call of Widget::get_widgets"); }
Widget_get_widgets_REDEFINED(Handle self)3328 void Widget_get_widgets_REDEFINED( Handle self) { warn("Invalid call of Widget::get_widgets"); }
Widget_screen_to_client(Handle self)3329 void Widget_screen_to_client ( Handle self) { warn("Invalid call of Widget::screen_to_client"); }
Widget_screen_to_client_REDEFINED(Handle self)3330 void Widget_screen_to_client_REDEFINED ( Handle self) { warn("Invalid call of Widget::screen_to_client"); }
Widget_client_to_screen(Handle self)3331 void Widget_client_to_screen ( Handle self) { warn("Invalid call of Widget::screen_to_client"); }
Widget_client_to_screen_REDEFINED(Handle self)3332 void Widget_client_to_screen_REDEFINED ( Handle self) { warn("Invalid call of Widget::screen_to_client"); }
3333
3334 #ifdef __cplusplus
3335 }
3336 #endif
3337