Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / muimaster / classes / area.c
blob9f603c5fc490d5e0258c4007d18952117e8cc431
1 /*
2 Copyright 1999, David Le Corfec.
3 Copyright 2002-2006, The AROS Development Team.
4 All rights reserved.
6 $Id$
7 */
9 #include <stdlib.h>
10 #include <string.h>
11 #include <exec/types.h>
12 #include <graphics/gfxmacros.h>
13 #include <intuition/imageclass.h>
14 #include <libraries/gadtools.h>
16 #include <clib/alib_protos.h>
17 #include <proto/exec.h>
18 #include <proto/intuition.h>
19 #include <proto/graphics.h>
20 #include <proto/utility.h>
21 #include <proto/muimaster.h>
23 extern struct Library *MUIMasterBase;
24 #include "muimaster_intern.h"
26 #include "mui.h"
27 #include "support.h"
28 #include "imspec.h"
29 #include "menu.h"
30 #include "prefs.h"
31 #include "font.h"
32 #include "textengine.h"
33 #include "bubbleengine.h"
34 #include "datatypescache.h"
37 // #define MYDEBUG 1
38 #include "debug.h"
41 Area.mui/MUIA_Background done
42 Area.mui/MUIA_BottomEdge done
43 Area.mui/MUIA_ContextMenu done
44 Area.mui/MUIA_ContextMenuTrigger
45 Area.mui/MUIA_ControlChar done
46 Area.mui/MUIA_CycleChain done
47 Area.mui/MUIA_Disabled done
48 Area.mui/MUIA_Draggable done
49 Area.mui/MUIA_Dropable done
50 Area.mui/MUIA_ExportID
51 Area.mui/MUIA_FillArea done
52 Area.mui/MUIA_FixHeight done
53 Area.mui/MUIA_FixHeightTxt done
54 Area.mui/MUIA_FixWidth done
55 Area.mui/MUIA_FixWidthTxt done
56 Area.mui/MUIA_Font done
57 Area.mui/MUIA_Frame done
58 Area.mui/MUIA_FramePhantomHoriz done
59 Area.mui/MUIA_FrameTitle done
60 Area.mui/MUIA_Height done
61 Area.mui/MUIA_HorizDisappear
62 Area.mui/MUIA_HorizWeight done
63 Area.mui/MUIA_InnerBottom done
64 Area.mui/MUIA_InnerLeft done
65 Area.mui/MUIA_InnerRight done
66 Area.mui/MUIA_InnerTop done
67 Area.mui/MUIA_InputMode done
68 Area.mui/MUIA_LeftEdge done
69 Area.mui/MUIA_MaxHeight done
70 Area.mui/MUIA_MaxWidth done
71 Area.mui/MUIA_Pressed done
72 Area.mui/MUIA_RightEdge done
73 Area.mui/MUIA_Selected done
74 Area.mui/MUIA_ShortHelp done
75 Area.mui/MUIA_ShowMe done
76 Area.mui/MUIA_ShowSelState done (I only)
77 Area.mui/MUIA_Timer done
78 Area.mui/MUIA_TopEdge done
79 Area.mui/MUIA_VertDisappear
80 Area.mui/MUIA_VertWeight done
81 Area.mui/MUIA_Weight done
82 Area.mui/MUIA_Width done
83 Area.mui/MUIA_Window done
84 Area.mui/MUIA_WindowObject done
86 Area.mui/MUIM_AskMinMax done
87 Area.mui/MUIM_Cleanup done
88 Area.mui/MUIM_ContextMenuBuild done
89 Area.mui/MUIM_ContextMenuChoice done
90 Area.mui/MUIM_CreateBubble
91 Area.mui/MUIM_CreateShortHelp
92 Area.mui/MUIM_DeleteBubble
93 Area.mui/MUIM_DeleteShortHelp
94 Area.mui/MUIM_DragBegin
95 Area.mui/MUIM_DragDrop done
96 Area.mui/MUIM_DragFinish
97 Area.mui/MUIM_DragQuery done
98 Area.mui/MUIM_DragReport
99 Area.mui/MUIM_Draw done
100 Area.mui/MUIM_DrawBackground done
101 Area.mui/MUIM_HandleEvent done
102 Area.mui/MUIM_HandleInput
103 Area.mui/MUIM_Hide done
104 Area.mui/MUIM_Setup done
105 Area.mui/MUIM_Show done
108 static const int __version = 1;
109 static const int __revision = 1;
111 //#ifdef DEBUG
112 //static STRPTR zune_area_to_string (Object *area);
113 //#endif
115 static const struct MUI_FrameSpec_intern *get_intframe(
116 Object *obj,
117 struct MUI_AreaData *data,
118 struct MUI_FrameSpec_intern *tempstore);
119 static void set_inner_sizes (Object *obj, struct MUI_AreaData *data);
120 static void set_title_sizes (Object *obj, struct MUI_AreaData *data);
122 static void area_update_msizes(Object *obj, struct MUI_AreaData *data,
123 const struct MUI_FrameSpec_intern *frame,
124 const struct ZuneFrameGfx *zframe);
125 static void setup_control_char (struct MUI_AreaData *data, Object *obj,
126 struct IClass *cl);
127 static void cleanup_control_char (struct MUI_AreaData *data, Object *obj);
129 //static void setup_cycle_chain (struct MUI_AreaData *data, Object *obj);
130 //static void cleanup_cycle_chain (struct MUI_AreaData *data, Object *obj);
132 #define ZUNE_FOCUS_TYPE_ACTIVE_OBJ 0
133 #define ZUNE_FOCUS_TYPE_DROP_OBJ 1
135 static void _zune_focus_new(Object *obj, int type)
137 Object *parent;
138 struct RastPort *rp;
139 UWORD oldDrPt;
141 //bug("_zune_focus_new 1 %p\n", obj);
143 if (NULL == obj || !(_flags(obj) & MADF_CANDRAW))
144 return;
146 parent = _parent(obj);
147 rp = _rp(obj);
148 oldDrPt = rp->LinePtrn;
150 int x1 = _left(obj);
151 int y1 = _top(obj);
152 int x2 = _left(obj) + _width(obj) -1;
153 int y2 = _top(obj) + _height(obj) -1;
155 if (!parent || parent == _win(obj)) return;
157 SetABPenDrMd(rp, _pens(obj)[MPEN_SHINE], _pens(obj)[MPEN_SHADOW], JAM2);
159 if (type == ZUNE_FOCUS_TYPE_ACTIVE_OBJ)
161 SetDrPt(rp, 0xCCCC);
162 x1--; y1--; x2++; y2++;
164 else
166 SetDrPt(rp,0xF0F0);
169 Move(rp, x1, y1);
170 Draw(rp, x2, y1);
171 Draw(rp, x2, y2);
172 Draw(rp, x1, y2);
173 Draw(rp, x1, y1);
174 SetDrPt(rp, oldDrPt);
177 static void _zune_focus_destroy(Object *obj, int type)
179 Object *parent;
181 //bug("_zune_focus_destroy 1 %p\n", obj);
183 if (NULL == obj || !(_flags(obj) & MADF_CANDRAW))
184 return;
186 parent = _parent(obj);
187 int x1 = _left(obj);
188 int y1 = _top(obj);
189 int x2 = _left(obj) + _width(obj) - 1;
190 int y2 = _top(obj) + _height(obj) - 1;
191 int width;
192 int height;
194 if (type == ZUNE_FOCUS_TYPE_ACTIVE_OBJ)
196 if (!parent || parent == _win(obj)) return;
198 x1--; y1--; x2++; y2++;
199 width = x2 - x1 + 1;
200 height = y2 - y1 + 1;
202 DoMethod(parent, MUIM_DrawBackground, x1, y1, width, 1, x1, y1, 0);
203 DoMethod(parent, MUIM_DrawBackground, x2, y1, 1, height, x2, y1, 0);
204 DoMethod(parent, MUIM_DrawBackground, x1, y2, width, 1, x1, y2, 0);
205 DoMethod(parent, MUIM_DrawBackground, x1, y1, 1, height, x1, y1, 0);
207 else
209 struct Region *region;
210 struct Rectangle rect;
211 APTR clip = NULL;
213 region = NewRegion();
214 if (region)
216 rect.MinX = _left(obj);
217 rect.MinY = _top(obj);
218 rect.MaxX = _right(obj);
219 rect.MaxY = _top(obj);
221 OrRectRegion(region, &rect);
223 rect.MinX = _right(obj);
224 rect.MinY = _top(obj);
225 rect.MaxX = _right(obj);
226 rect.MaxY = _bottom(obj);
228 OrRectRegion(region, &rect);
230 rect.MinX = _left(obj);
231 rect.MinY = _bottom(obj);
232 rect.MaxX = _right(obj);
233 rect.MaxY = _bottom(obj);
235 OrRectRegion(region, &rect);
237 rect.MinX = _left(obj);
238 rect.MinY = _top(obj);
239 rect.MaxX = _left(obj);
240 rect.MaxY = _bottom(obj);
242 OrRectRegion(region, &rect);
244 clip = MUI_AddClipRegion(muiRenderInfo(obj), region);
246 } /* if (region) */
248 MUI_Redraw(obj, MADF_DRAWOBJECT);
250 if (region)
252 MUI_RemoveClipRegion(muiRenderInfo(obj), clip);
260 /**************************************************************************
261 OM_NEW
262 **************************************************************************/
263 static IPTR Area__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
265 struct MUI_AreaData *data;
266 struct TagItem *tags,*tag;
268 obj = (Object *)DoSuperMethodA(cl, obj, (Msg)msg);
269 if (!obj) return FALSE;
271 /* Initial local instance data */
272 data = INST_DATA(cl, obj);
274 data->mad_Flags = MADF_FILLAREA | MADF_SHOWME | MADF_SHOWSELSTATE | MADF_DROPABLE;
275 data->mad_HorizWeight = data->mad_VertWeight = 100;
276 data->mad_InputMode = MUIV_InputMode_None;
278 /* parse initial taglist */
280 for (tags = msg->ops_AttrList; (tag = NextTagItem((const struct TagItem **)&tags)); )
282 switch (tag->ti_Tag)
284 case MUIA_Background:
286 data->mad_Flags |= MADF_OWNBG;
287 if (data->mad_BackgroundSpec)
289 zune_image_spec_free(data->mad_BackgroundSpec);
291 data->mad_BackgroundSpec = zune_image_spec_duplicate(tag->ti_Data);
293 break;
295 case MUIA_ControlChar:
296 data->mad_ControlChar = tag->ti_Data;
297 break;
299 case MUIA_CycleChain:
300 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_CYCLECHAIN);
301 break;
303 case MUIA_Disabled:
304 case MUIA_NestedDisabled:
305 if (tag->ti_Data)
307 data->mad_DisableCount = 1;
309 break;
311 case MUIA_FillArea:
312 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_FILLAREA);
313 break;
315 case MUIA_Draggable:
316 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DRAGGABLE);
317 break;
319 case MUIA_Dropable:
320 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DROPABLE);
321 break;
323 case MUIA_FixHeight:
324 data->mad_Flags |= MADF_FIXHEIGHT;
325 data->mad_HardHeight = tag->ti_Data;
326 break;
328 case MUIA_FixHeightTxt:
329 data->mad_HardHeightTxt = (STRPTR)tag->ti_Data;
330 break;
332 case MUIA_FixWidth:
333 data->mad_Flags |= MADF_FIXWIDTH;
334 data->mad_HardWidth = tag->ti_Data;
335 break;
337 case MUIA_FixWidthTxt:
338 data->mad_HardWidthTxt = (STRPTR)tag->ti_Data;
339 break;
341 case MUIA_Font:
342 data->mad_FontPreset = tag->ti_Data;
343 break;
345 case MUIA_Frame:
346 data->mad_Frame = tag->ti_Data;
347 break;
349 case MUIA_FramePhantomHoriz:
350 data->mad_Flags |= MADF_FRAMEPHANTOM;
351 break;
353 case MUIA_FrameTitle:
354 data->mad_FrameTitle = (STRPTR)tag->ti_Data;
355 break;
357 case MUIA_HorizWeight:
358 data->mad_HorizWeight = tag->ti_Data;
359 break;
361 case MUIA_InnerBottom:
362 data->mad_Flags |= MADF_INNERBOTTOM;
363 data->mad_InnerBottom = CLAMP((IPTR)tag->ti_Data, 0, 32);
364 break;
366 case MUIA_InnerLeft:
367 data->mad_Flags |= MADF_INNERLEFT;
368 data->mad_InnerLeft = CLAMP((IPTR)tag->ti_Data, 0, 32);
369 break;
371 case MUIA_InnerRight:
372 data->mad_Flags |= MADF_INNERRIGHT;
373 data->mad_InnerRight = CLAMP((IPTR)tag->ti_Data, 0, 32);
374 break;
376 case MUIA_InnerTop:
377 data->mad_Flags |= MADF_INNERTOP;
378 data->mad_InnerTop = CLAMP((IPTR)tag->ti_Data, 0, 32);
379 break;
381 case MUIA_InputMode:
382 data->mad_InputMode = tag->ti_Data;
383 break;
385 case MUIA_MaxHeight:
386 data->mad_Flags |= MADF_MAXHEIGHT;
387 data->mad_HardHeight = tag->ti_Data;
388 break;
390 case MUIA_MaxWidth:
391 data->mad_Flags |= MADF_MAXWIDTH;
392 data->mad_HardWidth = tag->ti_Data;
393 break;
395 case MUIA_Selected:
396 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_SELECTED);
397 break;
399 case MUIA_ShortHelp:
400 data->mad_ShortHelp = (STRPTR)tag->ti_Data;
401 break;
403 case MUIA_ShowMe:
404 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_SHOWME);
405 break;
407 case MUIA_ShowSelState:
408 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_SHOWSELSTATE);
409 break;
411 case MUIA_VertWeight:
412 data->mad_VertWeight = tag->ti_Data;
413 break;
415 case MUIA_Weight:
416 data->mad_HorizWeight = data->mad_VertWeight = tag->ti_Data;
417 break;
419 case MUIA_ContextMenu:
420 data->mad_ContextMenu = (Object*)tag->ti_Data;
421 break;
425 /* In Soliton MUIA_Selected was setted to MUIV_InputMode_RelVerify (=1) for MUIA_Input_Mode
426 ** MUIV_InputMode_RelVerify which is wrong of course but MUI seems to filter this out
427 ** so we have to do it also
429 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
431 if (data->mad_Flags & MADF_SELECTED)
432 D(bug("MUIA_Selected was set in OM_NEW, although being in MUIV_InputMode_RelVerify\n"));
433 data->mad_Flags &= ~MADF_SELECTED;
436 data->mad_ehn.ehn_Events = 0; /* Will be filled on demand */
437 data->mad_ehn.ehn_Priority = -5;
438 /* Please also send mui key events to us, no idea if mui handles this like this */
439 data->mad_ehn.ehn_Flags = MUI_EHF_ALWAYSKEYS;
440 data->mad_ehn.ehn_Object = obj;
441 data->mad_ehn.ehn_Class = cl;
443 data->mad_hiehn.ehn_Events = 0;
444 data->mad_hiehn.ehn_Priority = -10;
445 data->mad_hiehn.ehn_Flags = MUI_EHF_HANDLEINPUT;
446 data->mad_hiehn.ehn_Object = obj;
447 data->mad_hiehn.ehn_Class = 0;
449 return (IPTR)obj;
452 /**************************************************************************
453 OM_DISPOSE
454 **************************************************************************/
455 static IPTR Area__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
457 struct MUI_AreaData *data = INST_DATA(cl, obj);
459 zune_image_spec_free(data->mad_BackgroundSpec); /* Safe to call this with NULL */
461 return DoSuperMethodA(cl, obj, msg);
465 /**************************************************************************
466 OM_SET
467 **************************************************************************/
468 static IPTR Area__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
470 struct MUI_AreaData *data = INST_DATA(cl, obj);
471 struct TagItem *tags = msg->ops_AttrList;
472 struct TagItem *tag;
473 CONST_STRPTR old_backgroundspec;
475 int change_disable = 0; /* Has the disable state changed? */
477 while ((tag = NextTagItem((const struct TagItem **)&tags)) != NULL)
479 switch (tag->ti_Tag)
481 case MUIA_Background:
482 old_backgroundspec = data->mad_BackgroundSpec;
483 data->mad_BackgroundSpec = zune_image_spec_duplicate(tag->ti_Data);
484 if (!data->mad_BackgroundSpec)
486 /* Out of memory */
487 data->mad_BackgroundSpec = old_backgroundspec;
488 break;
491 data->mad_Flags |= MADF_OWNBG;
493 if (old_backgroundspec && (strcmp(data->mad_BackgroundSpec, old_backgroundspec) == 0))
495 /* New background does not differ from old one */
496 zune_image_spec_free(old_backgroundspec);
497 tag->ti_Tag = TAG_IGNORE;
498 break;
501 zune_image_spec_free(old_backgroundspec);
503 if (data->mad_Background)
505 if (_flags(obj) & MADF_CANDRAW)
507 zune_imspec_hide(data->mad_Background);
509 if (_flags(obj) & MADF_SETUP)
511 zune_imspec_cleanup(data->mad_Background);
512 data->mad_Background = NULL;
516 if (_flags(obj) & MADF_SETUP)
518 data->mad_Background =
519 zune_imspec_setup((IPTR)data->mad_BackgroundSpec,
520 muiRenderInfo(obj));
522 if (_flags(obj) & MADF_CANDRAW)
524 zune_imspec_show(data->mad_Background, obj);
526 MUI_Redraw(obj, MADF_DRAWOBJECT);
527 break;
529 case MUIA_FillArea:
530 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_FILLAREA);
531 break;
533 case MUIA_Frame:
534 /* this is not documented in MUI but it is possible,
535 and needed to suppress frame for external images */
536 data->mad_Frame = tag->ti_Data;
537 if (muiGlobalInfo(obj))
539 set_inner_sizes(obj, data);
540 set_title_sizes(obj, data);
542 break;
544 case MUIA_ControlChar:
545 if (_flags(obj) & MADF_SETUP)
546 cleanup_control_char(data, obj);
547 data->mad_ControlChar = tag->ti_Data;
548 if (_flags(obj) & MADF_SETUP)
549 setup_control_char(data, obj, cl);
550 break;
552 case MUIA_CycleChain:
553 // if (data->mad_InputMode == MUIV_InputMode_None)
554 // break;
556 if ((!(_flags(obj) & MADF_CYCLECHAIN) && tag->ti_Data)
557 || ((_flags(obj) & MADF_CYCLECHAIN) && !tag->ti_Data))
559 if (_flags(obj) & MADF_SETUP)
561 cleanup_control_char(data,obj);
562 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_CYCLECHAIN);
563 setup_control_char(data,obj,cl);
564 } else _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_CYCLECHAIN);
566 break;
568 case MUIA_Disabled:
569 if (tag->ti_Data)
571 if (!data->mad_DisableCount)
573 data->mad_DisableCount = 1;
574 change_disable = 1;
577 else
579 if (data->mad_DisableCount)
581 data->mad_DisableCount = 0;
582 change_disable = 1;
585 break;
587 case MUIA_NestedDisabled:
588 if (tag->ti_Data)
590 if (!data->mad_DisableCount) change_disable = 1;
591 data->mad_DisableCount++;
593 else
595 if (data->mad_DisableCount)
597 data->mad_DisableCount--;
598 if (!data->mad_DisableCount) change_disable = 1;
601 break;
604 case MUIA_HorizWeight:
605 data->mad_HorizWeight = tag->ti_Data;
606 break;
608 case MUIA_Pressed:
609 if (tag->ti_Data)
610 data->mad_Flags |= MADF_PRESSED;
611 else
612 data->mad_Flags &= ~MADF_PRESSED;
613 break;
615 case MUIA_ShortHelp:
616 data->mad_ShortHelp = (STRPTR)tag->ti_Data;
617 break;
619 case MUIA_ShowMe:
621 ULONG oldflags = data->mad_Flags;
622 int recalc = 0;
624 if (tag->ti_Data) data->mad_Flags |= MADF_SHOWME;
625 else data->mad_Flags &= ~MADF_SHOWME;
627 if (oldflags != data->mad_Flags)
629 if (!tag->ti_Data)
631 /* Should be made invisible, so send a MUIM_Hide and then a MUIM_Cleanup to the object if needed,
632 ** as objects with MUIA_ShowMe to false neighter get MUIM_Setup nor MUIM_Show */
633 if (_flags(obj)&MADF_CANDRAW)
635 DoHideMethod(obj);
636 recalc = 1;
638 #if 0 /* SHOWME affects only show/hide */
639 if (_flags(obj)&MADF_SETUP) DoMethod(obj,MUIM_Cleanup);
640 #endif
642 else
644 Object *parent = _parent(obj); /* Will be NULL if direct child of a window! */
645 if (parent)
647 #if 0 /* SHOWME affects only show/hide */
648 if (_flags(parent) & MADF_SETUP) DoSetupMethod(obj,muiRenderInfo(parent));
649 #endif
650 if (_flags(parent) & MADF_CANDRAW)
652 DoShowMethod(obj);
653 recalc = 1;
655 } else
657 /* Check if window is open... */
661 if (recalc && muiRenderInfo(obj)) /* If renderinfo is NULL _win(obj) does not work (crash) */
663 DoMethod(_win(obj), MUIM_Window_RecalcDisplay, (IPTR)_parent(obj));
667 break;
669 case MUIA_Selected:
670 /* D(bug(" Area_Set(%p) :
671 MUIA_Selected val=%ld sss=%d\n", obj, tag->ti_Data, !!(data->mad_Flags & MADF_SHOWSELSTATE)));
673 if (tag->ti_Data) data->mad_Flags |= MADF_SELECTED;
674 else data->mad_Flags &= ~MADF_SELECTED;
675 /* if (data->mad_Flags & MADF_SHOWSELSTATE) */
676 MUI_Redraw(obj, MADF_DRAWOBJECT);
677 /* else */
678 /* MUI_Redraw(obj, MADF_DRAWUPDATE); */
679 break;
681 case MUIA_Timer:
682 data->mad_Timeval = tag->ti_Data;
683 break;
685 case MUIA_VertWeight:
686 data->mad_VertWeight = tag->ti_Data;
687 break;
689 case MUIA_Draggable:
690 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DRAGGABLE);
691 break;
693 case MUIA_Dropable:
694 _handle_bool_tag(data->mad_Flags, tag->ti_Data, MADF_DROPABLE);
695 break;
697 case MUIA_ContextMenu:
698 data->mad_ContextMenu = (Object*)tag->ti_Data;
699 break;
701 case MUIA_Font:
702 data->mad_FontPreset = tag->ti_Data;
703 break;
705 case MUIA_InputMode:
706 data->mad_InputMode = tag->ti_Data;
707 break;
712 if (change_disable)
714 MUI_Redraw(obj, MADF_DRAWOBJECT);
717 return DoSuperMethodA(cl, obj, (Msg)msg);
721 /**************************************************************************
722 OM_GET
723 **************************************************************************/
724 static IPTR Area__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
726 #define STORE *(msg->opg_Storage)
728 struct MUI_AreaData *data = INST_DATA(cl, obj);
730 switch(msg->opg_AttrID)
732 case MUIA_Background:
733 STORE = (IPTR)data->mad_Background;
734 return TRUE;
736 case MUIA_BottomEdge:
737 STORE = (IPTR)_bottom(obj);
738 return TRUE;
740 case MUIA_ControlChar:
741 STORE = data->mad_ControlChar;
742 return TRUE;
744 case MUIA_CycleChain:
745 STORE = ((data->mad_Flags & MADF_CYCLECHAIN) != 0);
746 return TRUE;
748 case MUIA_Disabled:
749 case MUIA_NestedDisabled:
750 STORE = !!data->mad_DisableCount; /* BOOLEAN */
751 return TRUE;
753 case MUIA_Font:
754 STORE = (IPTR)data->mad_FontPreset;
755 return TRUE;
757 case MUIA_Height:
758 STORE = (IPTR)_height(obj);
759 return TRUE;
761 case MUIA_HorizWeight:
762 STORE = (IPTR)data->mad_HorizWeight;
763 return TRUE;
765 case MUIA_InnerBottom:
766 STORE = (IPTR)data->mad_InnerBottom;
767 return TRUE;
769 case MUIA_InnerLeft:
770 STORE = (IPTR)data->mad_InnerLeft;
771 return TRUE;
773 case MUIA_InnerRight:
774 STORE = (IPTR)data->mad_InnerRight;
775 return TRUE;
777 case MUIA_InnerTop:
778 STORE = (IPTR)data->mad_InnerTop;
779 return TRUE;
781 case MUIA_LeftEdge:
782 STORE = (IPTR)_left(obj);
783 return TRUE;
785 case MUIA_Pressed:
786 STORE = !!(data->mad_Flags & MADF_PRESSED);
787 return TRUE;
789 case MUIA_RightEdge:
790 STORE = (IPTR)_right(obj);
791 return TRUE;
793 case MUIA_Selected:
794 STORE = !!(data->mad_Flags & MADF_SELECTED);
795 return TRUE;
797 case MUIA_ShortHelp:
798 STORE = (IPTR)data->mad_ShortHelp;
799 return TRUE;
801 case MUIA_ShowMe:
802 STORE = (data->mad_Flags & MADF_SHOWME);
803 return TRUE;
805 case MUIA_Timer:
806 return TRUE;
808 case MUIA_TopEdge:
809 STORE = (IPTR)_top(obj);
810 return TRUE;
812 case MUIA_VertWeight:
813 STORE = (IPTR)data->mad_VertWeight;
814 return TRUE;
816 case MUIA_Width:
817 STORE = (IPTR)_width(obj);
818 return TRUE;
820 case MUIA_Window:
821 if (muiAreaData(obj)->mad_RenderInfo)
822 STORE = (IPTR)_window(obj);
823 else
824 STORE = 0L;
825 return TRUE;
827 case MUIA_WindowObject:
828 if (muiAreaData(obj)->mad_RenderInfo)
829 STORE = (IPTR)_win(obj);
830 else
831 STORE = 0L;
832 return TRUE;
834 case MUIA_ContextMenu:
835 STORE = (IPTR)data->mad_ContextMenu;
836 return TRUE;
838 case MUIA_Frame:
839 STORE = (IPTR)data->mad_Frame;
840 return TRUE;
843 return(DoSuperMethodA(cl, obj, (Msg) msg));
844 #undef STORE
848 /**************************************************************************
849 MUIM_AskMinMax
850 **************************************************************************/
851 static IPTR Area__MUIM_AskMinMax(struct IClass *cl, Object *obj, struct MUIP_AskMinMax *msg)
853 struct MUI_AreaData *data = INST_DATA(cl, obj);
854 const struct ZuneFrameGfx *zframe;
855 const struct MUI_FrameSpec_intern *frame;
856 struct MUI_FrameSpec_intern tempframe;
858 frame = get_intframe(obj, data, &tempframe);
859 zframe = zune_zframe_get(obj, frame);
861 area_update_msizes(obj, data, frame, zframe);
863 msg->MinMaxInfo->MinWidth = _subwidth(obj);
864 msg->MinMaxInfo->MinHeight = _subheight(obj);
866 msg->MinMaxInfo->MaxWidth = msg->MinMaxInfo->MinWidth;
867 msg->MinMaxInfo->MaxHeight = msg->MinMaxInfo->MinHeight;
868 msg->MinMaxInfo->DefWidth = msg->MinMaxInfo->MinWidth;
869 msg->MinMaxInfo->DefHeight = msg->MinMaxInfo->MinHeight;
871 /* D(bug("Area_AskMinMax 0x%lx (%s): Min=%ldx%ld Max=%ldx%ld Def=%ldx%ld\n", obj, data->mad_FrameTitle, */
872 /* msg->MinMaxInfo->MinWidth, msg->MinMaxInfo->MinHeight, */
873 /* msg->MinMaxInfo->MaxWidth, msg->MinMaxInfo->MaxHeight, */
874 /* msg->MinMaxInfo->DefWidth, msg->MinMaxInfo->DefHeight)); */
876 return TRUE;
880 * Called after MUIM_AskMinMax, to handle fixed and max sizes.
882 void __area_finish_minmax(Object *obj, struct MUI_MinMax *MinMaxInfo)
884 struct MUI_AreaData *data = muiAreaData(obj);
886 if ((_flags(obj) & MADF_FIXHEIGHT) && data->mad_HardHeight)
888 int h = data->mad_HardHeight + data->mad_subheight;
890 MinMaxInfo->MinHeight =
891 MinMaxInfo->DefHeight =
892 MinMaxInfo->MaxHeight = CLAMP(h, MinMaxInfo->MinHeight, MinMaxInfo->MaxHeight);
894 else if (data->mad_HardHeightTxt)
896 ZText *text;
898 if ((text = zune_text_new(NULL, data->mad_HardHeightTxt, ZTEXT_ARG_NONE, 0)))
900 zune_text_get_bounds(text, obj);
902 MinMaxInfo->MinHeight =
903 MinMaxInfo->DefHeight =
904 MinMaxInfo->MaxHeight =
905 CLAMP(text->height + data->mad_subheight, MinMaxInfo->MinHeight, MinMaxInfo->MaxHeight);
907 zune_text_destroy(text);
911 else if (_flags(obj) & MADF_MAXHEIGHT)
913 MinMaxInfo->MaxHeight =
914 CLAMP(data->mad_HardHeight + data->mad_subheight,
915 MinMaxInfo->MinHeight,
916 MinMaxInfo->MaxHeight);
919 if ((_flags(obj) & MADF_FIXWIDTH) && data->mad_HardWidth)
921 int w = data->mad_HardWidth + data->mad_subwidth;
923 MinMaxInfo->MinWidth =
924 MinMaxInfo->DefWidth =
925 MinMaxInfo->MaxWidth = CLAMP(w, MinMaxInfo->MinWidth, MinMaxInfo->MaxWidth);
927 else if (data->mad_HardWidthTxt)
929 ZText *text;
931 if ((text = zune_text_new(NULL, data->mad_HardWidthTxt, ZTEXT_ARG_NONE, 0)))
933 zune_text_get_bounds(text, obj);
935 MinMaxInfo->MinWidth =
936 MinMaxInfo->DefWidth =
937 MinMaxInfo->MaxWidth =
938 CLAMP(text->width + data->mad_subwidth, MinMaxInfo->MinWidth, MinMaxInfo->MaxWidth);
940 zune_text_destroy(text);
944 else if (_flags(obj) & MADF_MAXWIDTH)
946 MinMaxInfo->MaxWidth =
947 CLAMP(data->mad_HardWidth + data->mad_subwidth,
948 MinMaxInfo->MinWidth,
949 MinMaxInfo->MaxWidth);
952 /* Set minmax */
953 _minwidth(obj) = MinMaxInfo->MinWidth;
954 _minheight(obj) = MinMaxInfo->MinHeight;
955 _maxwidth(obj) = MinMaxInfo->MaxWidth;
956 _maxheight(obj) = MinMaxInfo->MaxHeight;
957 _defwidth(obj) = MinMaxInfo->DefWidth;
958 _defheight(obj) = MinMaxInfo->DefHeight;
961 /* <-- _top(obj) (frame title position depends of _top(obj))
962 * ====== Title ===== <-- frame_top (depends of title, if centered/above)
963 * | | <-- bgtop (depends of frame, bg always begins under frame)
964 * | |
965 * | |
966 * ================== <-- "bgbottom" and "frame_bottom" (frame overwrites bg (1))
968 * (1) : needed for phantom frame objects, where no frame overwrites bg, thus bg
969 * must go as far as theorical bottom frame border.
973 * draw object background if MADF_FILLAREA.
975 static void Area_Draw_handle_background(Object *obj, struct MUI_AreaData *data, ULONG flags,
976 const struct ZuneFrameGfx *zframe)
978 struct MUI_ImageSpec_intern *background;
979 struct Rectangle r, r2, rects[4];
980 int i, bgtop, bgleft, bgw, bgh, numrects;
982 if (!(data->mad_Flags & MADF_SELECTED) || !(data->mad_Flags & MADF_SHOWSELSTATE))
983 background = data->mad_Background;
984 else
985 background = data->mad_SelBack;
987 if (zframe->customframe)
989 bgtop = _top(obj) + data->mad_TitleHeightAbove;
991 else
993 bgtop = _top(obj) + data->mad_TitleHeightAbove + zframe->itop;
996 bgleft = _left(obj);
997 bgw = _width(obj);
998 bgh = _height(obj) - bgtop + _top(obj);
1000 r.MinX = bgleft;
1001 r.MinY = bgtop;
1002 r.MaxX = bgleft + bgw - 1;
1003 r.MaxY = bgtop + bgh - 1;
1005 if (data->mad_Flags & MADF_FILLAREA)
1007 rects[0] = r;
1008 numrects = 1;
1010 else
1012 /* MADF_FILLAREA not set. Only draw frame outside of
1013 innerbox (_mleft, _mtop, _mright, _mbottom):
1015 .............
1016 .***********.
1017 .*#########*.
1018 .*#########*.
1019 .***********.
1020 .............
1022 # = innerbox
1023 * = frame outside of innerbox
1024 . = object frame
1027 r2.MinX = _mleft(obj);
1028 r2.MinY = _mtop(obj);
1029 r2.MaxX = _mright(obj);
1030 r2.MaxY = _mbottom(obj);
1032 numrects = SubtractRectFromRect(&r, &r2, rects);
1035 for(i = 0; i < numrects; i++)
1037 if (!background)
1039 /* This will do the rest, TODO: on MADF_DRAWALL we not really need to draw this */
1040 /* D(bug(" Area_Draw(%p):%ld: MUIM_DrawBackground\n", obj, __LINE__)); */
1041 /* ATTENTION: This draws the clipped away regions of the area. Comment out and */
1042 /* check the result to see what I mean. */
1043 DoMethod(obj, MUIM_DrawBackground,
1044 rects[i].MinX, rects[i].MinY,
1045 rects[i].MaxX - rects[i].MinX + 1, rects[i].MaxY - rects[i].MinY + 1,
1046 rects[i].MinX, rects[i].MinY,
1047 data->mad_Flags
1050 else
1052 /* D(bug(" Area_Draw(%p):%ld: zune_imspec_draw\n", obj, __LINE__)); */
1053 zune_imspec_draw(background, data->mad_RenderInfo,
1054 rects[i].MinX, rects[i].MinY,
1055 rects[i].MaxX - rects[i].MinX + 1, rects[i].MaxY - rects[i].MinY + 1,
1056 rects[i].MinX, rects[i].MinY,
1062 if (muiGlobalInfo(obj)->mgi_Prefs->window_redraw == WINDOW_REDRAW_WITHOUT_CLEAR)
1064 if (bgtop > _top(obj) && !(flags & MADF_DRAWALL))
1066 /* Fill in the gap produced by the title with the background
1067 * of the parent object but only if
1068 * the upper object hasn't drawn it already
1069 * (which is the case if MADF_DRAWALL is setted) */
1070 DoMethod(
1071 obj, MUIM_DrawParentBackground, bgleft, _top(obj), bgw, bgtop - _top(obj),
1072 bgleft, _top(obj), data->mad_Flags
1080 * draw object frame + title if not MADF_FRAMEPHANTOM.
1082 static void Area_Draw_handle_frame(Object *obj, struct MUI_AreaData *data,
1083 const struct ZuneFrameGfx *zframe)
1085 APTR textdrawclip = (APTR)-1;
1086 struct Region *region;
1087 int tx;
1088 int tw, frame_height, frame_top;
1089 int addtw;
1090 struct TextExtent te;
1091 int nchars;
1092 int maxtxtwidth;
1094 /* no frametitle, just draw frame and return */
1095 if (!data->mad_FrameTitle)
1097 zframe->draw(zframe->customframe, muiRenderInfo(obj), _left(obj), _top(obj), _width(obj), _height(obj), _left(obj), _top(obj), _width(obj), _height(obj));
1098 return;
1101 /* set clipping so that frame is not drawn behind title */
1103 switch (muiGlobalInfo(obj)->mgi_Prefs->group_title_color)
1105 case GROUP_TITLE_COLOR_OUTLINE:
1106 addtw = 2;
1107 break;
1108 case GROUP_TITLE_COLOR_3D:
1109 addtw = 1;
1110 break;
1111 default:
1112 addtw = 0;
1115 maxtxtwidth = _width(obj) - zframe->ileft - zframe->iright - 2 * 5 - addtw;
1117 nchars = TextFit(_rp(obj), data->mad_FrameTitle,
1118 strlen(data->mad_FrameTitle),
1119 &te, NULL, 1, maxtxtwidth, _font(obj)->tf_YSize);
1121 tw = te.te_Width + addtw;
1122 tx = _left(obj) + (_width(obj) - tw) / 2;
1124 frame_top = _top(obj) + data->mad_TitleHeightAbove;
1125 frame_height = _height(obj) - frame_top + _top(obj);
1127 if ((region = NewRegion()))
1129 struct Rectangle rect;
1130 int hspace = _font(obj)->tf_YSize / 8;
1132 rect.MinX = tx - hspace;
1133 rect.MinY = _top(obj);
1134 rect.MaxX = tx + tw - 1 + hspace;
1135 rect.MaxY = _top(obj) + _font(obj)->tf_YSize - 1; // frame is not thick enough anywhy
1136 OrRectRegion(region,&rect);
1138 rect.MinX = _left(obj);
1139 rect.MinY = _top(obj);
1140 rect.MaxX = _right(obj);
1141 rect.MaxY = _bottom(obj);
1142 XorRectRegion(region,&rect);
1144 textdrawclip = MUI_AddClipRegion(muiRenderInfo(obj),region);
1147 zframe->draw(zframe->customframe, muiRenderInfo(obj), _left(obj), frame_top, _width(obj), frame_height, _left(obj), frame_top, _width(obj), frame_height);
1149 if (region && textdrawclip != (APTR)-1)
1151 MUI_RemoveClipRegion(muiRenderInfo(obj),textdrawclip);
1152 /* DisposeRegion(region);*/ /* sba: DisposeRegion happens in MUI_RemoveClipRegion, this seems wrong to me */
1155 /* Title text drawing */
1156 SetDrMd(_rp(obj), JAM1);
1157 SetAPen(_rp(obj), _pens(obj)[MPEN_SHADOW]);
1158 if (muiGlobalInfo(obj)->mgi_Prefs->group_title_color == GROUP_TITLE_COLOR_3D)
1160 Move(_rp(obj), tx + 1, _top(obj) + _font(obj)->tf_Baseline + 1);
1161 Text(_rp(obj), data->mad_FrameTitle, nchars);
1162 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
1163 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline);
1164 Text(_rp(obj), data->mad_FrameTitle, nchars);
1166 else if (muiGlobalInfo(obj)->mgi_Prefs->group_title_color == GROUP_TITLE_COLOR_OUTLINE)
1168 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
1170 tx += addtw / 2;
1171 Move(_rp(obj), tx + 1, _top(obj) + _font(obj)->tf_Baseline);
1172 Text(_rp(obj), data->mad_FrameTitle, nchars);
1173 Move(_rp(obj), tx - 1, _top(obj) + _font(obj)->tf_Baseline);
1174 Text(_rp(obj), data->mad_FrameTitle, nchars);
1175 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline + 1);
1176 Text(_rp(obj), data->mad_FrameTitle, nchars);
1177 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline - 1);
1178 Text(_rp(obj), data->mad_FrameTitle, nchars);
1180 SetAPen(_rp(obj), _pens(obj)[MPEN_SHADOW]);
1181 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline);
1182 Text(_rp(obj), data->mad_FrameTitle, nchars);
1184 else
1186 if (muiGlobalInfo(obj)->mgi_Prefs->group_title_color == GROUP_TITLE_COLOR_HILITE)
1188 SetAPen(_rp(obj), _pens(obj)[MPEN_SHINE]);
1190 Move(_rp(obj), tx, _top(obj) + _font(obj)->tf_Baseline);
1191 Text(_rp(obj), data->mad_FrameTitle, nchars);
1195 /**************************************************************************
1196 MUIM_Draw
1197 **************************************************************************/
1198 static IPTR Area__MUIM_Draw(struct IClass *cl, Object *obj, struct MUIP_Draw *msg)
1200 struct MUI_AreaData *data = INST_DATA(cl, obj);
1201 const struct ZuneFrameGfx *zframe;
1202 struct TextFont *obj_font = NULL;
1203 ULONG flags = data->mad_Flags & MADF_DRAWFLAGS;
1205 //APTR areaclip;
1207 /* D(bug("Area_Draw(0x%lx) %ldx%ldx%ldx%ld\n",obj,_left(obj),_top(obj),_right(obj),_bottom(obj))); */
1208 /* D(bug(" Area_Draw(%p) msg=0x%08lx flags=0x%08lx\n",obj, msg->flags,_flags(obj))); */
1210 if (flags & MADF_DRAWALL)
1211 flags |= MADF_DRAWOBJECT;
1213 msg->flags = flags;
1214 data->mad_Flags &= ~MADF_DRAWFLAGS;
1216 if (!(flags & MADF_DRAWOBJECT))
1218 /* dont draw bg/frame, let subclass redraw content only
1220 return 0;
1224 /* Background cant be drawn without knowing anything about frame, thus some
1225 * calculations are made before background and frame drawing.
1228 /* on selected state, will get the opposite frame */
1229 const struct MUI_FrameSpec_intern *frame;
1230 struct MUI_FrameSpec_intern tempframe;
1231 int state;
1233 frame = get_intframe(obj, data, &tempframe);
1234 state = frame->state;
1235 if ((data->mad_Flags & MADF_SELECTED) && (data->mad_Flags & MADF_SHOWSELSTATE))
1236 state ^= 1;
1238 zframe = zune_zframe_get_with_state(
1239 obj, frame, state);
1240 /* update innersizes as there are frames which have different inner spacings in selected state */
1241 area_update_msizes(obj, data, frame, zframe);
1244 /* Background drawing */
1245 Area_Draw_handle_background(obj, data, msg->flags, zframe);
1247 obj_font = _font(obj);
1248 _font(obj) = zune_font_get(obj, MUIV_Font_Title);
1249 SetFont(_rp(obj), _font(obj));
1251 /* Frame and frametitle drawing */
1252 if (!(data->mad_Flags & MADF_FRAMEPHANTOM))
1254 Area_Draw_handle_frame(obj, data, zframe);
1257 _font(obj) = obj_font;
1258 SetFont(_rp(obj), _font(obj));
1260 /* MUI_RemoveClipping(muiRenderInfo(obj), areaclip);*/
1262 return TRUE;
1265 /**************************************************************************
1266 MUIM_DrawParentBackground
1267 **************************************************************************/
1268 static IPTR Area__MUIM_DrawParentBackground(struct IClass *cl, Object *obj, struct MUIP_DrawParentBackground *msg)
1270 struct MUI_AreaData *data = INST_DATA(cl, obj);
1271 Object *parent;
1273 if (!(data->mad_Flags & MADF_CANDRAW)) /* not between show/hide */
1274 return FALSE;
1276 get(obj, MUIA_Parent, &parent);
1277 if (parent)
1279 DoMethod(parent, MUIM_DrawBackground, msg->left, msg->top,
1280 msg->width, msg->height, msg->xoffset, msg->yoffset, msg->flags);
1282 else
1284 D(bug("Area_DrawParentBackground(%p) : MUIM_Window_DrawBackground\n", obj));
1285 DoMethod(_win(obj), MUIM_Window_DrawBackground, msg->left, msg->top,
1286 msg->width, msg->height, msg->xoffset, msg->yoffset, msg->flags);
1288 return TRUE;
1291 /**************************************************************************
1292 MUIM_DrawBackground
1293 **************************************************************************/
1294 static IPTR Area__MUIM_DrawBackground(struct IClass *cl, Object *obj, struct MUIP_DrawBackground *msg)
1296 struct MUI_AreaData *data = INST_DATA(cl, obj);
1297 struct MUI_ImageSpec_intern *bg;
1298 LONG state;
1300 if (!(data->mad_Flags & MADF_CANDRAW)) /* not between show/hide */
1301 return FALSE;
1303 if ((msg->flags & MADF_SELECTED) && (msg->flags & MADF_SHOWSELSTATE) && data->mad_SelBack)
1305 /* D(bug("Area_DrawBackground(%p): selected bg\n", obj)); */
1306 bg = data->mad_SelBack;
1307 state = IDS_SELECTED;
1309 else
1311 /* D(bug("Area_DrawBackground(%p): normal bg\n", obj)); */
1312 bg = data->mad_Background;
1313 state = IDS_NORMAL;
1316 const struct ZuneFrameGfx *zframe;
1317 const struct MUI_FrameSpec_intern *frame;
1318 struct MUI_FrameSpec_intern tempframe;
1320 if (!bg)
1322 Object *parent;
1323 get(obj, MUIA_Parent, &parent);
1325 D(bug("Area_DrawBackground(%p) : MUIM_DrawParentBackground\n",
1326 obj));
1328 return DoMethod(obj, MUIM_DrawParentBackground, msg->left, msg->top,
1329 msg->width, msg->height, msg->xoffset, msg->yoffset, msg->flags);
1332 frame = get_intframe(obj, data, &tempframe);
1334 int xstate = frame->state;
1335 if ((data->mad_Flags & MADF_SELECTED) && (data->mad_Flags & MADF_SHOWSELSTATE))
1336 xstate ^= 1;
1338 zframe = zune_zframe_get_with_state(obj, frame, xstate);
1340 if (zframe->customframe == NULL)
1342 /* D(bug("Area_DrawBackground(%p): draw bg\n", obj)); */
1343 zune_imspec_draw(bg, data->mad_RenderInfo,
1344 msg->left, msg->top, msg->width, msg->height,
1345 msg->xoffset, msg->yoffset, state);
1347 // if (!data->mad_FrameTitle)
1348 // {
1351 else
1353 if (zframe->noalpha == FALSE)
1355 zune_imspec_draw(bg, data->mad_RenderInfo,
1356 msg->left, msg->top, msg->width, msg->height,
1357 msg->xoffset, msg->yoffset, state);
1362 if (zframe->customframe)
1364 zframe->draw(zframe->customframe, muiRenderInfo(obj), _left(obj), _top(obj), _width(obj), _height(obj), msg->left, msg->top, msg->width, msg->height);
1367 return TRUE;
1370 static IPTR Area__MUIM_DrawBackgroundBuffered(struct IClass *cl, Object *obj, struct MUIP_DrawBackgroundBuffered *msg)
1372 struct MUI_AreaData *data = INST_DATA(cl, obj);
1373 struct MUI_ImageSpec_intern *bg;
1374 LONG state;
1376 if (!(data->mad_Flags & MADF_CANDRAW)) /* not between show/hide */
1377 return FALSE;
1379 bg = data->mad_Background;
1381 /* D(bug("Area_DrawBackground(%p): draw bg\n", obj)); */
1382 zune_imspec_drawbuffered(bg, msg->rp, data->mad_RenderInfo,
1383 msg->left, msg->top, msg->width, msg->height,
1384 msg->xoffset+msg->left, msg->yoffset+msg->top, state, msg->left, msg->top, 1,
1385 _mleft(obj), _mtop(obj), _mright(obj), _mbottom(obj));
1387 return TRUE;
1390 /* Perverting the EventHandlerNode structure to specify a shortcut.
1392 static void setup_control_char (struct MUI_AreaData *data, Object *obj, struct IClass *cl)
1394 if (data->mad_ControlChar != 0 || data->mad_Flags & MADF_CYCLECHAIN)
1396 data->mad_ccn.ehn_Events = data->mad_ControlChar;
1397 switch (data->mad_InputMode)
1399 case MUIV_InputMode_RelVerify:
1400 data->mad_ccn.ehn_Flags = MUIKEY_PRESS;
1401 break;
1402 case MUIV_InputMode_Toggle:
1403 data->mad_ccn.ehn_Flags = MUIKEY_TOGGLE;
1404 break;
1405 case MUIV_InputMode_Immediate:
1406 data->mad_ccn.ehn_Flags = MUIKEY_PRESS;
1407 break;
1409 data->mad_ccn.ehn_Priority = 0;
1410 data->mad_ccn.ehn_Object = obj;
1411 data->mad_ccn.ehn_Class = cl;
1412 DoMethod(_win(obj), MUIM_Window_AddControlCharHandler, (IPTR)&data->mad_ccn);
1417 static void cleanup_control_char (struct MUI_AreaData *data, Object *obj)
1419 if (data->mad_ControlChar != 0 || data->mad_Flags & MADF_CYCLECHAIN)
1421 DoMethod(_win(obj),
1422 MUIM_Window_RemControlCharHandler, (IPTR)&data->mad_ccn);
1426 static const struct MUI_FrameSpec_intern *get_intframe(
1427 Object *obj, struct MUI_AreaData *data, struct MUI_FrameSpec_intern *tempstore)
1429 if (data->mad_Frame > 100)
1431 /* Frame is spec in string format. Store it in tempstore and return a pointer
1432 to it. The caller should have such a temp variable on the stack. Don't want
1433 to add it to MUI_AreaData as that will increase mem usage of every object. */
1435 if (zune_frame_spec_to_intern((CONST_STRPTR)data->mad_Frame, tempstore))
1437 return tempstore;
1439 else
1441 return &muiGlobalInfo(obj)->mgi_Prefs->frames[MUIV_Frame_None];
1444 else
1446 /* Frame is MUIV_Frame_<something> */
1447 return &muiGlobalInfo(obj)->mgi_Prefs->frames[data->mad_Frame];
1451 static void set_inner_sizes (Object *obj, struct MUI_AreaData *data)
1453 const struct MUI_FrameSpec_intern *frame;
1454 struct MUI_FrameSpec_intern tempframe;
1456 frame = get_intframe(obj, data, &tempframe);
1457 // Use frame inner spacing when not hardcoded
1458 if (!(data->mad_Flags & MADF_INNERLEFT))
1459 data->mad_InnerLeft = frame->innerLeft;
1460 if (!(data->mad_Flags & MADF_INNERTOP))
1461 data->mad_InnerTop = frame->innerTop;
1462 if (!(data->mad_Flags & MADF_INNERRIGHT))
1463 data->mad_InnerRight = frame->innerRight;
1464 if (!(data->mad_Flags & MADF_INNERBOTTOM))
1465 data->mad_InnerBottom = frame->innerBottom;
1469 static void set_title_sizes (Object *obj, struct MUI_AreaData *data)
1471 if (data->mad_FrameTitle)
1473 const struct ZuneFrameGfx *zframe;
1474 const struct MUI_FrameSpec_intern *frame;
1475 struct MUI_FrameSpec_intern tempframe;
1477 frame = get_intframe(obj, data, &tempframe);
1478 zframe = zune_zframe_get(obj, frame);
1480 _font(obj) = zune_font_get(obj, MUIV_Font_Title);
1482 switch (muiGlobalInfo(obj)->mgi_Prefs->group_title_position)
1484 case GROUP_TITLE_POSITION_ABOVE:
1485 data->mad_TitleHeightAbove = _font(obj)->tf_Baseline;
1486 break;
1487 case GROUP_TITLE_POSITION_CENTERED:
1488 data->mad_TitleHeightAbove = _font(obj)->tf_YSize / 2;
1489 break;
1492 data->mad_TitleHeightAdd = _font(obj)->tf_YSize - data->mad_InnerTop - zframe->itop;
1493 data->mad_TitleHeightBelow = data->mad_TitleHeightAdd - data->mad_TitleHeightAbove;
1498 /**************************************************************************
1499 First method to be called after an OM_NEW, it is the place
1500 for all initializations depending on the environment, but not
1501 on the gadget size/position. Matched by MUIM_Cleanup.
1502 **************************************************************************/
1503 static IPTR Area__MUIM_Setup(struct IClass *cl, Object *obj, struct MUIP_Setup *msg)
1505 struct MUI_AreaData *data = INST_DATA(cl, obj);
1506 const struct ZuneFrameGfx *zframe;
1507 const struct MUI_FrameSpec_intern *frame;
1508 struct MUI_FrameSpec_intern tempframe;
1510 muiRenderInfo(obj) = msg->RenderInfo;
1512 if (data->mad_Frame)
1514 /* no frame allowed for root object (see Area.doc) */
1515 IPTR rootobj;
1516 get(_win(obj), MUIA_Window_RootObject, &rootobj);
1517 if ((Object*)rootobj == obj)
1519 data->mad_Frame = MUIV_Frame_None;
1520 data->mad_FrameTitle = NULL;
1524 set_inner_sizes(obj, data);
1525 set_title_sizes(obj, data);
1527 frame = get_intframe(obj, data, &tempframe);
1528 zframe = zune_zframe_get(obj, frame);
1530 area_update_msizes(obj, data, frame, zframe);
1532 if (data->mad_Flags & MADF_OWNBG)
1534 data->mad_Background = zune_imspec_setup((IPTR)data->mad_BackgroundSpec,
1535 muiRenderInfo(obj));
1538 if ((data->mad_Flags & MADF_SHOWSELSTATE) &&
1539 (data->mad_InputMode != MUIV_InputMode_None))
1541 data->mad_SelBack = zune_imspec_setup(MUII_SelectedBack, muiRenderInfo(obj));
1544 if (data->mad_InputMode != MUIV_InputMode_None || data->mad_ContextMenu)
1546 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
1547 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1550 /* Those are filled by RequestIDCMP() */
1551 if (data->mad_hiehn.ehn_Events)
1552 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_hiehn);
1554 setup_control_char (data, obj, cl);
1555 // setup_cycle_chain (data, obj);
1557 if (data->mad_FontPreset == MUIV_Font_Inherit)
1559 if (_parent(obj) != NULL && _parent(obj) != _win(obj))
1560 data->mad_Font = _font(_parent(obj));
1561 else
1563 D(bug("Area_Setup %p: getting normal font\n", obj));
1564 data->mad_Font = zune_font_get(obj, MUIV_Font_Normal);
1565 D(bug("Area_Setup %p: got normal font %p\n", obj, data->mad_Font));
1568 else
1570 data->mad_Font = zune_font_get(obj, data->mad_FontPreset);
1573 _flags(obj) |= MADF_SETUP;
1575 data->mad_Timer.ihn_Flags = MUIIHNF_TIMER;
1576 data->mad_Timer.ihn_Method = MUIM_Timer;
1577 data->mad_Timer.ihn_Object = obj;
1579 return TRUE;
1583 /**************************************************************************
1584 Called to match a MUIM_Setup, when environment is no more available.
1585 **************************************************************************/
1586 static IPTR Area__MUIM_Cleanup(struct IClass *cl, Object *obj, struct MUIP_Cleanup *msg)
1588 struct MUI_AreaData *data = INST_DATA(cl, obj);
1590 _flags(obj) &= ~MADF_SETUP;
1592 // cleanup_cycle_chain (data, obj);
1593 cleanup_control_char (data, obj);
1595 if (data->mad_Timer.ihn_Millis)
1597 DoMethod(_app(obj), MUIM_Application_RemInputHandler, (IPTR)&data->mad_Timer);
1598 data->mad_Timer.ihn_Millis = 0;
1601 /* Remove the handler if it is added */
1602 if (data->mad_hiehn.ehn_Events)
1603 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_hiehn);
1605 /* Remove the event handler if it has been added */
1606 if (data->mad_ehn.ehn_Events)
1607 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1609 D(bug("Area cleanup %p active=%p\n", obj,
1610 (Object *)XGET(_win(obj), MUIA_Window_ActiveObject)));
1611 if (obj == (Object *)XGET(_win(obj), MUIA_Window_ActiveObject))
1613 D(bug("we are active, unset us\n"));
1614 set(_win(obj), MUIA_Window_ActiveObject, MUIV_Window_ActiveObject_None);
1617 /* It's save to call the following function with NULL */
1618 if ((data->mad_Flags & MADF_SHOWSELSTATE) &&
1619 (data->mad_InputMode != MUIV_InputMode_None))
1621 zune_imspec_cleanup(data->mad_SelBack);
1622 data->mad_SelBack = NULL;
1624 if (data->mad_Flags & MADF_OWNBG)
1626 zune_imspec_cleanup(data->mad_Background);
1627 data->mad_Background = NULL;
1630 muiRenderInfo(obj) = NULL;
1632 return TRUE;
1636 /**************************************************************************
1637 Called after the window is open and the area layouted, but before
1638 any drawing. Matched by one MUIM_Hide.
1639 Good place to init things depending on gadget size/position.
1640 **************************************************************************/
1641 static IPTR Area__MUIM_Show(struct IClass *cl, Object *obj, struct MUIP_Show *msg)
1643 struct MUI_AreaData *data = INST_DATA(cl, obj);
1645 zune_imspec_show(data->mad_Background, obj);
1647 if (data->mad_Flags & MADF_SHOWSELSTATE
1648 && data->mad_InputMode != MUIV_InputMode_None)
1650 zune_imspec_show(data->mad_SelBack, obj);
1653 return TRUE;
1656 /**************************************************************************
1657 Called when the window is about to be closed, to match MUIM_Show.
1658 **************************************************************************/
1659 static IPTR Area__MUIM_Hide(struct IClass *cl, Object *obj, struct MUIP_Hide *msg)
1661 struct MUI_AreaData *data = INST_DATA(cl, obj);
1663 zune_imspec_hide(data->mad_Background);
1664 if (data->mad_Flags & MADF_SHOWSELSTATE
1665 && data->mad_InputMode != MUIV_InputMode_None)
1667 zune_imspec_hide(data->mad_SelBack);
1670 if (data->mad_ContextZMenu)
1672 zune_close_menu(data->mad_ContextZMenu);
1673 data->mad_ContextZMenu = NULL;
1676 return TRUE;
1679 /**************************************************************************
1680 Called when gadget activated
1681 **************************************************************************/
1682 static IPTR Area__MUIM_GoActive(struct IClass *cl, Object *obj, Msg msg)
1684 //bug("Area_GoActive %p\n", obj);
1685 if (_flags(obj) & MADF_CANDRAW)
1686 _zune_focus_new(obj, ZUNE_FOCUS_TYPE_ACTIVE_OBJ);
1687 return TRUE;
1690 /**************************************************************************
1691 Called when gadget deactivated
1692 **************************************************************************/
1693 static IPTR Area__MUIM_GoInactive(struct IClass *cl, Object *obj, Msg msg)
1695 //bug("Area_GoInactive %p\n", obj);
1696 if (_flags(obj) & MADF_CANDRAW)
1697 _zune_focus_destroy(obj, ZUNE_FOCUS_TYPE_ACTIVE_OBJ);
1698 return TRUE;
1701 /**************************************************************************
1702 This one or derived methods wont be called if short help is
1703 not set in area instdata. So set this to a dummy val if overriding
1704 **************************************************************************/
1705 static IPTR Area__MUIM_CreateShortHelp(struct IClass *cl, Object *obj, struct MUIP_CreateShortHelp *msg)
1707 struct MUI_AreaData *data = INST_DATA(cl, obj);
1709 return (IPTR)data->mad_ShortHelp;
1712 /**************************************************************************
1714 **************************************************************************/
1715 static IPTR Area__MUIM_DeleteShortHelp(struct IClass *cl, Object *obj, struct MUIP_DeleteShortHelp *msg)
1717 return TRUE;
1720 /**************************************************************************
1722 **************************************************************************/
1723 static IPTR Area__MUIM_CreateBubble(struct IClass *cl, Object *obj, struct MUIP_CreateBubble *msg)
1725 return (IPTR)zune_bubble_create(obj, msg->x, msg->y, msg->txt, msg->flags);
1728 /**************************************************************************
1730 **************************************************************************/
1731 static IPTR Area__MUIM_DeleteBubble(struct IClass *cl, Object *obj, struct MUIP_DeleteBubble *msg)
1733 zune_bubble_delete(obj, msg->bubble);
1735 return TRUE;
1738 /* either lmb or press key */
1739 static void handle_press(struct IClass *cl, Object *obj)
1741 struct MUI_AreaData *data = INST_DATA(cl, obj);
1743 switch (data->mad_InputMode)
1745 case MUIV_InputMode_RelVerify:
1746 set(obj, MUIA_Timer, ++muiAreaData(obj)->mad_Timeval);
1747 if (!data->mad_Timer.ihn_Millis)
1749 data->mad_Timer.ihn_Millis = 300;
1750 DoMethod(_app(obj), MUIM_Application_AddInputHandler, (IPTR)&data->mad_Timer);
1752 SetAttrs(obj, MUIA_Selected, TRUE, MUIA_Pressed, TRUE, TAG_DONE);
1753 break;
1755 case MUIV_InputMode_Immediate:
1757 IPTR selected;
1759 get(obj, MUIA_Selected, &selected);
1760 if (selected)
1762 /* D(bug("handle_press(%p) : nnset MUIA_Selected FALSE\n", obj)); */
1763 nnset(obj, MUIA_Selected, FALSE);
1765 /* D(bug("handle_press(%p) : set MUIA_Selected TRUE\n", obj)); */
1766 set(obj, MUIA_Selected, TRUE);
1767 /* D(bug("handle_press(%p) : done\n", obj)); */
1768 break;
1770 case MUIV_InputMode_Toggle:
1771 // although undocumented, MUI sets MUIA_Pressed too
1772 SetAttrs(obj, MUIA_Selected, !(data->mad_Flags & MADF_SELECTED),
1773 MUIA_Pressed, !(data->mad_Flags & MADF_PRESSED),
1774 TAG_DONE);
1775 break;
1779 /* either lmb or release key */
1780 static void handle_release(struct IClass *cl, Object *obj, int cancel)
1782 struct MUI_AreaData *data = INST_DATA(cl, obj);
1784 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
1786 if (data->mad_Flags & MADF_SELECTED)
1788 if (cancel)
1789 nnset(obj, MUIA_Pressed, FALSE);
1790 else
1791 set(obj, MUIA_Pressed, FALSE);
1793 set(obj, MUIA_Selected, FALSE);
1797 if (data->mad_Timer.ihn_Millis)
1799 DoMethod(_app(obj), MUIM_Application_RemInputHandler, (IPTR)&data->mad_Timer);
1800 data->mad_Timer.ihn_Millis = 0;
1805 static IPTR event_button(Class *cl, Object *obj, struct IntuiMessage *imsg)
1807 struct MUI_AreaData *data = INST_DATA(cl, obj);
1808 BOOL in = _between(_left(obj), imsg->MouseX, _right(obj))
1809 && _between(_top(obj), imsg->MouseY, _bottom(obj));
1811 switch (imsg->Code)
1813 case SELECTDOWN:
1814 if (data->mad_InputMode == MUIV_InputMode_None)
1815 break;
1817 if (in)
1819 // set(_win(obj), MUIA_Window_ActiveObject, obj);
1820 data->mad_ClickX = imsg->MouseX;
1821 data->mad_ClickY = imsg->MouseY;
1823 if ((data->mad_InputMode != MUIV_InputMode_Toggle) && (data->mad_Flags & MADF_SELECTED))
1824 break;
1825 nnset(obj,MUIA_Timer,0);
1826 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
1828 if (data->mad_ehn.ehn_Events) DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1829 data->mad_ehn.ehn_Events |= IDCMP_MOUSEMOVE | IDCMP_RAWKEY;
1830 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1832 handle_press(cl, obj);
1833 return MUI_EventHandlerRC_Eat;
1836 case SELECTUP:
1837 if (data->mad_InputMode == MUIV_InputMode_None)
1838 break;
1840 if (data->mad_ehn.ehn_Events != IDCMP_MOUSEBUTTONS)
1842 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1843 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
1844 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1845 if (!in) nnset(obj, MUIA_Pressed, FALSE);
1846 handle_release(cl, obj, FALSE /*cancel*/ );
1847 return MUI_EventHandlerRC_Eat;
1849 break;
1851 case MENUDOWN:
1852 if (in && data->mad_ContextMenu)
1854 Object *menuobj = (Object*)DoMethod(obj, MUIM_ContextMenuBuild, imsg->MouseX, imsg->MouseY);
1855 if (menuobj)
1857 struct NewMenu *newmenu;
1859 /* stegerg: HACKME, CHECKME! The menu/menu item objs should automatically
1860 be connected (parentobject setup) without need for
1861 this, but they aren't. Because of how family class is and
1862 is used by other classes, I think!? */
1863 DoMethod(menuobj, MUIM_ConnectParent, obj);
1865 get(menuobj,MUIA_Menuitem_NewMenu,&newmenu);
1866 if (newmenu)
1868 if (data->mad_ContextZMenu) zune_close_menu(data->mad_ContextZMenu);
1869 data->mad_ContextZMenu = zune_open_menu(_window(obj),newmenu);
1872 if (data->mad_ehn.ehn_Events) DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1873 data->mad_ehn.ehn_Events |= IDCMP_MOUSEMOVE;
1874 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1876 return MUI_EventHandlerRC_Eat;
1878 break;
1880 case MENUUP:
1881 if (data->mad_ContextZMenu)
1883 struct MenuItem *item = zune_leave_menu(data->mad_ContextZMenu);
1885 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1886 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
1887 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1889 if (item)
1891 Object *itemobj = (Object*)GTMENUITEM_USERDATA(item);
1893 /* CHECKME: MUIA_MenuItem_Trigger should probably be set inside
1894 MUIM_ContextMenuChoice!? But there I only know about
1895 itemobj, not MenuItem itself! */
1896 if (item->Flags & CHECKIT)
1898 set(itemobj, MUIA_Menuitem_Checked, !!(item->Flags & CHECKED));
1900 } /* if (item->Flags & CHECKIT) */
1902 set(itemobj, MUIA_Menuitem_Trigger, item);
1904 DoMethod(obj, MUIM_ContextMenuChoice, itemobj);
1906 } /* if (item) */
1908 zune_close_menu(data->mad_ContextZMenu);
1909 data->mad_ContextZMenu = NULL;
1911 return MUI_EventHandlerRC_Eat;
1913 } /* if (data->mad_ContextZMenu) */
1914 break;
1917 return 0;
1920 static IPTR event_motion(Class *cl, Object *obj, struct IntuiMessage *imsg)
1922 struct MUI_AreaData *data = INST_DATA(cl, obj);
1924 if ((imsg->Qualifier & IEQUALIFIER_RBUTTON) && data->mad_ContextZMenu)
1926 zune_mouse_update(data->mad_ContextZMenu, 0);
1927 return MUI_EventHandlerRC_Eat;
1930 if (imsg->Qualifier & IEQUALIFIER_LEFTBUTTON)
1932 BOOL in = _between(_left(obj), imsg->MouseX, _right(obj))
1933 && _between(_top(obj), imsg->MouseY, _bottom(obj));
1935 if (in)
1937 if ((data->mad_Flags & MADF_DRAGGABLE) && ((abs(data->mad_ClickX-imsg->MouseX) >= 3) || (abs(data->mad_ClickY-imsg->MouseY)>=3)))
1938 /* should be user configurable */
1940 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
1941 set(obj, MUIA_Selected, FALSE);
1942 nnset(obj, MUIA_Pressed, FALSE);
1944 if (data->mad_ehn.ehn_Events) DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1945 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
1946 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1947 if (data->mad_Timer.ihn_Millis)
1949 DoMethod(_app(obj), MUIM_Application_RemInputHandler, (IPTR)&data->mad_Timer);
1950 data->mad_Timer.ihn_Millis = 0;
1953 DoMethod(obj,MUIM_DoDrag, data->mad_ClickX - _left(obj), data->mad_ClickY - _top(obj), 0);
1954 return MUI_EventHandlerRC_Eat;
1958 if (data->mad_InputMode == MUIV_InputMode_RelVerify)
1960 if (!in && (data->mad_Flags & MADF_SELECTED)) /* going out */
1962 set(obj, MUIA_Selected, FALSE);
1964 else if (in && !(data->mad_Flags & MADF_SELECTED)) /* going in */
1966 set(obj, MUIA_Selected, TRUE);
1970 return MUI_EventHandlerRC_Eat;
1973 /**************************************************************************
1975 **************************************************************************/
1976 static IPTR Area__MUIM_HandleEvent(struct IClass *cl, Object *obj, struct MUIP_HandleEvent *msg)
1978 struct MUI_AreaData *data = INST_DATA(cl, obj);
1980 //bug("Area_HandleEvent [%p] imsg=%p muikey=%ld\n", obj, msg->imsg, msg->muikey);
1981 if (data->mad_DisableCount) return 0;
1982 if (data->mad_InputMode == MUIV_InputMode_None && !data->mad_ContextMenu) return 0;
1984 if (msg->muikey != MUIKEY_NONE)
1986 switch (msg->muikey)
1988 case MUIKEY_PRESS:
1989 if (data->mad_Flags & MADF_SELECTED)
1990 break;
1991 if (data->mad_ehn.ehn_Events)
1992 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
1993 data->mad_ehn.ehn_Events |= IDCMP_RAWKEY;
1994 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
1995 handle_press(cl, obj);
1996 return MUI_EventHandlerRC_Eat;
1998 case MUIKEY_TOGGLE:
1999 if (data->mad_InputMode == MUIV_InputMode_Toggle)
2000 set(obj, MUIA_Selected, !(data->mad_Flags & MADF_SELECTED));
2001 return MUI_EventHandlerRC_Eat;
2003 case MUIKEY_RELEASE:
2004 if (data->mad_ehn.ehn_Events)
2005 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
2006 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
2007 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
2008 handle_release(cl, obj, FALSE /* cancel */);
2009 return MUI_EventHandlerRC_Eat;
2011 return 0;
2014 if (msg->imsg)
2016 switch (msg->imsg->Class)
2018 case IDCMP_MOUSEBUTTONS: return event_button(cl, obj, msg->imsg);
2019 case IDCMP_MOUSEMOVE: return event_motion(cl, obj, msg->imsg);
2020 case IDCMP_RAWKEY:
2022 unsigned char code;
2023 UWORD msg_code;
2024 /* Remove the up prefix as convert key does not convert a upkey event */
2025 msg_code = msg->imsg->Code;
2026 msg->imsg->Code &= ~IECODE_UP_PREFIX;
2027 code = ConvertKey(msg->imsg);
2028 msg->imsg->Code = msg_code;
2030 if (code != 0 && code == data->mad_ControlChar)
2032 if (msg->imsg->Code & IECODE_UP_PREFIX)
2034 msg->muikey = MUIKEY_RELEASE;
2036 else
2038 msg->muikey = MUIKEY_PRESS;
2040 msg->imsg = NULL;
2041 return Area__MUIM_HandleEvent(cl, obj, msg);
2044 if (msg->imsg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
2046 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->mad_ehn);
2047 data->mad_ehn.ehn_Events = IDCMP_MOUSEBUTTONS;
2048 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->mad_ehn);
2049 handle_release(cl,obj, TRUE /*cancel */);
2051 return MUI_EventHandlerRC_Eat;
2053 break;
2056 return 0;
2059 /**************************************************************************
2061 **************************************************************************/
2062 static IPTR Area__MUIM_HandleInput(struct IClass *cl, Object *obj, struct MUIP_HandleInput *msg)
2064 /* Actually a dummy, but real MUI does handle here the input stuff which Zune
2065 ** has in Area_HandleEvent. For compatibility we should do this too
2067 //bug("Area_HandleEvent [%p] imsg=%p muikey=%ld\b", obj, msg->imsg, msg->muikey);
2068 return 0;
2071 /**************************************************************************
2072 Trivial; custom classes may override this to get dynamic menus.
2073 **************************************************************************/
2074 static IPTR Area__MUIM_ContextMenuBuild(struct IClass *cl, Object *obj, struct MUIP_ContextMenuBuild *msg)
2076 struct MUI_AreaData *data = INST_DATA(cl, obj);
2077 return (IPTR)data->mad_ContextMenu; /* a Menustrip object */
2080 /**************************************************************************/
2081 static IPTR Area__MUIM_ContextMenuChoice(struct IClass *cl, Object *obj, struct MUIP_ContextMenuChoice *msg)
2083 set(obj, MUIA_ContextMenuTrigger, msg->item);
2084 return 0;
2088 /**************************************************************************
2089 MUIM_Export : to export an objects "contents" to a dataspace object.
2090 **************************************************************************/
2091 static IPTR Area__MUIM_Export(struct IClass *cl, Object *obj, struct MUIP_Export *msg)
2093 struct MUI_AreaData *data = INST_DATA(cl, obj);
2094 ULONG id;
2096 if ((id = muiNotifyData(obj)->mnd_ObjectID))
2098 char selected = (data->mad_Flags & MADF_SELECTED)?1:0;
2099 DoMethod(msg->dataspace, MUIM_Dataspace_Add, (IPTR)&selected, sizeof(char),(IPTR)id);
2101 return 0;
2105 /**************************************************************************
2106 MUIM_Import : to import an objects "contents" from a dataspace object.
2107 **************************************************************************/
2108 static IPTR Area__MUIM_Import(struct IClass *cl, Object *obj, struct MUIP_Import *msg)
2110 ULONG id;
2112 if ((id = muiNotifyData(obj)->mnd_ObjectID))
2114 char *selected = (char*)DoMethod(msg->dataspace, MUIM_Dataspace_Find, (IPTR)id);
2116 if (selected)
2117 set(obj, MUIA_Selected, *selected);
2119 return 0;
2122 /**************************************************************************
2123 MUIM_Timer
2124 **************************************************************************/
2125 static IPTR Area__MUIM_Timer(struct IClass *cl, Object *obj, Msg msg)
2127 struct MUI_AreaData *data = INST_DATA(cl, obj);
2128 if (data->mad_Timer.ihn_Millis)
2129 DoMethod(_app(obj), MUIM_Application_RemInputHandler, (IPTR)&data->mad_Timer);
2130 data->mad_Timer.ihn_Millis = 50;
2131 DoMethod(_app(obj), MUIM_Application_AddInputHandler, (IPTR)&data->mad_Timer);
2133 if (data->mad_Flags & MADF_SELECTED)
2134 set(obj, MUIA_Timer, ++muiAreaData(obj)->mad_Timeval);
2135 return 0;
2138 /**************************************************************************
2139 MUIM_DoDrag
2140 **************************************************************************/
2141 static IPTR Area__MUIM_DoDrag(struct IClass *cl, Object *obj, struct MUIP_DoDrag *msg)
2143 //struct MUI_AreaData *data = INST_DATA(cl, obj);
2144 DoMethod(_win(obj), MUIM_Window_DragObject, (IPTR)obj, msg->touchx, msg->touchy, msg->flags);
2145 return 0;
2148 /**************************************************************************
2149 MUIM_CreateDragImage
2150 **************************************************************************/
2151 static IPTR Area__MUIM_CreateDragImage(struct IClass *cl, Object *obj, struct MUIP_CreateDragImage *msg)
2153 struct MUI_DragImage *img = (struct MUI_DragImage *)AllocVec(sizeof(struct MUIP_CreateDragImage),MEMF_CLEAR);
2154 if (img)
2156 const struct ZuneFrameGfx *zframe;
2157 LONG depth = GetBitMapAttr(_screen(obj)->RastPort.BitMap,BMA_DEPTH);
2159 zframe = zune_zframe_get(obj, &muiGlobalInfo(obj)->mgi_Prefs->frames[MUIV_Frame_Drag]);
2161 img->width = _width(obj) + zframe->ileft + zframe->iright;
2162 img->height = _height(obj) + zframe->itop + zframe->ibottom;
2164 if ((img->bm = AllocBitMap(img->width,img->height,depth,BMF_MINPLANES,_screen(obj)->RastPort.BitMap)))
2166 /* Render the stuff now */
2167 struct RastPort *rp_save = muiRenderInfo(obj)->mri_RastPort;
2168 struct RastPort temprp;
2169 InitRastPort(&temprp);
2170 temprp.BitMap = img->bm;
2171 ClipBlit(_rp(obj),_left(obj),_top(obj),&temprp,zframe->ileft,zframe->itop,_width(obj),_height(obj),0xc0);
2173 muiRenderInfo(obj)->mri_RastPort = &temprp;
2174 zframe->draw(zframe->customframe, muiRenderInfo(obj), 0, 0, img->width, img->height, 0, 0, img->width, img->height);
2175 muiRenderInfo(obj)->mri_RastPort = rp_save;
2177 DeinitRastPort(&temprp);
2180 img->touchx = msg->touchx;
2181 img->touchy = msg->touchy;
2182 img->flags = 0;
2184 return (IPTR)img;
2187 /**************************************************************************
2188 MUIM_DeleteDragImage
2189 **************************************************************************/
2190 static IPTR Area__MUIM_DeleteDragImage(struct IClass *cl, Object *obj, struct MUIP_DeleteDragImage *msg)
2192 if (msg->di)
2194 if (msg->di->bm) FreeBitMap(msg->di->bm);
2195 FreeVec(msg->di);
2197 return 0;
2200 /**************************************************************************
2201 MUIM_DragQueryExtended
2202 **************************************************************************/
2203 static IPTR Area__MUIM_DragQueryExtended(struct IClass *cl, Object *obj, struct MUIP_DragQueryExtended *msg)
2205 struct MUI_AreaData *data = INST_DATA(cl, obj);
2206 if (data->mad_Flags & MADF_DROPABLE)
2208 if (_left(obj) <= msg->x && msg->x <= _right(obj) && _top(obj) <= msg->y && msg->y <= _bottom(obj))
2210 if (DoMethod(obj,MUIM_DragQuery,(IPTR)msg->obj) == MUIV_DragQuery_Accept)
2211 return (IPTR)obj;
2214 return 0;
2217 /**************************************************************************
2218 MUIM_DragBegin
2219 **************************************************************************/
2220 static IPTR Area__MUIM_DragBegin(struct IClass *cl, Object *obj, struct MUIP_DragBegin *msg)
2222 //struct MUI_AreaData *data = INST_DATA(cl, obj);
2223 _zune_focus_new(obj, ZUNE_FOCUS_TYPE_DROP_OBJ);
2224 return 0;
2227 /**************************************************************************
2228 MUIM_DragFinish
2229 **************************************************************************/
2230 static IPTR Area__MUIM_DragFinish(struct IClass *cl, Object *obj, struct MUIP_DragFinish *msg)
2232 //struct MUI_AreaData *data = INST_DATA(cl, obj);
2233 _zune_focus_destroy(obj, ZUNE_FOCUS_TYPE_DROP_OBJ);
2234 return 0;
2239 * Calculates addleft, addtop, subwidth, subheight from current settings.
2240 * If frame phantom, ignore horizontal frame components.
2241 * Depends on inner sizes and frame
2243 static void area_update_msizes(Object *obj, struct MUI_AreaData *data,
2244 const struct MUI_FrameSpec_intern *frame,
2245 const struct ZuneFrameGfx *zframe)
2248 /* if (XGET(obj, MUIA_UserData) == 42) */
2249 /* { */
2250 /* D(bug("area_update_msizes(%p) : ileft=%ld itop=%ld\n", obj, zframe->ileft, zframe->itop)); */
2251 /* } */
2253 struct dt_frame_image *fi = zframe->customframe;
2255 if (fi != NULL)
2257 //UWORD w = fi->tile_left + fi->tile_right;
2258 //UWORD h = fi->tile_top + fi->tile_bottom;
2260 data->mad_addleft = data->mad_InnerLeft + zframe->ileft;
2261 data->mad_subwidth = data->mad_addleft + data->mad_InnerRight + zframe->iright;
2262 data->mad_addtop = data->mad_InnerTop + data->mad_TitleHeightAdd + zframe->itop;
2263 data->mad_subheight = data->mad_addtop + data->mad_InnerBottom + zframe->ibottom;
2265 else
2267 data->mad_addleft = data->mad_InnerLeft + zframe->ileft;
2268 data->mad_subwidth = data->mad_addleft + data->mad_InnerRight + zframe->iright;
2269 data->mad_addtop = data->mad_InnerTop + data->mad_TitleHeightAdd + zframe->itop;
2270 data->mad_subheight = data->mad_addtop + data->mad_InnerBottom + zframe->ibottom;
2273 if (data->mad_Flags & MADF_FRAMEPHANTOM)
2275 data->mad_addleft = 0;
2276 data->mad_subwidth = 0;
2279 // clamping ... maybe ?
2281 /* D(bug("area_update_msizes(%x,%d) => addleft/top=%d/%d, subwidth/height=%d/%d\n", */
2282 /* obj, data->mad_Frame, data->mad_addleft, data->mad_addtop, data->mad_subwidth, data->mad_subheight)); */
2285 /**************************************************************************
2286 MUIM_Area_UnknownDropDestination
2287 **************************************************************************/
2288 IPTR Area__MUIM_UnknownDropDestination(struct IClass *cl, Object *obj, struct MUIP_UnknownDropDestination *msg)
2291 return 0;
2294 /**************************************************************************
2295 MUIM_UpdateInnerSizes - Updates the innersizes of an object. You actually
2296 should only call this method if the dimensions of an object would not be
2297 affected, otherwise the results are unexpected
2298 **************************************************************************/
2299 static IPTR Area__MUIM_UpdateInnerSizes(struct IClass *cl, Object *obj, struct MUIP_UpdateInnerSizes *msg)
2301 struct MUI_AreaData *data = INST_DATA(cl, obj);
2302 const struct ZuneFrameGfx *zframe;
2303 const struct MUI_FrameSpec_intern *frame;
2304 struct MUI_FrameSpec_intern tempframe;
2306 if (_flags(obj) & MADF_SETUP)
2308 frame = get_intframe(obj, data, &tempframe);
2309 zframe = zune_zframe_get(obj, frame);
2310 area_update_msizes(obj, data, frame, zframe);
2312 return 1;
2315 static IPTR Area__MUIM_FindAreaObject(struct IClass *cl, Object *obj,
2316 struct MUIP_FindAreaObject *msg)
2318 if (msg->obj == obj)
2319 return (IPTR)obj;
2320 else
2321 return (IPTR)NULL;
2324 BOOPSI_DISPATCHER(IPTR, Area_Dispatcher, cl, obj, msg)
2326 switch (msg->MethodID)
2328 case OM_NEW: return Area__OM_NEW(cl, obj, (struct opSet *) msg);
2329 case OM_DISPOSE: return Area__OM_DISPOSE(cl, obj, msg);
2330 case OM_SET: return Area__OM_SET(cl, obj, (struct opSet *)msg);
2331 case OM_GET: return Area__OM_GET(cl, obj, (struct opGet *)msg);
2332 case MUIM_AskMinMax: return Area__MUIM_AskMinMax(cl, obj, (APTR)msg);
2333 case MUIM_Draw: return Area__MUIM_Draw(cl, obj, (APTR)msg);
2334 case MUIM_DrawBackground: return Area__MUIM_DrawBackground(cl, obj, (APTR)msg);
2335 case MUIM_DrawBackgroundBuffered: return Area__MUIM_DrawBackgroundBuffered(cl, obj, (APTR)msg);
2336 case MUIM_DrawParentBackground: return Area__MUIM_DrawParentBackground(cl, obj, (APTR)msg);
2337 case MUIM_Setup: return Area__MUIM_Setup(cl, obj, (APTR)msg);
2338 case MUIM_Cleanup: return Area__MUIM_Cleanup(cl, obj, (APTR)msg);
2339 case MUIM_Show: return Area__MUIM_Show(cl, obj, (APTR)msg);
2340 case MUIM_Hide: return Area__MUIM_Hide(cl, obj, (APTR)msg);
2341 case MUIM_GoActive: return Area__MUIM_GoActive(cl, obj, (APTR)msg);
2342 case MUIM_GoInactive: return Area__MUIM_GoInactive(cl, obj, (APTR)msg);
2343 case MUIM_Layout: return 1;
2344 case MUIM_CreateShortHelp: return Area__MUIM_CreateShortHelp(cl, obj, (APTR)msg);
2345 case MUIM_DeleteShortHelp: return Area__MUIM_DeleteShortHelp(cl, obj, (APTR)msg);
2346 case MUIM_CreateBubble: return Area__MUIM_CreateBubble(cl, obj, (APTR)msg);
2347 case MUIM_DeleteBubble: return Area__MUIM_DeleteBubble(cl, obj, (APTR)msg);
2348 case MUIM_HandleEvent: return Area__MUIM_HandleEvent(cl, obj, (APTR)msg);
2349 case MUIM_ContextMenuBuild: return Area__MUIM_ContextMenuBuild(cl, obj, (APTR)msg);
2350 case MUIM_ContextMenuChoice: return Area__MUIM_ContextMenuChoice(cl, obj, (APTR)msg);
2351 case MUIM_Timer: return Area__MUIM_Timer(cl,obj,msg);
2352 case MUIM_UpdateInnerSizes: return Area__MUIM_UpdateInnerSizes(cl,obj,(APTR)msg);
2353 case MUIM_DragQuery: return MUIV_DragQuery_Refuse;
2354 case MUIM_DragBegin: return Area__MUIM_DragBegin(cl,obj,(APTR)msg);
2355 case MUIM_DragDrop: return FALSE;
2356 case MUIM_UnknownDropDestination: return Area__MUIM_UnknownDropDestination(cl,obj,(APTR)msg);
2357 case MUIM_DragFinish: return Area__MUIM_DragFinish(cl,obj,(APTR)msg);
2358 case MUIM_DragReport: return MUIV_DragReport_Continue; /* or MUIV_DragReport_Abort? */
2359 case MUIM_DoDrag: return Area__MUIM_DoDrag(cl, obj, (APTR)msg);
2360 case MUIM_CreateDragImage: return Area__MUIM_CreateDragImage(cl, obj, (APTR)msg);
2361 case MUIM_DeleteDragImage: return Area__MUIM_DeleteDragImage(cl, obj, (APTR)msg);
2362 case MUIM_DragQueryExtended: return Area__MUIM_DragQueryExtended(cl, obj, (APTR)msg);
2363 case MUIM_HandleInput: return Area__MUIM_HandleInput(cl, obj, (APTR)msg);
2364 case MUIM_FindAreaObject: return Area__MUIM_FindAreaObject(cl, obj, (APTR)msg);
2366 case MUIM_Export: return Area__MUIM_Export(cl, obj, (APTR)msg);
2367 case MUIM_Import: return Area__MUIM_Import(cl, obj, (APTR)msg);
2370 return DoSuperMethodA(cl, obj, msg);
2372 BOOPSI_DISPATCHER_END
2376 * Class descriptor.
2378 const struct __MUIBuiltinClass _MUI_Area_desc = {
2379 MUIC_Area,
2380 MUIC_Notify,
2381 sizeof(struct MUI_AreaData),
2382 (void*)Area_Dispatcher