Some fix for scrolling with lasso.
[tangerine.git] / workbench / tools / HDToolBox / ptclass.c
blobe137b1121a9ce325301599535671b2d6637ef101
1 /*
2 Copyright © 1995-2002, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <string.h>
8 #include <proto/alib.h>
9 #include <proto/exec.h>
10 #include <proto/graphics.h>
11 #include <proto/intuition.h>
12 #include <proto/utility.h>
14 #include <intuition/cghooks.h>
15 #include <intuition/classes.h>
16 #include <intuition/classusr.h>
17 #include <intuition/gadgetclass.h>
18 #include <intuition/intuition.h>
19 #include <intuition/imageclass.h>
21 #include <string.h>
23 #include "ptclass.h"
24 #include "partitions.h"
25 #include "partitiontables.h"
26 #include "platform.h"
28 #define DEBUG 0
29 #include "debug.h"
31 #define G(a) ((struct Gadget *)a)
33 #define DPTYPE_EMPTY 0
34 #define DPTYPE_EMPTY_SELECTED 1
35 #define DPTYPE_USED 2
36 #define DPTYPE_USED_SELECTED 3
38 #define PARTITIONBLOCK_FRAMEWIDTH 2
40 #define END_FIX 1
42 #define EMPTY1_RED 0x99999999
43 #define EMPTY1_GREEN 0x99999999
44 #define EMPTY1_BLUE 0x99999999
46 #define EMPTY2_RED 0x65656565
47 #define EMPTY2_GREEN 0x65656565
48 #define EMPTY2_BLUE 0x65656565
50 #define EMPTY1_DARK_RED 0x66666666
51 #define EMPTY1_DARK_GREEN 0x66666666
52 #define EMPTY1_DARK_BLUE 0x66666666
54 #define EMPTY2_DARK_RED 0x42424242
55 #define EMPTY2_DARK_GREEN 0x42424242
56 #define EMPTY2_DARK_BLUE 0x42424242
58 #define EMPTY1_SEL_RED 0x40404040
59 #define EMPTY1_SEL_GREEN 0x85858585
60 #define EMPTY1_SEL_BLUE 0x99999999
62 #define EMPTY2_SEL_RED 0x29292929
63 #define EMPTY2_SEL_GREEN 0x56565656
64 #define EMPTY2_SEL_BLUE 0x63636363
66 #define USED_RED 0x02020202
67 #define USED_GREEN 0x75757575
68 #define USED_BLUE 0x02020202
70 #define USED_SEL_RED 0x66666666
71 #define USED_SEL_GREEN 0xc9c9c9c9
72 #define USED_SEL_BLUE 0x66666666
74 #define PEN_EMPTY1 0
75 #define PEN_EMPTY2 1
76 #define PEN_EMPTY1_SEL 2
77 #define PEN_EMPTY2_SEL 3
78 #define PEN_EMPTY1_DARK 4
79 #define PEN_EMPTY2_DARK 5
80 #define PEN_USED 6
81 #define PEN_USED_SEL 7
83 #define NUM_PENS 8
85 STATIC CONST ULONG rgbtable[] =
87 EMPTY1_RED , EMPTY1_GREEN , EMPTY1_BLUE ,
88 EMPTY2_RED , EMPTY2_GREEN , EMPTY2_BLUE ,
89 EMPTY1_SEL_RED , EMPTY1_SEL_GREEN , EMPTY1_SEL_BLUE ,
90 EMPTY2_SEL_RED , EMPTY2_SEL_GREEN , EMPTY2_SEL_BLUE ,
91 EMPTY1_DARK_RED , EMPTY1_DARK_GREEN , EMPTY1_DARK_BLUE ,
92 EMPTY2_DARK_RED , EMPTY2_DARK_GREEN , EMPTY2_DARK_BLUE ,
93 USED_RED , USED_GREEN , USED_BLUE ,
94 USED_SEL_RED , USED_SEL_GREEN , USED_SEL_BLUE
97 struct PTableData {
98 struct DrawInfo *dri;
99 struct Image *frame;
100 struct HDTBPartition *table;
101 struct HDTBPartition *active; /* active partition */
102 struct DosEnvec gap;
103 struct ColorMap *cm;
104 ULONG block;
105 ULONG flags;
106 WORD pens[NUM_PENS];
107 BOOL move;
108 BOOL selected;
109 BOOL multicolor;
110 BOOL firstdraw;
111 BOOL pensallocated;
114 STATIC UWORD pattern[]=
116 0xAAAA, 0xAAAA,
117 0x5555, 0x5555
120 STATIC UWORD pattern2[] =
122 0xFF00,
123 0xFF00,
124 0xFF00,
125 0xFF00,
126 0xFF00,
127 0xFF00,
128 0xFF00,
129 0xFF00,
130 0x00FF,
131 0x00FF,
132 0x00FF,
133 0x00FF,
134 0x00FF,
135 0x00FF,
136 0x00FF,
137 0x00FF
140 #define SetPattern(r,p,s) {r->AreaPtrn = (UWORD *)p; r->AreaPtSz = s;}
142 Class *ptcl=0;
145 static void PrepareRP(struct RastPort *rp, struct PTableData *data, WORD dptype)
147 if (data->multicolor)
149 switch(dptype)
151 case DPTYPE_EMPTY:
152 SetPattern(rp, pattern2, 4);
153 SetABPenDrMd(rp, data->pens[PEN_EMPTY1], data->pens[PEN_EMPTY2], JAM2);
154 break;
156 case DPTYPE_EMPTY_SELECTED:
157 SetPattern(rp, pattern2, 4);
158 SetABPenDrMd(rp, data->pens[PEN_EMPTY1_SEL], data->pens[PEN_EMPTY2_SEL], JAM2);
159 break;
161 case DPTYPE_USED:
162 SetPattern(rp, NULL, 0);
163 SetABPenDrMd(rp, data->pens[PEN_USED], 0, JAM2);
164 break;
166 case DPTYPE_USED_SELECTED:
167 SetPattern(rp, NULL, 0);
168 SetABPenDrMd(rp, data->pens[PEN_USED_SEL], 0, JAM2);
169 break;
171 } /* if (data->multicolor) */
172 else
174 switch(dptype)
176 case DPTYPE_EMPTY:
177 SetPattern(rp, NULL, 0);
178 SetABPenDrMd(rp, 0, 0, JAM2);
179 break;
181 case DPTYPE_EMPTY_SELECTED:
182 SetPattern(rp, pattern, 2);
183 SetABPenDrMd(rp, 1, 0, JAM2);
184 break;
186 case DPTYPE_USED:
187 SetPattern(rp, pattern, 2);
188 SetABPenDrMd(rp, 2, 0, JAM2);
189 break;
191 case DPTYPE_USED_SELECTED:
192 SetPattern(rp, pattern, 2);
193 SetABPenDrMd(rp, 3, 0, JAM2);
194 break;
198 } /* if (data->multicolor) */
202 STATIC IPTR pt_new(Class *cl, Object *obj, struct opSet *msg) {
203 struct PTableData *data;
204 struct DrawInfo *dri;
205 struct Image *frame;
206 struct HDTBPartition *table;
207 ULONG flags;
208 struct TagItem tags[]=
210 {IA_Width , 0UL },
211 {IA_Height , 0UL },
212 {IA_Resolution , 0UL },
213 {IA_FrameType , FRAME_BUTTON },
214 {TAG_DONE }
217 dri = (struct DrawInfo *) GetTagData(GA_DrawInfo, NULL, msg->ops_AttrList);
218 if (!dri)
219 return NULL;
220 tags[0].ti_Data = GetTagData(GA_Width, 0, msg->ops_AttrList);
221 tags[1].ti_Data = GetTagData(GA_Height, 0, msg->ops_AttrList);
222 table = (struct HDTBPartition *)GetTagData(PTCT_PartitionTable, 0, msg->ops_AttrList);
223 flags = GetTagData(PTCT_Flags, 0, msg->ops_AttrList);
224 tags[2].ti_Data = (dri->dri_Resolution.X << 16) + dri->dri_Resolution.Y;
225 frame = (struct Image *) NewObjectA(NULL, FRAMEICLASS, tags);
226 if (!frame)
227 return NULL;
229 tags[0].ti_Tag = GA_Image;
230 tags[0].ti_Data = (IPTR) frame;
231 tags[1].ti_Tag = TAG_MORE;
232 tags[1].ti_Data = (IPTR) msg->ops_AttrList;
233 obj = (Object *) DoSuperMethodA(cl, obj, (Msg)msg);
234 if (!obj)
236 DisposeObject(frame);
237 return NULL;
239 data = INST_DATA(cl, obj);
240 data->dri = dri;
241 data->frame = frame;
242 data->table = table;
243 data->flags = flags;
244 data->active = 0;
245 data->move = FALSE;
246 data->selected = FALSE;
247 data->firstdraw = TRUE;
249 return (IPTR)obj;
252 STATIC IPTR pt_set(Class *cl, Object *obj, struct opSet *msg) {
253 IPTR retval = 0UL;
254 struct PTableData *data;
255 struct TagItem *tag;
256 struct TagItem *taglist;
257 struct RastPort *rport;
259 if (msg->MethodID != OM_NEW)
260 retval = DoSuperMethodA(cl, obj, (Msg)msg);
262 data = INST_DATA(cl, obj);
263 taglist = (struct TagItem *)msg->ops_AttrList;
264 while ((tag = NextTagItem(&taglist)))
266 switch (tag->ti_Tag)
268 case GA_Disabled:
269 retval = TRUE;
270 break;
271 case GA_DrawInfo:
272 if (msg->MethodID == OM_NEW)
273 data->dri = (struct DrawInfo *)tag->ti_Data;
274 break;
275 case PTCT_PartitionTable:
276 data->table = (struct HDTBPartition *)tag->ti_Data;
277 retval = TRUE;
278 break;
279 case PTCT_ActivePartition:
280 data->active = (struct HDTBPartition *)tag->ti_Data;
281 retval = TRUE;
282 break;
286 /* redraw if one attribute has changed something */
287 if ((retval) && (OCLASS(obj) == cl))
289 rport = ObtainGIRPort(msg->ops_GInfo);
290 if (rport)
292 DoMethod(obj, GM_RENDER, (IPTR) msg->ops_GInfo, (IPTR) rport, GREDRAW_UPDATE);
293 ReleaseGIRPort(rport);
294 retval = FALSE;
297 return retval;
300 STATIC IPTR pt_get(Class *cl, Object *obj, struct opGet *msg) {
301 struct PTableData *data=INST_DATA(cl, obj);
302 IPTR retval = 0;
304 switch (msg->opg_AttrID)
306 case PTCT_PartitionTable:
307 *msg->opg_Storage = (IPTR)data->table;
308 retval = 1;
309 break;
310 case PTCT_ActivePartition:
311 *msg->opg_Storage = (IPTR)data->active;
312 retval = 1;
313 break;
314 case PTCT_ActiveType:
315 if ((struct DosEnvec *)data->active == &data->gap)
316 *msg->opg_Storage = (IPTR)PTS_EMPTY_AREA;
317 else if (data->active == NULL)
318 *msg->opg_Storage = (IPTR)PTS_NOTHING;
319 else
320 *msg->opg_Storage = (IPTR)PTS_PARTITION;
321 retval = 1;
322 break;
324 case PTCT_Flags:
325 break;
326 default:
327 retval = DoSuperMethodA(cl, obj, (Msg)msg);
329 return retval;
332 struct DosEnvec *findSpace
334 struct HDTBPartition *table,
335 struct DosEnvec *de,
336 ULONG block
339 struct HDTBPartition *pn;
340 ULONG spc;
341 ULONG first=0;
342 ULONG last=0xFFFFFFFF;
344 /* inherit */
345 CopyMem(&table->de, de, sizeof(struct DosEnvec));
346 de->de_SizeBlock = table->dg.dg_SectorSize>>2;
347 de->de_Surfaces = table->dg.dg_Heads;
348 de->de_BlocksPerTrack = table->dg.dg_TrackSectors;
349 de->de_BufMemType = table->dg.dg_BufMemType;
351 pn = (struct HDTBPartition *)table->listnode.list.lh_Head;
352 while (pn->listnode.ln.ln_Succ != NULL)
354 ULONG start;
355 ULONG end;
357 if (pn->listnode.ln.ln_Type != LNT_Parent)
359 spc = pn->de.de_Surfaces*pn->de.de_BlocksPerTrack;
360 start = pn->de.de_LowCyl*spc;
361 end = ((pn->de.de_HighCyl+1)*spc)-1;
362 if (block<start)
364 if (start<last)
365 last=start-1;
367 else if (block>end)
369 if (end>first)
370 first = end+1;
373 pn = (struct HDTBPartition *)pn->listnode.ln.ln_Succ;
375 spc = table->dg.dg_Heads*table->dg.dg_TrackSectors;
376 if (first == 0)
377 first = table->table->reserved;
378 first /= spc;
379 last = ((last+1)/spc)-1;
380 if (last>=table->dg.dg_Cylinders)
381 last=table->dg.dg_Cylinders-1;
382 de->de_LowCyl = first;
383 de->de_HighCyl = last;
385 return de;
388 struct HDTBPartition *getActive(struct PTableData *data) {
389 struct HDTBPartition *pn;
391 pn = (struct HDTBPartition *)data->table->listnode.list.lh_Head;
392 while (pn->listnode.ln.ln_Succ != NULL)
394 ULONG start;
395 ULONG end;
397 if (pn->listnode.ln.ln_Type != LNT_Parent)
399 start = pn->de.de_LowCyl*pn->de.de_Surfaces*pn->de.de_BlocksPerTrack;
400 end = (pn->de.de_HighCyl+1)*pn->de.de_Surfaces*pn->de.de_BlocksPerTrack;
401 if ((data->block>=start) && (data->block<end))
402 return pn;
404 pn = (struct HDTBPartition *)pn->listnode.ln.ln_Succ;
406 return (struct HDTBPartition *)findSpace(data->table,&data->gap,data->block);
409 void DrawBox(struct RastPort *rport, struct DrawInfo *dri,
410 UWORD sx, UWORD sy, UWORD ex, UWORD ey, BOOL recessed) {
412 SetAPen(rport, dri->dri_Pens[recessed ? SHINEPEN : SHADOWPEN]);
413 Move(rport, ex, sy);
414 Draw(rport, ex, ey);
415 Draw(rport, sx, ey);
416 SetAPen(rport, dri->dri_Pens[recessed ? SHADOWPEN : SHINEPEN]);
417 Draw(rport, sx, sy);
418 Draw(rport, ex, sy);
421 void DrawFilledBox
423 struct RastPort *rport,
424 struct DrawInfo *dri,
425 UWORD sx, UWORD sy, UWORD ex, UWORD ey
428 RectFill(rport, sx+1, sy+1, ex-1, ey-1);
429 DrawBox(rport, dri, sx, sy, ex, ey, FALSE);
432 void DrawPartition
434 struct RastPort *rport,
435 struct PTableData *data,
436 struct Gadget *gadget,
437 struct HDTBPartition *table,
438 struct DosEnvec *pn,
439 WORD drawtype
442 ULONG start;
443 ULONG end;
444 ULONG blocks;
445 ULONG spc;
446 ULONG cyls;
447 ULONG skipcyl;
449 if (!rport) return;
451 #if 0
452 blocks =
453 (table->table->de_HighCyl+1)*
454 table->table->de_Surfaces*
455 table->table->de_BlocksPerTrack;
456 #else
457 blocks = table->dg.dg_Heads*table->dg.dg_TrackSectors;
458 skipcyl = table->table->reserved/blocks;
459 cyls = (table->dg.dg_Cylinders-1)-skipcyl;
461 #endif
462 spc = pn->de_Surfaces*pn->de_BlocksPerTrack;
463 #if 0
464 start = pn->de_LowCyl*spc*gadget->Width/blocks;
465 end = (((pn->de_HighCyl+1)*spc)-1)*gadget->Width/blocks;
466 #else
467 start = pn->de_LowCyl;
468 end = pn->de_HighCyl;
469 if (
470 (pn->de_Surfaces!=table->dg.dg_Heads) ||
471 (pn->de_BlocksPerTrack!=table->dg.dg_TrackSectors)
474 start = start*spc/blocks;
475 end = end*spc/blocks;
477 if (start!=0)
478 start -= skipcyl;
479 if (end !=0)
480 end -= skipcyl;
481 start = (start*(gadget->Width - PARTITIONBLOCK_FRAMEWIDTH)/cyls)+1;
482 #if END_FIX
483 end = ((end + 1) *(gadget->Width - PARTITIONBLOCK_FRAMEWIDTH)/cyls) + 1 - 1;
484 #else
485 end = (end*(gadget->Width - PARTITIONBLOCK_FRAMEWIDTH)/cyls);
486 #endif
487 start += gadget->LeftEdge;
488 end += gadget->LeftEdge;
489 #endif
491 PrepareRP(rport, data, drawtype);
493 if (drawtype == DPTYPE_EMPTY)
495 RectFill(rport, start, gadget->TopEdge+1+(gadget->Height/2),
496 end, gadget->TopEdge+(gadget->Height)-2);
498 else
500 DrawFilledBox
502 rport,
503 data->dri,
504 start, gadget->TopEdge+1+(gadget->Height/2),
505 end, gadget->TopEdge+(gadget->Height)-2
509 SetPattern(rport, NULL, 0);
512 ULONG getBlock(UWORD mousex, UWORD width, struct HDTBPartition *table) {
513 ULONG block;
515 if ((WORD)mousex < 0) mousex = 0;
517 block = mousex*(table->dg.dg_Cylinders-1)/width;
518 block *= table->dg.dg_Heads*table->dg.dg_TrackSectors;
519 block += table->table->reserved;
520 return block;
523 STATIC VOID notify_all(Class *cl, Object *obj, struct GadgetInfo *gi, BOOL interim, BOOL userinput) {
524 struct PTableData *data=INST_DATA(cl, obj);
525 struct opUpdate opu;
526 struct TagItem tags[]=
528 {GA_ID, G(obj)->GadgetID},
529 #ifndef __AMIGAOS__
530 {GA_UserInput, userinput},
531 #endif
532 {PTCT_ActivePartition,(IPTR)data->active},
533 {PTCT_PartitionTable, (IPTR)data->table},
534 {PTCT_PartitionMove, (IPTR)data->move},
535 {PTCT_Selected, (IPTR)data->selected},
536 {TAG_DONE}
539 opu.MethodID = OM_NOTIFY;
540 opu.opu_AttrList = tags;
541 opu.opu_GInfo = gi;
542 opu.opu_Flags = interim ? OPUF_INTERIM : 0;
543 DoMethodA(obj, (Msg)&opu);
546 STATIC IPTR pt_goactive(Class *cl, Object *obj, struct gpInput *msg) {
547 IPTR retval = GMR_MEACTIVE;
548 struct PTableData *data;
549 struct DosEnvec *de;
550 struct RastPort *rport;
551 WORD drawtype;
553 data = INST_DATA(cl, obj);
555 data->block = getBlock(msg->gpi_Mouse.X, G(obj)->Width - PARTITIONBLOCK_FRAMEWIDTH,data->table);
556 rport = ObtainGIRPort(msg->gpi_GInfo);
557 if (data->active != NULL)
559 /* draw previous active as unselected */
560 if ((struct DosEnvec *)data->active == &data->gap)
562 drawtype = DPTYPE_EMPTY;
563 de = &data->gap;
565 else
567 drawtype = DPTYPE_USED;
568 de = &data->active->de;
570 DrawPartition(rport, data, (struct Gadget *)obj, data->table, de, drawtype);
572 data->active = getActive(data);
574 if ((struct DosEnvec *)data->active == &data->gap)
576 drawtype = DPTYPE_EMPTY_SELECTED;
577 de = &data->gap;
579 else
581 drawtype = DPTYPE_USED_SELECTED;
582 de = &data->active->de;
583 if (data->flags & PTCTF_EmptySelectOnly)
584 data->active=0;
586 data->selected = TRUE;
587 notify_all(cl, obj, msg->gpi_GInfo, TRUE, TRUE);
588 data->selected = FALSE;
589 if (data->active && rport)
591 DrawPartition(rport, data, (struct Gadget *)obj, data->table, de, drawtype);
594 if (rport) ReleaseGIRPort(rport);
596 return retval;
599 STATIC IPTR pt_goinactive(Class *cl, Object *obj, struct gpInput *msg) {
600 IPTR retval = TRUE;
601 struct PTableData *data;
602 struct DosEnvec *de;
603 struct RastPort *rport;
604 WORD drawtype;
606 data = INST_DATA(cl, obj);
607 if (data->active)
609 // data->block = getBlock(msg->gpi_Mouse.X, G(obj)->Width - PARTITIONBLOCK_FRAMEWIDTH, data->table);
610 if (getActive(data) == data->active)
612 if ((rport = ObtainGIRPort(msg->gpi_GInfo)))
614 if ((struct DosEnvec *)data->active == &data->gap)
616 drawtype = DPTYPE_EMPTY_SELECTED;
617 de = &data->gap;
619 else
621 drawtype = DPTYPE_USED_SELECTED;
622 de = &data->active->de;
624 DrawPartition(rport, data, (struct Gadget *)obj, data->table, de, drawtype);
626 ReleaseGIRPort(rport);
630 return retval;
633 ULONG overflow_add(ULONG a, LONG b) {
634 ULONG result;
636 result = a + b;
637 if (a > result)
638 result = (ULONG)-1;
639 return result;
642 ULONG underflow_add(ULONG a, LONG b) {
643 ULONG result;
645 if (a<-b)
646 result = 0;
647 else
648 result = a+b;
649 return result;
652 BOOL overlap(ULONG a, ULONG b, ULONG c, ULONG d) {
654 if (a>b)
656 ULONG e;
657 e = b;
658 b = a;
659 a = e;
661 return
663 (((a >= c) && (a < d)) || ((b >= c) && (b < d))) ||
664 (((c >= a) && (c < b)) || ((d >= a) && (d < b)))
668 LONG getBetterDiff
670 struct HDTBPartition *table,
671 struct HDTBPartition *current,
672 LONG diff
675 struct HDTBPartition *pn;
676 ULONG spc;
677 ULONG oldblock;
678 ULONG block;
679 ULONG other;
680 ULONG start;
681 ULONG end;
682 ULONG size;
684 spc = current->de.de_Surfaces*current->de.de_BlocksPerTrack;
685 start = current->de.de_LowCyl*spc;
686 end = ((current->de.de_HighCyl+1)*spc)-1;
687 size = end-start;
688 if (diff>0)
690 oldblock = end;
691 block = overflow_add(end, diff);
692 other = block-size;
694 else
696 oldblock = start;
697 block = underflow_add(start, diff);
698 other = block+size; /* use correct partition size */
700 if (block<table->table->reserved)
702 diff = table->table->reserved-oldblock;
703 if (diff == 0)
704 return 0;
705 return getBetterDiff(table, current, diff);
707 spc = table->dg.dg_Heads*table->dg.dg_TrackSectors;
708 if (block>=((table->dg.dg_Cylinders)*spc))
710 diff = (((table->dg.dg_Cylinders)*spc)-1)-oldblock;
711 if (diff == 0)
712 return 0;
713 return getBetterDiff(table, current, diff);
715 pn = (struct HDTBPartition *)table->listnode.list.lh_Head;
716 while (pn->listnode.ln.ln_Succ)
718 /* dont't check currently processed partition */
719 if (current != pn)
721 spc = pn->de.de_Surfaces*pn->de.de_BlocksPerTrack;
722 if (
723 overlap
725 block, other,
726 pn->de.de_LowCyl*spc, ((pn->de.de_HighCyl+1)*spc)-1
730 if (diff>0)
731 diff = ((pn->de.de_LowCyl*spc)-1)-oldblock;
732 else
733 diff = ((pn->de.de_HighCyl+1)*spc)-oldblock;
734 return getBetterDiff(table, current, diff);
737 pn = (struct HDTBPartition *)pn->listnode.ln.ln_Succ;
739 return diff;
742 STATIC IPTR pt_handleinput(Class *cl, Object *obj, struct gpInput *msg) {
743 IPTR retval = GMR_MEACTIVE;
744 struct InputEvent *ie;
745 struct PTableData *data;
746 struct RastPort *rport;
748 data = INST_DATA(cl, obj);
749 ie = msg->gpi_IEvent;
750 if (ie->ie_Class == IECLASS_RAWMOUSE)
752 switch (ie->ie_Code)
754 case IECODE_NOBUTTON:
755 if (
756 ((struct DosEnvec *)data->active != &data->gap) &&
757 (!(data->flags & PTCTF_NoPartitionMove))
760 ULONG block;
761 LONG diff;
762 ULONG start;
763 ULONG end;
764 ULONG spc;
765 ULONG tocheck;
767 block = getBlock(msg->gpi_Mouse.X, G(obj)->Width - PARTITIONBLOCK_FRAMEWIDTH, data->table);
768 diff = block-data->block;
769 if (diff)
771 diff = getBetterDiff(data->table, data->active, diff);
772 if (diff)
774 spc=data->active->de.de_Surfaces*data->active->de.de_BlocksPerTrack;
775 start = data->active->de.de_LowCyl*spc;
776 start += diff;
777 end = ((data->active->de.de_HighCyl+1)*spc)-1;
778 end += diff;
779 tocheck = (diff>0) ? end : start;
780 #ifdef DEBUG
781 #if DEBUG>0
782 if (validValue(data->table, data->active, tocheck))
784 #endif
785 #endif
786 rport = ObtainGIRPort(msg->gpi_GInfo);
788 start = start/spc;
789 end = ((end+1)/spc)-1;
791 DrawPartition
793 rport,
794 data,
795 (struct Gadget *)obj,
796 data->table,
797 &data->active->de,
798 DPTYPE_EMPTY
800 data->active->de.de_LowCyl=start;
801 data->active->de.de_HighCyl=end;
803 DrawPartition
805 rport,
806 data,
807 (struct Gadget *)obj,
808 data->table,
809 &data->active->de,
810 DPTYPE_USED_SELECTED
813 data->block = block;
814 data->move = TRUE;
815 notify_all(cl, obj, msg->gpi_GInfo, TRUE, TRUE);
817 if (rport) ReleaseGIRPort(rport);
818 #ifdef DEBUG
819 #if DEBUG>0
821 else
822 kprintf("!!!!!!!!!!!!!!!!!!!not valid\n");
823 #endif
824 #endif
828 break;
829 case SELECTUP:
830 data->move = FALSE;
831 notify_all(cl, obj, msg->gpi_GInfo, FALSE, TRUE);
832 data->selected = FALSE;
833 retval = GMR_NOREUSE|GMR_VERIFY;
834 break;
837 return retval;
840 void DrawLegend(struct RastPort *rport, struct DrawInfo *dri, LONG sx, LONG sy, LONG ex, LONG ey, char *text) {
841 RectFill(rport, sx+1, sy+1, ex-1, ey-1);
842 DrawBox(rport, dri, sx, sy, ex, ey, FALSE);
844 SetAPen(rport, 1);
845 SetDrMd(rport, JAM1);
847 Move(rport, sx, ey+rport->TxHeight+1);
848 Text(rport, text, strlen(text));
851 STATIC IPTR pt_render(Class *cl, Object *obj, struct gpRender *msg) {
852 struct PTableData *data = INST_DATA(cl, obj);
853 struct HDTBPartition *pn;
854 IPTR retval = 0;
856 retval = DoSuperMethodA(cl, obj, (Msg)msg);
858 if (data->firstdraw)
860 struct TagItem obp_tags[] =
862 {OBP_Precision, PRECISION_EXACT },
863 {OBP_FailIfBad, TRUE },
864 {TAG_DONE }
867 WORD i;
869 data->firstdraw = FALSE;
871 data->cm = msg->gpr_GInfo->gi_Screen->ViewPort.ColorMap;
873 for(i = 0; i < NUM_PENS; i++)
875 data->pens[i] = ObtainBestPenA(data->cm,
876 rgbtable[i * 3],
877 rgbtable[i * 3 + 1],
878 rgbtable[i * 3 + 2],
879 obp_tags);
880 if (data->pens[i] == -1)
882 while(--i >= 0)
884 ReleasePen(data->cm, data->pens[i]);
886 break;
890 if (i == NUM_PENS)
892 data->multicolor = TRUE;
893 data->pensallocated = TRUE;
898 EraseRect
900 msg->gpr_RPort,
901 G(obj)->LeftEdge,
902 G(obj)->TopEdge,
903 G(obj)->LeftEdge+G(obj)->Width - 1,
904 G(obj)->TopEdge+(G(obj)->Height - 1)
907 PrepareRP(msg->gpr_RPort, data, DPTYPE_EMPTY);
908 DrawLegend
910 msg->gpr_RPort,
911 data->dri,
912 G(obj)->LeftEdge,
913 G(obj)->TopEdge,
914 G(obj)->LeftEdge+(G(obj)->Width/5),
915 G(obj)->TopEdge+(G(obj)->Height/2)-(G(obj)->Height/4),
916 "Unselected Empty"
919 PrepareRP(msg->gpr_RPort, data, DPTYPE_EMPTY_SELECTED);
920 DrawLegend
922 msg->gpr_RPort,
923 data->dri,
924 G(obj)->LeftEdge+(G(obj)->Width/5)+(G(obj)->Width/15),
925 G(obj)->TopEdge,
926 G(obj)->LeftEdge+(G(obj)->Width/5*2)+(G(obj)->Width/15),
927 G(obj)->TopEdge+(G(obj)->Height/2)-(G(obj)->Height/4),
928 "Selected Empty"
931 PrepareRP(msg->gpr_RPort, data, DPTYPE_USED);
932 DrawLegend
934 msg->gpr_RPort,
935 data->dri,
936 G(obj)->LeftEdge+(G(obj)->Width/5*2)+(G(obj)->Width/15*2),
937 G(obj)->TopEdge,
938 G(obj)->LeftEdge+(G(obj)->Width/5*3)+(G(obj)->Width/15*2),
939 G(obj)->TopEdge+(G(obj)->Height/2)-(G(obj)->Height/4),
940 "Unselected Used"
944 PrepareRP(msg->gpr_RPort, data, DPTYPE_USED_SELECTED);
945 DrawLegend
947 msg->gpr_RPort,
948 data->dri,
949 G(obj)->LeftEdge+(G(obj)->Width/5*3)+(G(obj)->Width/15*3),
950 G(obj)->TopEdge,
951 G(obj)->LeftEdge+(G(obj)->Width/5*4)+(G(obj)->Width/15*3),
952 G(obj)->TopEdge+(G(obj)->Height/2)-(G(obj)->Height/4),
953 "Selected Used"
956 PrepareRP(msg->gpr_RPort, data, DPTYPE_EMPTY);
958 RectFill
960 msg->gpr_RPort,
961 G(obj)->LeftEdge,
962 G(obj)->TopEdge+(G(obj)->Height/2),
963 G(obj)->LeftEdge+G(obj)->Width - 1,
964 G(obj)->TopEdge+(G(obj)->Height - 1)
966 SetPattern(msg->gpr_RPort, NULL, 0);
968 DrawBox
970 msg->gpr_RPort,
971 data->dri,
972 G(obj)->LeftEdge,
973 G(obj)->TopEdge+(G(obj)->Height/2),
974 G(obj)->LeftEdge+G(obj)->Width - 1,
975 G(obj)->TopEdge+(G(obj)->Height - 1),
976 TRUE
979 if (data->table)
981 SetPattern(msg->gpr_RPort, &pattern, 2);
982 pn = (struct HDTBPartition *)data->table->listnode.list.lh_Head;
983 while (pn->listnode.ln.ln_Succ)
985 if (pn->listnode.ln.ln_Type == LNT_Partition)
987 DrawPartition
989 msg->gpr_RPort,
990 data,
991 (struct Gadget *)obj,
992 data->table,
993 &pn->de,
994 (data->active == pn) ? DPTYPE_USED_SELECTED : DPTYPE_USED
997 pn = (struct HDTBPartition *)pn->listnode.ln.ln_Succ;
999 if ((struct DosEnvec *)data->active == &data->gap)
1001 DrawPartition
1003 msg->gpr_RPort,
1004 data,
1005 (struct Gadget *)obj,
1006 data->table,
1007 &data->gap,
1008 DPTYPE_EMPTY_SELECTED
1011 SetPattern(msg->gpr_RPort, 0, 0);
1013 return retval;
1016 STATIC IPTR pt_dispose(Class *cl, Object *obj, Msg msg) {
1017 struct PTableData *data = INST_DATA(cl, obj);
1019 if (data->pensallocated)
1021 WORD i = 0;
1023 for(i = 0; i < NUM_PENS; i++)
1025 ReleasePen(data->cm, data->pens[i]);
1029 return DoSuperMethodA(cl, obj, msg);
1032 STATIC IPTR pt_hittest(Class *cl, Object *obj, struct gpHitTest *msg) {
1034 return GMR_GADGETHIT;
1037 AROS_UFH3S(IPTR, dispatch_ptclass,
1038 AROS_UFHA(Class *, cl, A0),
1039 AROS_UFHA(Object *, obj, A2),
1040 AROS_UFHA(Msg, msg, A1)
1043 AROS_USERFUNC_INIT
1044 IPTR retval;
1045 switch (msg->MethodID)
1047 case OM_NEW:
1048 retval = pt_new(cl, obj, (struct opSet *)msg);
1049 break;
1050 case OM_DISPOSE:
1051 retval = pt_dispose(cl, obj, msg);
1052 break;
1053 case OM_SET:
1054 case OM_UPDATE:
1055 retval = pt_set(cl, obj, (struct opSet *)msg);
1056 break;
1057 case OM_GET:
1058 retval = pt_get(cl, obj, (struct opGet *)msg);
1059 break;
1060 case GM_HITTEST:
1061 retval = pt_hittest(cl, obj, (struct gpHitTest *)msg);
1062 break;
1063 case GM_RENDER:
1064 retval = pt_render(cl, obj, (struct gpRender *)msg);
1065 break;
1066 case GM_GOACTIVE:
1067 retval = pt_goactive(cl, obj, (struct gpInput *)msg);
1068 break;
1069 case GM_GOINACTIVE:
1070 retval = pt_goinactive(cl, obj, (struct gpInput *)msg);
1071 break;
1072 case GM_HANDLEINPUT:
1073 retval = pt_handleinput(cl, obj, (struct gpInput *)msg);
1074 break;
1075 default:
1076 kprintf("default %ld\n", msg->MethodID);
1077 retval = DoSuperMethodA(cl, obj, msg);
1078 break;
1080 return retval;
1082 AROS_USERFUNC_EXIT
1085 Class *makePTClass(void) {
1087 if (!ptcl)
1089 ptcl = MakeClass(NULL, GADGETCLASS, NULL, sizeof(struct PTableData), 0);
1090 if (ptcl)
1092 ptcl->cl_Dispatcher.h_Entry = AROS_ASMSYMNAME(dispatch_ptclass);
1093 ptcl->cl_Dispatcher.h_SubEntry = NULL;
1094 ptcl->cl_UserData = NULL;
1097 return ptcl;