Hint added.
[AROS.git] / workbench / prefs / locale / page_timezone.c
blob5a1c86911b1c1ed3ecfd51b7c57499f98ed33838
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 /*************************************************************************/
11 // #define MUIMASTER_YES_INLINE_STDARG
13 #include <cybergraphx/cybergraphics.h>
15 //#define DEBUG 1
16 #include <zune/customclasses.h>
17 #include <zune/prefseditor.h>
19 #include <proto/alib.h>
20 #include <proto/intuition.h>
21 #include <proto/graphics.h>
22 #include <proto/cybergraphics.h>
23 #include <proto/utility.h>
24 #include <proto/muimaster.h>
26 #include <stdio.h>
28 #include <aros/debug.h>
30 #include "page_timezone.h"
31 #include "registertab.h"
32 #include "locale.h"
33 #include "misc.h"
34 #include "cities.h"
36 #include "earthmap_small_image.c"
37 #include "timezones_small_image.c"
39 /*************************************************************************/
41 #define H 16
43 #define DOUBLE_ARROWS 1
45 #define CONTINENT_RED 18
46 #define CONTINENT_GREEN 114
47 #define CONTINENT_BLUE 58
49 #define OCEAN_RED 21
50 #define OCEAN_GREEN 18
51 #define OCEAN_BLUE 114
53 #define SELECTED_INTENSITY_INC 80
55 #define GAD_DEC 1000
56 #define GAD_INC 1001
57 #define GAD_TEXT 1002
59 /*************************************************************************/
61 #define NUM_TIMEZONES 36
63 static struct timezone
65 LONG id;
66 LONG minoffset;
67 LONG pen;
70 timezone_table[NUM_TIMEZONES] =
72 { 0, 0 , -1 }, /* Z : 0:00 */
73 { 1, 1 * 60 , -1 }, /* A : + 1:00 */
74 { 2, 2 * 60 , -1 }, /* B : + 2:00 */
75 { 3, 3 * 60 , -1 }, /* C : + 3:00 */
76 { 4, 3 * 60 + 30 , -1 }, /* C*: + 3:30 */
77 { 5, 4 * 60 , -1 }, /* D : + 4:00 */
78 { 6, 4 * 60 + 30 , -1 }, /* D*: + 4:30 */
79 { 7, 5 * 60 , -1 }, /* E : + 5:00 */
80 { 8, 5 * 60 + 30 , -1 }, /* E*: + 5:30 */
81 { 9, 6 * 60 , -1 }, /* F : + 6:00 */
82 { 10, 6 * 60 + 30 , -1 }, /* F*: + 6:30 */
83 { 11, 7 * 60 , -1 }, /* G : + 7:00 */
84 { 12, 8 * 60 , -1 }, /* H : + 8:00 */
85 { 13, 9 * 60 , -1 }, /* I : + 9:00 */
86 { 14, 9 * 60 + 30 , -1 }, /* I*: + 9:30 */
87 { 15, 10 * 60 , -1 }, /* K : + 10:00 */
88 { 16, 10 * 60 + 30 , -1 }, /* K*: + 10:30 */
89 { 17, 11 * 60 , -1 }, /* L : + 11:00 */
90 { 18, 11 * 60 + 30 , -1 }, /* L*: + 11:30 */
91 { 19, 12 * 60 , -1 }, /* M : + 12:00 */
92 { 20, 13 * 60 , -1 }, /* M*: + 13:00 */
93 { 35, -12 * 60 , -1 }, /* Y : - 12:00 */
94 { 34, -11 * 60 , -1 }, /* X : - 11:00 */
95 { 33, -10 * 60 , -1 }, /* W : - 10:00 */
96 { 32, -9 * 60 - 30 , -1 }, /* V*: - 9:30 */
97 { 31, -9 * 60 , -1 }, /* V : - 9:00 */
98 { 30, -8 * 60 - 30 , -1 }, /* U*: - 8:30 */
99 { 29, -8 * 60 , -1 }, /* U : - 8:00 */
100 { 28, -7 * 60 , -1 }, /* T : - 7:00 */
101 { 27, -6 * 60 , -1 }, /* S : - 6:00 */
102 { 26, -5 * 60 , -1 }, /* R : - 5:00 */
103 { 25, -4 * 60 , -1 }, /* Q : - 4:00 */
104 { 24, -3 * 60 - 30 , -1 }, /* P*: - 3:30 */
105 { 23, -3 * 60 , -1 }, /* P : - 3:00 */
106 { 22, -2 * 60 , -1 }, /* O : - 2:00 */
107 { 21, -1 * 60 , -1 }, /* N : - 1:00 */
110 /*************************************************************************/
112 struct Timezone_DATA
114 Object *me;
115 Object *zone_name;
116 Object *city_name;
117 Object *gmt_switch;
118 Object *gmt_label;
119 Object *prefs;
120 struct Hook h;
121 struct Hook Timezone_list_hook;
122 LONG remaptable[256];
123 ULONG earthmap_coltab[256];
124 LONG lp_GMTOffset;
125 char **city_select_names;
126 BOOL truecolor;
128 struct MUI_EventHandlerNode ehn;
131 struct MUI_CustomClass *Timezone_CLASS;
133 /*************************************************************************/
135 static WORD active_timezone;
137 static UBYTE timezones_chunky[TIMEZONES_SMALL_WIDTH * TIMEZONES_SMALL_HEIGHT];
138 static UBYTE earthmap_chunky[EARTHMAP_SMALL_WIDTH * EARTHMAP_SMALL_HEIGHT];
139 static UBYTE *earthmap_chunky_remapped;
141 static char timezone_text[256];
142 static LONG pen2index[NUM_TIMEZONES];
144 static BOOL pens_alloced;
146 /*************************************************************************/
148 #if EARTHMAP_SMALL_PACKED || TIMEZONES_SMALL_PACKED
150 static const UBYTE *unpack_byterun1(const UBYTE *source, UBYTE *dest, LONG unpackedsize)
152 UBYTE r;
153 BYTE c;
155 for(;;)
157 c = (BYTE)(*source++);
158 if (c >= 0)
160 while(c-- >= 0)
162 *dest++ = *source++;
163 if (--unpackedsize <= 0) return source;
166 else if (c != -128)
168 c = -c;
169 r = *source++;
171 while(c-- >= 0)
173 *dest++ = r;
174 if (--unpackedsize <= 0) return source;
181 #endif
183 /*************************************************************************/
185 static LONG timezone_init(Object *obj,struct Timezone_DATA *data)
187 LONG i;
188 LONG id;
189 LONG i2;
190 ULONG a;
191 ULONG r;
192 ULONG g;
193 ULONG b;
194 ULONG rgb;
196 D(bug("[timezone class] timezone_init\n"));
198 data->truecolor = GetBitMapAttr(_screen(obj)->RastPort.BitMap, BMA_DEPTH) >= 15;
200 if (!data->truecolor)
202 earthmap_chunky_remapped = AllocVec(EARTHMAP_SMALL_WIDTH * EARTHMAP_SMALL_HEIGHT, MEMF_PUBLIC);
203 if (!earthmap_chunky_remapped)
204 return FALSE;
207 #if EARTHMAP_SMALL_PACKED
208 unpack_byterun1(earthmap_small_data, earthmap_chunky, EARTHMAP_SMALL_WIDTH * EARTHMAP_SMALL_HEIGHT);
209 #endif
210 #if TIMEZONES_SMALL_PACKED
211 unpack_byterun1(timezones_small_data, timezones_chunky, TIMEZONES_SMALL_WIDTH * TIMEZONES_SMALL_HEIGHT);
212 #endif
214 for(i = 0; i < EARTHMAP_SMALL_COLORS; i++)
216 rgb = earthmap_small_pal[i];
217 r = (rgb & 0xFF0000) >> 16;
218 g = (rgb & 0x00FF00) >> 8;
219 b = (rgb & 0x0000FF);
220 a = (r + g + b) / 3;
222 r = (a * OCEAN_RED + (255 - a) * CONTINENT_RED ) / 255;
223 g = (a * OCEAN_GREEN + (255 - a) * CONTINENT_GREEN) / 255;
224 b = (a * OCEAN_BLUE + (255 - a) * CONTINENT_BLUE ) / 255;
226 rgb = (r << 16) + (g << 8) + b;
228 data->earthmap_coltab[i] = rgb;
230 if (!data->truecolor)
232 data->remaptable[i] = ObtainBestPen(_screen(obj)->ViewPort.ColorMap,
233 r * 0x01010101,
234 g * 0x01010101,
235 b * 0x01010101,
236 OBP_Precision, PRECISION_IMAGE,
237 OBP_FailIfBad, FALSE,
238 TAG_DONE);
241 r += SELECTED_INTENSITY_INC; if (r > 255) r = 255;
242 g += SELECTED_INTENSITY_INC; if (g > 255) g = 255;
243 b += SELECTED_INTENSITY_INC; if (b > 255) b = 255;
245 rgb = (r << 16) + (g << 8) + b;
247 data->earthmap_coltab[128 + i] = rgb;
249 if (!data->truecolor)
251 data->remaptable[128 + i] = ObtainBestPen(_screen(obj)->ViewPort.ColorMap,
252 r * 0x01010101,
253 g * 0x01010101,
254 b * 0x01010101,
255 OBP_Precision, PRECISION_IMAGE,
256 OBP_FailIfBad, FALSE,
257 TAG_DONE);
262 if (!data->truecolor) pens_alloced = TRUE;
264 /* For each timezone find out, with which pen (index) it is
265 represented in the timezones image */
267 for(i = 0; i < NUM_TIMEZONES; i++)
269 id = timezone_table[i].id;
270 r = ((id & 0x30) >> 4) * 64;
271 g = ((id & 0x0C) >> 2) * 64;
272 b = ((id & 0x03) ) * 64;
273 rgb = (r << 16) + (g << 8) + b;
275 for(i2 = 0; i2 < TIMEZONES_SMALL_COLORS; i2++)
277 if (timezones_small_pal[i2] == rgb)
279 timezone_table[i].pen = i2;
280 break;
284 pen2index[id] = i;
287 return TRUE;
290 /*************************************************************************/
292 static void ClearEarthmapSelection(void)
294 LONG l;
296 for(l = 0; l < EARTHMAP_SMALL_WIDTH * EARTHMAP_SMALL_HEIGHT; l++)
298 earthmap_chunky[l] &= 127;
302 /*************************************************************************/
304 static void SetEarthmapSelection(UBYTE timezonespen)
306 LONG l;
308 for(l = 0; l < EARTHMAP_SMALL_WIDTH * EARTHMAP_SMALL_HEIGHT; l++)
310 if (timezones_chunky[l] == timezonespen) earthmap_chunky[l] |= 128;
314 /*************************************************************************/
316 static void UpdateZoneName(Object *zone_name, char *newname, BOOL noNotify)
318 char *old = NULL;
320 GET(zone_name, MUIA_Text_Contents, &old);
322 if(old && strcmp(old, newname))
324 SetAttrs(zone_name, MUIA_Text_Contents, newname, MUIA_NoNotify, noNotify, TAG_DONE);
328 /*************************************************************************/
330 static void RepaintEarthmap(Object *obj, struct Timezone_DATA *data, BOOL noNotify)
332 char *fmt;
333 WORD minoffset; /* is only used for text gadget */
335 minoffset = timezone_table[active_timezone].minoffset;
337 if (data->truecolor)
339 WriteLUTPixelArray(earthmap_chunky,
342 EARTHMAP_SMALL_WIDTH,
343 _rp(obj),
344 data->earthmap_coltab,
345 _mleft(obj) +1,
346 _mtop(obj) +1,
347 EARTHMAP_SMALL_WIDTH,
348 EARTHMAP_SMALL_HEIGHT,
349 CTABFMT_XRGB8);
351 else
353 LONG l;
355 for(l = 0; l < EARTHMAP_SMALL_WIDTH * EARTHMAP_SMALL_HEIGHT; l++)
357 earthmap_chunky_remapped[l] = data->remaptable[earthmap_chunky[l]];
360 WriteChunkyPixels(_rp(obj),
361 _mleft(obj) + 1,
362 _mtop(obj) + 1,
363 _mleft(obj) + EARTHMAP_SMALL_WIDTH,
364 _mtop(obj) + EARTHMAP_SMALL_HEIGHT,
365 earthmap_chunky_remapped,
366 EARTHMAP_SMALL_WIDTH);
369 if (minoffset < 0)
370 minoffset = -minoffset;
372 if (minoffset == 60)
374 fmt = (char *) _(MSG_TIMEZONE_1HOUR);
376 else if (minoffset % 60)
378 fmt = (char *) _(MSG_TIMEZONE_HOURSMINS);
380 else
382 fmt = (char *) _(MSG_TIMEZONE_HOURS);
385 sprintf(timezone_text, fmt, minoffset / 60, minoffset % 60);
387 UpdateZoneName(data->zone_name, timezone_text, noNotify);
390 /*************************************************************************/
392 static void timezone_cleanup(Object *obj, struct Timezone_DATA *data)
394 WORD i;
396 if (earthmap_chunky_remapped)
398 FreeVec(earthmap_chunky_remapped);
399 earthmap_chunky_remapped = NULL;
402 if (pens_alloced)
404 for(i = 0; i < EARTHMAP_SMALL_COLORS; i++)
406 if (data->remaptable[i] != -1)
408 ReleasePen(_screen(obj)->ViewPort.ColorMap, data->remaptable[i]);
409 data->remaptable[i] = -1;
411 if (data->remaptable[128 + i] != -1)
413 ReleasePen(_screen(obj)->ViewPort.ColorMap, data->remaptable[128 + i]);
414 data->remaptable[128 + i] = -1;
417 pens_alloced = FALSE;
421 /*************************************************************************/
423 STATIC IPTR Timezone__MUIM_Draw(struct IClass *cl, Object *obj, struct MUIP_Draw *msg)
425 struct Timezone_DATA *data = INST_DATA(cl, obj);
427 struct DrawInfo *dri=_dri(obj);
429 DoSuperMethodA(cl, obj, (Msg)msg);
431 if ( !(msg->flags & MADF_DRAWOBJECT) &&
432 !(msg->flags & MADF_DRAWUPDATE) )
434 D(bug("[timezone class] nothing to draw (!MADF_DRAWOBJECT and !MADF_DRAWUPDATE)\n"));
435 return 0;
438 SetDrMd(_rp(obj), JAM1);
440 SetAPen(_rp(obj), dri->dri_Pens[SHADOWPEN]);
442 RectFill(_rp(obj), _mleft(obj),
443 _mtop(obj),
444 _mleft(obj) + _mwidth(obj) - 2,
445 _mtop(obj));
447 RectFill(_rp(obj), _mleft(obj),
448 _mtop(obj) + 1,
449 _mleft(obj),
450 _mtop(obj) + EARTHMAP_SMALL_HEIGHT + 2 - 1);
452 SetAPen(_rp(obj), dri->dri_Pens[SHINEPEN]);
454 RectFill(_rp(obj), _mleft(obj) + _mwidth(obj) - 1,
455 _mtop(obj),
456 _mleft(obj) + _mwidth(obj) - 1,
457 _mtop(obj) + EARTHMAP_SMALL_HEIGHT + 2 - 1);
459 RectFill(_rp(obj), _mleft(obj) + 1,
460 _mtop(obj) + EARTHMAP_SMALL_HEIGHT + 2 - 1,
461 _mleft(obj) + _mwidth(obj) - 2,
462 _mtop(obj) + EARTHMAP_SMALL_HEIGHT + 2 - 1);
464 RepaintEarthmap(obj, data, TRUE);
466 return TRUE;
469 /*************************************************************************/
471 AROS_UFH3(
472 static ULONG, LayoutHook,
473 AROS_UFHA(struct Hook *, hook, A0),
474 AROS_UFHA(APTR, obj, A2),
475 AROS_UFHA(struct MUI_LayoutMsg *, lm, A1))
477 AROS_USERFUNC_INIT
478 struct Timezone_DATA *data = hook->h_Data;
480 D(bug("[timezone class] LayoutHook\n"));
482 switch (lm->lm_Type)
484 case MUILM_MINMAX:
487 lm->lm_MinMax.MinWidth = EARTHMAP_SMALL_WIDTH +
488 _minwidth(data->city_name);
489 lm->lm_MinMax.MinHeight = EARTHMAP_SMALL_HEIGHT +
490 _minheight(data->zone_name) + _minheight(data->gmt_switch) + H + (H/2);
492 lm->lm_MinMax.DefWidth = EARTHMAP_SMALL_WIDTH +
493 _defwidth(data->city_name);
494 lm->lm_MinMax.DefHeight = EARTHMAP_SMALL_HEIGHT +
495 _defheight(data->zone_name) + _defheight(data->gmt_switch) + H + (H/2);
497 lm->lm_MinMax.MaxWidth = EARTHMAP_SMALL_WIDTH +
498 _maxwidth(data->city_name);
499 lm->lm_MinMax.MaxHeight = EARTHMAP_SMALL_HEIGHT +
500 _maxheight(data->zone_name) + _maxheight(data->gmt_switch);
501 return 0;
503 case MUILM_LAYOUT:
505 /* we only have a few childs ;) */
507 if(!MUI_Layout(data->city_name,
508 /* x,y */
509 EARTHMAP_SMALL_WIDTH , 1,
510 /* width, height: */
511 _defwidth(data->city_name), EARTHMAP_SMALL_HEIGHT,
514 return FALSE;
517 if(!MUI_Layout(data->zone_name,
518 1, EARTHMAP_SMALL_HEIGHT + (H/2),
519 /* full width */
520 EARTHMAP_SMALL_WIDTH + _defwidth(data->city_name),
521 _minheight(data->zone_name),0))
523 return FALSE;
526 if(!MUI_Layout(data->gmt_switch,
527 1, EARTHMAP_SMALL_HEIGHT + H + _minheight(data->zone_name),
528 /* full width */
529 _minwidth(data->gmt_switch),
530 _minheight(data->gmt_switch),0))
532 return FALSE;
535 if(!MUI_Layout(data->gmt_label,
536 1 + _minwidth(data->gmt_switch) + (H/2), EARTHMAP_SMALL_HEIGHT + H + _minheight(data->zone_name),
537 /* full width */
538 _minwidth(data->gmt_label),
539 _minheight(data->gmt_label),0))
541 return FALSE;
544 return TRUE;
548 return MUILM_UNKNOWN;
550 AROS_USERFUNC_EXIT
553 /*************************************************************************/
555 AROS_UFH2(
556 void, Timezone_list_hook_func,
557 AROS_UFHA(struct Hook *, hook, A0),
558 AROS_UFHA(APTR, obj, A2)
561 AROS_USERFUNC_INIT
562 struct Timezone_DATA *data= hook->h_Data;
563 ULONG sel = 0;
564 ULONG i;
565 LONG tz;
567 GET(obj, MUIA_List_Active, &sel);
568 D(bug("[timezone class] Timezone_list_hook_func: %d\n",sel));
570 tz=-1;
571 i = 0;
572 while ((tz < 0) && (i < NUM_TIMEZONES))
574 if(CityArray[sel].timediff / 100*60 == timezone_table[i].minoffset)
576 D(bug("[timezone class] Found timezone: %s\n", CityArray[sel].city_name));
577 tz=i;
579 i++;
582 active_timezone = tz;
584 data->lp_GMTOffset = -timezone_table[active_timezone].minoffset;
586 ClearEarthmapSelection();
587 SetEarthmapSelection(timezone_table[tz].pen);
588 RepaintEarthmap(data->me, data, FALSE);
590 AROS_USERFUNC_EXIT
592 /*************************************************************************/
594 static Object *handle_New_error(Object *obj, struct IClass *cl, char *error)
596 struct Timezone_DATA *data;
598 D(bug("[Timezone class] %s\n",error));
599 ShowMessage(error);
601 if(!obj)
602 return NULL;
604 data = INST_DATA(cl, obj);
606 if (data->gmt_label)
607 DisposeObject(data->gmt_label);
609 if (data->gmt_switch)
610 DisposeObject(data->gmt_switch);
612 if(data->zone_name)
614 DisposeObject(data->zone_name);
615 data->zone_name = NULL;
618 if(data->city_select_names)
620 FreeVec(data->city_select_names);
621 data->city_select_names = NULL;
624 CoerceMethod(cl, obj, OM_DISPOSE);
625 return NULL;
628 Object *Timezone__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
630 struct Timezone_DATA *data;
631 struct TagItem *tstate, *tag;
632 ULONG i;
634 D(bug("[timezone class] Timezone new\n"));
636 obj = (Object *) DoSuperNewTags
638 cl, obj, NULL,
639 MUIA_Frame, MUIV_Frame_Text,
640 TAG_DONE
643 if (obj == NULL)
645 return handle_New_error(obj, cl, "ERROR: Unable to create object!\n");
648 data = INST_DATA(cl, obj);
649 data->me = obj;
651 tstate = ((struct opSet *)msg)->ops_AttrList;
652 while ((tag = (struct TagItem *) NextTagItem((APTR) &tstate)))
654 switch (tag->ti_Tag)
656 case MUIA_UserData:
657 data->prefs = (Object *) tag->ti_Data;
658 break;
662 if (!data->prefs)
664 return handle_New_error(obj, cl, "ERROR: MA_PrefsObject not supplied!\n");
667 /* Layout Hook */
668 data->h.h_Entry = (HOOKFUNC) LayoutHook;
669 data->h.h_Data = data;
670 SET(obj, MUIA_Group_LayoutHook, &data->h);
672 /* xx hours away from GMT */
673 data->zone_name = TextObject,
674 MUIA_Frame, MUIV_Frame_Text,
675 MUIA_Text_PreParse, "\33c",
676 MUIA_Text_Contents, "-", /* will be replaced anyway */
677 End;
679 if(!data->zone_name)
681 return handle_New_error(obj,cl,"ERROR: Unable to create TextObject!\n");
684 /* count cities */
685 i = 0;
686 while(CityArray[i].city_name != NULL)
688 i++;
691 /* build SourceArray */
692 data->city_select_names = AllocVec((i + 1) * sizeof(IPTR), MEMF_CLEAR);
693 if(!data->city_select_names)
695 /* we are dead anyway, but .. */
696 return handle_New_error(obj, cl, "ERROR: Out of memory!\n");
699 i = 0;
700 while (CityArray[i].city_name != NULL)
702 data->city_select_names[i] = CityArray[i].city_name;
703 i++;
705 data->city_select_names[i] = NULL;
707 /* city selection list */
708 data->city_name = ListviewObject,
709 MUIA_Listview_List,
710 /* This crashes the List in FamilyAddTail..?:
711 * MUIA_Listview_MultiSelect, MUIV_Listview_ScrollerPos_Default
713 ListObject, InputListFrame,
714 MUIA_List_AdjustWidth, TRUE,
715 MUIA_List_SourceArray, data->city_select_names,
716 End,
717 End;
719 if(!data->city_name)
721 return handle_New_error(obj, cl, "ERROR: unable to create city_name ListviewObject!\n");
724 data->gmt_switch = MUI_MakeObject(MUIO_Checkmark, NULL);
725 if (!data->gmt_switch)
726 return handle_New_error(obj, cl, "ERROR: unable to create checkmark bject!\n");
728 data->gmt_label = Label1(_(MSG_GMT_CLOCK));
729 if (!data->gmt_label)
730 return handle_New_error(obj, cl, "ERROR: unable to create label object!\n");
732 DoMethod(obj, OM_ADDMEMBER, data->zone_name);
733 DoMethod(obj, OM_ADDMEMBER, data->city_name);
734 DoMethod(obj, OM_ADDMEMBER, data->gmt_switch);
735 DoMethod(obj, OM_ADDMEMBER, data->gmt_label);
737 data->Timezone_list_hook.h_Entry = (HOOKFUNC) &Timezone_list_hook_func;
738 data->Timezone_list_hook.h_Data = data ;
739 DoMethod(data->city_name,
740 MUIM_Notify, MUIA_List_Active,
741 MUIV_EveryTime, data->city_name,
742 2, MUIM_CallHook, &data->Timezone_list_hook);
744 /* handle mouse clicks to map image */
745 data->ehn.ehn_Events = IDCMP_MOUSEBUTTONS |
746 IDCMP_ACTIVEWINDOW |
747 IDCMP_INACTIVEWINDOW;
748 data->ehn.ehn_Priority = 0;
749 data->ehn.ehn_Flags = 0;
750 data->ehn.ehn_Object = obj;
751 data->ehn.ehn_Class = cl;
753 /* changed hooks */
754 DoMethod(data->zone_name, MUIM_Notify, MUIA_Text_Contents, MUIV_EveryTime, (IPTR) data->prefs, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
755 DoMethod(data->gmt_switch, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, (IPTR) data->prefs, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
757 return obj;
760 /*************************************************************************/
762 static IPTR Timezone__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
764 struct Timezone_DATA *data = INST_DATA(cl, obj);
766 if(data->city_select_names)
768 FreeVec(data->city_select_names);
769 data->city_select_names = NULL;
772 return DoSuperMethodA(cl, obj, msg);
775 /*** Setup ******************************************************************/
776 static IPTR Timezone__MUIM_Setup(struct IClass *cl, Object *obj, Msg msg)
778 struct Timezone_DATA *data = INST_DATA(cl, obj);
779 D(bug("[timezone class] Timezone_Setup\n"));
781 if (!DoSuperMethodA(cl, obj, msg))
782 return FALSE;
784 DoMethod(_win(obj), MUIM_Window_AddEventHandler, (IPTR)&data->ehn);
786 return timezone_init(obj, data);
789 static IPTR Timezone__MUIM_Cleanup(Class *cl, Object *obj, struct MUIP_Cleanup *msg)
791 struct Timezone_DATA *data = INST_DATA(cl, obj);
793 D(bug("[timezone class] Timezone_Cleanup\n"));
795 DoMethod(_win(obj), MUIM_Window_RemEventHandler, (IPTR)&data->ehn);
797 timezone_cleanup(obj, data);
799 return DoSuperMethodA(cl, obj, (Msg)msg);
802 /* handle clicks on the map */
803 static IPTR Timezone__MUIM_HandleEvent(struct IClass *cl, Object *obj, struct MUIP_HandleEvent *msg)
805 struct Timezone_DATA *data = INST_DATA(cl, obj);
807 if (msg->imsg)
809 LONG mx = msg->imsg->MouseX - _left(obj);
810 LONG my = msg->imsg->MouseY - _top(obj);
811 switch (msg->imsg->Class)
813 case IDCMP_MOUSEBUTTONS:
814 if (msg->imsg->Code == SELECTDOWN)
816 if(my > 0 && my < EARTHMAP_SMALL_HEIGHT &&
817 mx > 0 && mx < EARTHMAP_SMALL_WIDTH)
819 ULONG timezonergb;
820 LONG timezoneid;
821 UBYTE timezonepen;
823 timezonepen = timezones_chunky[my * TIMEZONES_SMALL_WIDTH + mx];
824 timezonergb = timezones_small_pal[timezonepen];
825 timezoneid = (timezonergb & 0xC00000) >> (16 + 2);
826 timezoneid += (timezonergb & 0x00C000) >> (8 + 4);
827 timezoneid += (timezonergb & 0x0000C0) >> (0 + 6);
829 if ((timezoneid >= 0) && (timezoneid < NUM_TIMEZONES))
831 active_timezone = pen2index[timezoneid];
833 /* AmigaOS seems to have the sign the other way round, therefore the "-" */
835 data->lp_GMTOffset = -timezone_table[active_timezone].minoffset;
836 D(bug("[timezone class] data->lp_GMTOffset: %d\n",data->lp_GMTOffset));
838 ClearEarthmapSelection();
839 SetEarthmapSelection(timezonepen);
840 RepaintEarthmap(obj, data, FALSE);
841 NNSET(data->city_name, MUIA_List_Active, MUIV_List_Active_Off);
847 return 0;
850 /*** Get ******************************************************************/
851 static IPTR Timezone__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
853 struct Timezone_DATA *data = INST_DATA(cl, obj);
854 IPTR rc;
856 switch (msg->opg_AttrID)
858 case MUIA_Timezone_Timeoffset:
859 rc = data->lp_GMTOffset;
860 D(bug("[timezone class] Timezone_Get: MA_TimeOffset: %d\n",rc));
861 break;
863 case MUIA_Timezone_GMTClock:
864 GetAttr(MUIA_Selected, data->gmt_switch, &rc);
865 break;
867 default:
868 return DoSuperMethodA(cl, obj, (Msg)msg);
871 *msg->opg_Storage = rc;
872 return TRUE;
875 /*** Set ******************************************************************/
876 static IPTR Timezone__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
878 struct Timezone_DATA *data = INST_DATA(cl, obj);
879 struct TagItem *tstate, *tag;
880 ULONG update;
881 ULONG i;
882 LONG tz;
883 LONG t;
885 tstate = msg->ops_AttrList;
886 update = FALSE;
888 while ((tag = (struct TagItem *) NextTagItem((APTR) &tstate)))
890 switch (tag->ti_Tag)
892 case MUIA_Timezone_Timeoffset:
893 tz=-1;
894 i = 0;
895 t = (LONG)tag->ti_Data;
896 D(bug("[timezone class] Timezone_Set: t: %d\n",t));
897 while ((tz < 0) && (i < NUM_TIMEZONES))
899 if(t == timezone_table[i].minoffset)
901 D(bug("[timezone class] Found timezone: %d\n",i));
902 tz = i;
904 i++;
907 if(tz < 0)
909 D(bug("[timezone class] ERROR: Could not find timezone !?\n"));
910 break;
913 active_timezone = tz;
914 /* removed - */
915 data->lp_GMTOffset = timezone_table[active_timezone].minoffset;
916 D(bug("[timezone class] Timezone_Set; data->lp_GMTOffset: %d\n",data->lp_GMTOffset));
918 ClearEarthmapSelection();
919 SetEarthmapSelection(timezone_table[tz].pen);
921 update=TRUE;
922 break;
924 case MUIA_Timezone_GMTClock:
925 SetAttrs(data->gmt_switch, MUIA_Selected, tag->ti_Data, MUIA_NoNotify, TRUE, TAG_DONE);
926 break;
928 default:
929 return DoSuperMethodA(cl, obj, (Msg)msg);
933 if(update)
935 MUI_Redraw(obj, MADF_DRAWOBJECT);
938 return TRUE;
941 /*** Setup ******************************************************************/
942 ZUNE_CUSTOMCLASS_8
944 Timezone, NULL, MUIC_Group, NULL,
945 OM_NEW, struct opSet *,
946 OM_SET, struct opSet *,
947 OM_GET, struct opGet *,
948 OM_DISPOSE, Msg,
949 MUIM_Setup, Msg,
950 MUIM_Draw, struct MUIP_Draw *,
951 MUIM_Cleanup, struct MUIP_Cleanup *,
952 MUIM_HandleEvent, struct MUIP_HandleEvent *