2 Copyright © 2017, The AROS Development Team. All rights reserved.
7 #include <aros/debug.h>
9 #define MUIMASTER_YES_INLINE_STDARG
11 #include <exec/types.h>
12 #include <utility/date.h>
14 #include <aros/asmcall.h>
16 #include <proto/alib.h>
17 #include <proto/muimaster.h>
18 #include <proto/graphics.h>
19 #include <proto/intuition.h>
20 #include <proto/utility.h>
21 #include <proto/timer.h>
28 #include "graph_intern.h"
30 IPTR
Graph__UpdateSourceArray(struct Graph_DATA
*data
, IPTR count
)
32 struct Graph_SourceDATA
*newSourceArray
= data
->graph_Sources
;
34 D(bug("[Graph] %s(%d)\n", __func__
, count
);)
36 if (data
->graph_SourceCount
!= count
)
40 if (count
> data
->graph_SourceCount
)
41 copycnt
= data
->graph_SourceCount
;
45 newSourceArray
= AllocMem(sizeof(struct Graph_SourceDATA
) * count
, MEMF_ANY
);
49 if (data
->graph_Sources
)
51 CopyMem(data
->graph_Sources
, newSourceArray
, sizeof(struct Graph_SourceDATA
) * copycnt
);
52 FreeMem(data
->graph_Sources
, sizeof(struct Graph_SourceDATA
) * data
->graph_SourceCount
);
55 if (count
> data
->graph_SourceCount
)
57 D(bug("[Graph] %s: initializing new source\n", __func__
);)
58 memset(&newSourceArray
[count
- 1], 0, sizeof(struct Graph_SourceDATA
));
59 newSourceArray
[count
- 1].gs_PlotPen
= -1;
60 newSourceArray
[count
- 1].gs_PlotFillPen
= -1;
61 if (data
->graph_EntryCount
> 0)
62 newSourceArray
[count
- 1].gs_Entries
= AllocMem(sizeof(IPTR
) * data
->graph_EntryCount
, MEMF_CLEAR
|MEMF_ANY
);
65 data
->graph_Sources
= newSourceArray
;
66 data
->graph_SourceCount
= count
;
70 return (IPTR
)newSourceArray
;
73 IPTR
Graph__UpdateSourceEntries(struct Graph_DATA
*data
, IPTR sourceNo
, IPTR count
)
75 struct Graph_SourceDATA
*dataSource
= NULL
;
77 D(bug("[Graph] %s(%d:%d)\n", __func__
, sourceNo
, count
);)
79 if (count
> data
->graph_EntryCount
)
83 dataSource
= &data
->graph_Sources
[sourceNo
];
85 newEntries
= AllocMem(sizeof(IPTR
) * count
, MEMF_ANY
);
88 if (dataSource
->gs_Entries
)
90 CopyMem(dataSource
->gs_Entries
, newEntries
, sizeof(IPTR
) * data
->graph_EntryCount
);
91 FreeMem(dataSource
->gs_Entries
, sizeof(IPTR
) * data
->graph_EntryCount
);
93 dataSource
->gs_Entries
= newEntries
;
97 return (IPTR
)dataSource
;
100 void Graph__FreeInfoText(Class
*cl
, Object
*obj
)
102 struct Graph_DATA
*data
= INST_DATA(cl
, obj
);
103 struct Node
*infoLine
, *tmp
;
105 D(bug("[Graph] %s()\n", __func__
);)
107 ForeachNodeSafe(&data
->graph_InfoText
, infoLine
, tmp
)
109 D(bug("[Graph] %s: Deleting old infotext line @ 0x%p - '%s'\n", __func__
, infoLine
, infoLine
->ln_Name
);)
113 data
->graph_ITHeight
= 0;
116 IPTR
Graph__ParseInfoText(Class
*cl
, Object
*obj
, char *infoTxt
)
118 struct Graph_DATA
*data
= INST_DATA(cl
, obj
);
120 int i
, srcLen
, start
= 0;
121 struct Node
*infoLine
;
123 D(bug("[Graph] %s(0x%p)\n", __func__
, infoTxt
);)
125 Graph__FreeInfoText(cl
, obj
);
129 srcLen
= strlen(infoTxt
);
131 for (i
= 0; i
< (srcLen
+ 1); i
++)
133 if (((i
- start
) > 0) && (infoTxt
[i
] == '\n') || (infoTxt
[i
] == '\0'))
135 infoLine
= (struct Node
*)AllocVec(sizeof(struct Node
) + 1 + (i
- start
), MEMF_ANY
|MEMF_CLEAR
);
136 infoLine
->ln_Name
= (char *)&infoLine
[1];
138 CopyMem(&infoTxt
[start
], infoLine
->ln_Name
, (i
- start
));
140 D(bug("[Graph] %s: New infotext line @ 0x%p - '%s'\n", __func__
, infoLine
, infoLine
->ln_Name
);)
141 AddTail(&data
->graph_InfoText
, infoLine
);
143 data
->graph_ITHeight
+= 1;
148 D(bug("[Graph] %s: InfoText> %d lines\n", __func__
, data
->graph_ITHeight
);)
149 return data
->graph_ITHeight
;
152 IPTR
Graph__SumValues(IPTR
*start
, int count
)
156 for (i
= 0; i
< count
; i
++)
165 /*** Methods ****************************************************************/
166 IPTR
Graph__OM_NEW(Class
*cl
, Object
*obj
, struct opSet
*msg
)
168 struct Graph_DATA
*data
;
170 D(bug("[Graph] %s()\n", __func__
);)
172 obj
= (Object
*) DoSuperNewTags
181 TAG_MORE
, (IPTR
) msg
->ops_AttrList
186 data
= INST_DATA(cl
, obj
);
188 NEWLIST(&data
->graph_InfoText
);
189 data
->graph_ITHeight
= 0;
191 data
->graph_RastPort
= NULL
;
193 data
->graph_Flags
= (GRAPHF_DRAWAXIS
|GRAPHF_DRAWSEGS
);
194 data
->graph_BackPen
= -1;
195 data
->graph_AxisPen
= -1;
196 data
->graph_SegmentPen
= -1;
198 /* We always have atleast one source .. */
199 Graph__UpdateSourceArray(data
, 1);
201 data
->ihn
.ihn_Flags
= MUIIHNF_TIMER
;
202 data
->ihn
.ihn_Method
= MUIM_Graph_Timer
;
203 data
->ihn
.ihn_Object
= obj
;
204 data
->ihn
.ihn_Millis
= 1000;
206 data
->graph_PeriodCeiling
= data
->ihn
.ihn_Millis
* 10;
207 data
->graph_PeriodStepping
= data
->ihn
.ihn_Millis
;
209 data
->graph_ValCeiling
= 100;
210 data
->graph_ValStepping
= 10;
212 SetAttrsA(obj
, msg
->ops_AttrList
);
218 IPTR
Graph__OM_DISPOSE(Class
*cl
, Object
*obj
, Msg msg
)
220 struct Graph_DATA
*data
= INST_DATA(cl
, obj
);
223 D(bug("[Graph] %s()\n", __func__
);)
225 if (data
->graph_SourceCount
> 0)
227 if (data
->graph_EntryCount
> 0)
229 for (i
= 0; i
< data
->graph_SourceCount
; i
++)
231 FreeMem(data
->graph_Sources
[i
].gs_Entries
, sizeof(IPTR
) * data
->graph_EntryCount
);
234 FreeMem(data
->graph_Sources
, sizeof(struct Graph_SourceDATA
) * data
->graph_SourceCount
);
237 Graph__FreeInfoText(cl
, obj
);
239 return DoSuperMethodA(cl
, obj
, msg
);
243 IPTR
Graph__OM_SET(Class
*cl
, Object
*obj
, struct opSet
*msg
)
245 struct Graph_DATA
*data
= INST_DATA(cl
, obj
);
246 struct TagItem
*tags
= msg
->ops_AttrList
;
250 D(bug("[Graph] %s()\n", __func__
);)
252 while ((tag
= NextTagItem(&tags
)) != NULL
)
256 /* Aggreagte mode plots the sum of source entries/no of sources */
257 case MUIA_Graph_Aggregate
:
258 data
->graph_Flags
&= ~GRAPHF_AGGR
;
260 data
->graph_Flags
|= GRAPHF_AGGR
;
263 /* Set the info text to display */
264 case MUIA_Graph_InfoText
:
265 Graph__ParseInfoText(cl
, obj
, (char *)tag
->ti_Data
);
269 /* Set the input value ceiling and stepping */
270 case MUIA_Graph_ValueCeiling
:
271 data
->graph_ValCeiling
= tag
->ti_Data
;
274 case MUIA_Graph_ValueStep
:
275 data
->graph_ValStepping
= tag
->ti_Data
;
278 /* Set the period ceiling and stepping */
279 case MUIA_Graph_PeriodCeiling
:
280 data
->graph_PeriodCeiling
= tag
->ti_Data
;
283 case MUIA_Graph_PeriodStep
:
284 data
->graph_PeriodStepping
= tag
->ti_Data
;
287 /* Set or turn off periodic update mode */
288 case MUIA_Graph_PeriodInterval
:
291 data
->graph_Flags
|= GRAPHF_PERIODIC
;
292 data
->ihn
.ihn_Millis
= tag
->ti_Data
;
293 SET(obj
, MUIA_Graph_EntryCount
, (data
->graph_PeriodCeiling
/ data
->ihn
.ihn_Millis
));
294 if ((data
->graph_Flags
& GRAPHF_SETUP
) && !(data
->graph_Flags
& GRAPHF_HANDLER
))
296 data
->graph_Flags
|= GRAPHF_HANDLER
;
297 DoMethod(_app(obj
), MUIM_Application_AddInputHandler
, (IPTR
) &data
->ihn
);
302 data
->graph_Flags
&= ~GRAPHF_PERIODIC
;
303 if ((data
->graph_Flags
& GRAPHF_SETUP
) && (data
->graph_Flags
& GRAPHF_HANDLER
))
305 DoMethod(_app(obj
), MUIM_Application_RemInputHandler
, (IPTR
) &data
->ihn
);
306 data
->graph_Flags
&= ~GRAPHF_HANDLER
;
311 /* Set or turn off Fixed entry count mode */
312 case MUIA_Graph_EntryCount
:
316 for (i
= 0; i
< data
->graph_SourceCount
; i
++)
318 Graph__UpdateSourceEntries(data
, i
, tag
->ti_Data
);
320 data
->graph_EntryCount
= tag
->ti_Data
;
321 data
->graph_Flags
|= GRAPHF_FIXEDLEN
;
325 data
->graph_Flags
&= ~GRAPHF_FIXEDLEN
;
332 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
334 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
338 IPTR
Graph__OM_GET(Class
*cl
, Object
*obj
, struct opGet
*msg
)
340 struct Graph_DATA
*data
= INST_DATA(cl
, obj
);
343 D(bug("[Graph] %s()\n", __func__
);)
345 switch(msg
->opg_AttrID
)
347 case MUIA_Graph_ValueCeiling
:
348 *(msg
->opg_Storage
) = data
->graph_ValCeiling
;
351 case MUIA_Graph_EntryCount
:
352 *(msg
->opg_Storage
) = data
->graph_EntryCount
;
355 case MUIA_Graph_PeriodInterval
:
356 *(msg
->opg_Storage
) = data
->ihn
.ihn_Millis
;
360 retval
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
367 IPTR
Graph__MUIM_Setup(Class
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
369 struct Graph_DATA
*data
= INST_DATA(cl
, obj
);
372 D(bug("[Graph] %s()\n", __func__
);)
374 if (!DoSuperMethodA(cl
, obj
, (Msg
)msg
)) return FALSE
;
376 if ((data
->graph_Flags
& GRAPHF_PERIODIC
) && !(data
->graph_Flags
& GRAPHF_HANDLER
))
378 data
->graph_Flags
|= GRAPHF_HANDLER
;
379 DoMethod(_app(obj
), MUIM_Application_AddInputHandler
, (IPTR
) &data
->ihn
);
382 data
->graph_BackPen
= ObtainBestPen(_screen(obj
)->ViewPort
.ColorMap
,
386 OBP_Precision
, PRECISION_GUI
,
387 OBP_FailIfBad
, FALSE
,
390 data
->graph_AxisPen
= ObtainBestPen(_screen(obj
)->ViewPort
.ColorMap
,
394 OBP_Precision
, PRECISION_GUI
,
395 OBP_FailIfBad
, FALSE
,
398 data
->graph_SegmentPen
= ObtainBestPen(_screen(obj
)->ViewPort
.ColorMap
,
402 OBP_Precision
, PRECISION_GUI
,
403 OBP_FailIfBad
, FALSE
,
406 for (i
= 0; i
< data
->graph_SourceCount
; i
++)
409 if (((penSrc
= (ULONG
*)data
->graph_Sources
[i
].gs_PlotFillPenSrc
) != NULL
) &&
410 (data
->graph_Sources
[i
].gs_PlotFillPenSrc
!= data
->graph_Sources
[i
].gs_PlotPenSrc
))
411 data
->graph_Sources
[i
].gs_PlotFillPen
= ObtainBestPen(_screen(obj
)->ViewPort
.ColorMap
,
415 OBP_Precision
, PRECISION_GUI
,
416 OBP_FailIfBad
, FALSE
,
419 if ((penSrc
= (ULONG
*)data
->graph_Sources
[i
].gs_PlotPenSrc
) != NULL
)
420 data
->graph_Sources
[i
].gs_PlotPen
= ObtainBestPen(_screen(obj
)->ViewPort
.ColorMap
,
424 OBP_Precision
, PRECISION_GUI
,
425 OBP_FailIfBad
, FALSE
,
429 data
->graph_Flags
|= GRAPHF_SETUP
;
435 IPTR
Graph__MUIM_Cleanup(Class
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
)
437 struct Graph_DATA
*data
= INST_DATA(cl
, obj
);
440 D(bug("[Graph] %s()\n", __func__
);)
442 data
->graph_Flags
&= ~GRAPHF_SETUP
;
444 if (data
->graph_SegmentPen
!= -1)
446 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
, data
->graph_SegmentPen
);
447 data
->graph_SegmentPen
= -1;
450 if (data
->graph_AxisPen
!= -1)
452 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
, data
->graph_AxisPen
);
453 data
->graph_AxisPen
= -1;
456 if (data
->graph_BackPen
!= -1)
458 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
, data
->graph_BackPen
);
459 data
->graph_BackPen
= -1;
462 for (i
= 0; i
< data
->graph_SourceCount
; i
++)
464 if ((data
->graph_Sources
[i
].gs_PlotFillPen
!= -1) &&
465 (data
->graph_Sources
[i
].gs_PlotFillPen
!= data
->graph_Sources
[i
].gs_PlotPen
))
466 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
, data
->graph_Sources
[i
].gs_PlotFillPen
);
467 if (data
->graph_Sources
[i
].gs_PlotPen
!= -1)
468 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
, data
->graph_Sources
[i
].gs_PlotPen
);
471 if ((data
->graph_Flags
& GRAPHF_PERIODIC
) && (data
->graph_Flags
& GRAPHF_HANDLER
))
473 DoMethod(_app(obj
), MUIM_Application_RemInputHandler
, (IPTR
) &data
->ihn
);
474 data
->graph_Flags
&= ~GRAPHF_HANDLER
;
477 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
481 IPTR
Graph__MUIM_AskMinMax(Class
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
483 struct Graph_DATA
*data
= INST_DATA(cl
, obj
);
485 D(bug("[Graph] %s()\n", __func__
);)
487 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
489 msg
->MinMaxInfo
->MinWidth
+= (data
->graph_PeriodCeiling
/ data
->graph_PeriodStepping
) * 2;
490 msg
->MinMaxInfo
->MinHeight
+= (data
->graph_ValCeiling
/ data
->graph_ValStepping
) * 2;
491 msg
->MinMaxInfo
->DefWidth
+= (data
->graph_PeriodCeiling
/ data
->graph_PeriodStepping
) * 10;
492 msg
->MinMaxInfo
->DefHeight
+= (data
->graph_ValCeiling
/ data
->graph_ValStepping
) * 10;
493 msg
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
494 msg
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
499 IPTR
Graph__MUIM_Draw(Class
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
501 struct Graph_DATA
*data
= INST_DATA(cl
, obj
);
502 struct Graph_SourceDATA
*sourceData
;
503 struct Region
*region
;
504 struct Node
*infoLine
;
505 struct RastPort
*renderPort
;
506 struct Rectangle rect
;
508 UWORD pos
, span
= 1, offset
= 0, src
, objHeight
, objWidth
;
510 D(bug("[Graph] %s()\n", __func__
);)
512 rect
.MinX
= _left(obj
);
513 rect
.MinY
= _top(obj
);
514 rect
.MaxX
= _right(obj
);
515 rect
.MaxY
= _bottom(obj
);
517 region
= NewRegion();
520 OrRectRegion(region
, &rect
);
522 clip
= MUI_AddClipRegion(muiRenderInfo(obj
), region
);
525 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
527 /* Render our graph.. */
528 if ((msg
->flags
& (MADF_DRAWOBJECT
| MADF_DRAWUPDATE
)))
530 if (data
->graph_RastPort
)
532 renderPort
= data
->graph_RastPort
;
535 rect
.MaxX
= _right(obj
) - _left(obj
);
536 rect
.MaxY
= _bottom(obj
) - _top(obj
);
539 renderPort
= _rp(obj
);
541 objHeight
= rect
.MaxY
- rect
.MinY
+ 1;
542 objWidth
= rect
.MaxX
- rect
.MinX
+ 1;
544 data
->graph_PeriodSize
= ((float)objWidth
/ data
->graph_PeriodCeiling
) * data
->ihn
.ihn_Millis
;
546 if (data
->graph_Flags
& GRAPHF_PERIODIC
)
547 offset
= data
->graph_Tick
/ data
->ihn
.ihn_Millis
;
550 bug("[Graph] %s: dimensions %d,%d\n", __func__
, objWidth
, objHeight
);
551 bug("[Graph] %s: period size %d, span %d\n", __func__
, (int)data
->graph_PeriodSize
, span
);
552 bug("[Graph] %s: offset %d\n", __func__
, offset
);
555 // First fill the background ..
556 SetAPen(renderPort
, data
->graph_BackPen
);
557 RectFill(renderPort
, rect
.MinX
, rect
.MinY
, rect
.MaxX
, rect
.MaxY
);
559 if (data
->graph_Flags
& GRAPHF_DRAWSEGS
)
561 // Draw the segment divisions..
562 SetAPen(renderPort
, data
->graph_SegmentPen
);
563 data
->graph_SegmentSize
= (objWidth
* data
->graph_PeriodStepping
) / data
->graph_PeriodCeiling
;
564 if (data
->graph_SegmentSize
< 2.0)
565 data
->graph_SegmentSize
= 2.0;
566 for (pos
= 0; pos
<= ((data
->graph_PeriodCeiling
/ data
->graph_PeriodStepping
) + 1); pos
++)
568 Move(renderPort
, rect
.MinX
+ (pos
* data
->graph_SegmentSize
) - (offset
* data
->graph_PeriodSize
), rect
.MinY
);
569 Draw(renderPort
, rect
.MinX
+ (pos
* data
->graph_SegmentSize
) - (offset
* data
->graph_PeriodSize
), rect
.MaxY
);
571 data
->graph_SegmentSize
= (objHeight
* data
->graph_ValStepping
) / data
->graph_ValCeiling
;
572 if (data
->graph_SegmentSize
< 2.0)
573 data
->graph_SegmentSize
= 2.0;
574 for (pos
= rect
.MaxY
; pos
>= rect
.MinY
; pos
-= data
->graph_SegmentSize
)
576 Move(renderPort
, rect
.MinX
, pos
);
577 Draw(renderPort
, rect
.MaxX
, pos
);
581 if (data
->graph_Flags
& GRAPHF_DRAWAXIS
)
584 SetAPen(renderPort
, data
->graph_AxisPen
);
585 Move(renderPort
, rect
.MinX
, rect
.MinY
);
586 Draw(renderPort
, rect
.MaxX
, rect
.MinY
);
587 Draw(renderPort
, rect
.MaxX
, rect
.MaxY
);
588 Draw(renderPort
, rect
.MinX
, rect
.MaxY
);
589 Draw(renderPort
, rect
.MinX
, rect
.MinY
);
592 // Plot the entries..
593 if (data
->graph_Sources
)
595 for (src
= 0; src
< data
->graph_SourceCount
; src
++)
600 sourceData
= &data
->graph_Sources
[src
];
602 if ((start
= data
->graph_EntryPtr
- (objWidth
/ data
->graph_PeriodSize
)) < 0)
605 ypos
= (objHeight
* Graph__SumValues(&sourceData
->gs_Entries
[start
], span
))/ data
->graph_ValCeiling
;
608 if (data
->graph_Flags
& GRAPHF_PERIODIC
)
609 xpos
= rect
.MaxX
- (data
->graph_EntryPtr
* data
->graph_PeriodSize
);
611 xpos
= rect
.MinX
- (offset
* data
->graph_PeriodSize
);
613 SetAPen(renderPort
, data
->graph_Sources
[src
].gs_PlotPen
);
616 WritePixel(renderPort
, xpos
, rect
.MaxY
- ypos
);
618 Move(renderPort
, xpos
, rect
.MaxY
- ypos
);
620 for (pos
= start
; pos
< data
->graph_EntryPtr
; pos
+= span
)
622 ypos
= (objHeight
* Graph__SumValues(&sourceData
->gs_Entries
[pos
], span
))/ data
->graph_ValCeiling
;
625 xpos
+ (pos
* data
->graph_PeriodSize
),
632 pos
= ((rect
.MinY
+ rect
.MaxY
) /2) - ((_font(obj
)->tf_YSize
* data
->graph_ITHeight
) /2) + _font(obj
)->tf_Baseline
;
634 if (!IsListEmpty(&data
->graph_InfoText
))
635 SetFont(renderPort
, _font(obj
));
637 ForeachNode(&data
->graph_InfoText
, infoLine
)
639 UWORD txtLen
= strlen(infoLine
->ln_Name
);
640 UWORD textWidth
= TextLength(renderPort
, infoLine
->ln_Name
, txtLen
);
642 D(bug("[Graph] %s: pos = %d, strlen = %d, wid = %d\n", __func__
, pos
, txtLen
, textWidth
);)
646 SetAPen(renderPort
, _pens(obj
)[MPEN_TEXT
]);
647 Move(renderPort
, ((rect
.MinX
+ rect
.MaxX
) /2) - (textWidth
/ 2), pos
);
648 Text(renderPort
, (CONST_STRPTR
)infoLine
->ln_Name
, txtLen
);
649 pos
+= _font(obj
)->tf_YSize
;
652 if (renderPort
!= _rp(obj
))
661 _right(obj
) - _left(obj
) + 1,
662 _bottom(obj
) - _top(obj
) + 1,
668 MUI_RemoveClipRegion(muiRenderInfo(obj
), clip
);
671 D(bug("[Graph] %s: done\n", __func__
);)
676 IPTR
Graph__MUIM_Graph_GetSourceHandle(Class
*cl
, Object
*obj
, struct MUIP_Graph_GetSourceHandle
*msg
)
678 struct Graph_DATA
*data
;
681 D(bug("[Graph] %s(%d)\n", __func__
, msg
->SourceNo
);)
683 data
= INST_DATA(cl
, obj
);
684 if (msg
->SourceNo
>= data
->graph_SourceCount
)
685 Graph__UpdateSourceArray(data
, (msg
->SourceNo
+ 1));
687 retVal
= (IPTR
)&data
->graph_Sources
[msg
->SourceNo
];
692 IPTR
Graph__MUIM_Graph_SetSourceAttrib(Class
*cl
, Object
*obj
, struct MUIP_Graph_SetSourceAttrib
*msg
)
694 struct Graph_SourceDATA
*dataSource
= (struct Graph_SourceDATA
*)msg
->SourceHandle
;
696 D(bug("[Graph] %s()\n", __func__
);)
700 case MUIV_Graph_Source_ReadHook
:
701 dataSource
->gs_ReadHook
= (struct Hook
*)msg
->AttribVal
;
703 case MUIV_Graph_Source_PenSrc
:
704 dataSource
->gs_PlotPenSrc
= msg
->AttribVal
;
706 case MUIV_Graph_Source_Pen
:
707 if (dataSource
->gs_PlotPen
!= -1)
708 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
, dataSource
->gs_PlotPen
);
709 dataSource
->gs_PlotPen
= (WORD
)msg
->AttribVal
;
711 case MUIV_Graph_Source_FillPenSrc
:
712 dataSource
->gs_PlotPen
= msg
->AttribVal
;
714 case MUIV_Graph_Source_FillPen
:
715 if (dataSource
->gs_PlotFillPen
!= -1)
716 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
, dataSource
->gs_PlotFillPen
);
717 dataSource
->gs_PlotFillPen
= (WORD
)msg
->AttribVal
;
724 IPTR
Graph__MUIM_Graph_Reset(Class
*cl
, Object
*obj
, Msg msg
)
726 D(bug("[Graph] %s()\n", __func__
);)
731 IPTR
Graph__MUIM_Graph_Timer(Class
*cl
, Object
*obj
, Msg msg
)
733 struct Graph_DATA
*data
;
736 D(bug("[Graph] %s()\n", __func__
);)
738 data
= INST_DATA(cl
, obj
);
740 if ((data
->graph_Tick
+= data
->ihn
.ihn_Millis
) > data
->graph_PeriodStepping
)
741 data
->graph_Tick
-= data
->graph_PeriodStepping
;
743 if (data
->graph_Flags
& GRAPHF_PERIODIC
)
745 if (data
->graph_SourceCount
> 0)
747 BOOL updateEntries
= FALSE
, updated
= FALSE
, move
= FALSE
;
749 if (data
->graph_Flags
& GRAPHF_FIXEDLEN
)
751 if (data
->graph_EntryPtr
>= data
->graph_EntryCount
)
753 data
->graph_EntryPtr
= data
->graph_EntryCount
- 1;
759 if (!(data
->graph_EntryCount
) || (data
->graph_EntryPtr
>= data
->graph_EntryCount
))
760 updateEntries
= TRUE
;
763 D(bug("[Graph] %s: reading entry %d\n", __func__
, data
->graph_EntryPtr
);)
765 for (i
= 0; i
< data
->graph_SourceCount
; i
++)
767 if (data
->graph_Sources
[i
].gs_ReadHook
)
771 Graph__UpdateSourceEntries(data
, i
, (data
->graph_EntryPtr
+ 1));
777 CopyMem(&data
->graph_Sources
[i
].gs_Entries
[1], &data
->graph_Sources
[i
].gs_Entries
[0], sizeof(IPTR
) * (data
->graph_EntryCount
- 1));
780 D(bug("[Graph] %s: source %d entries @ 0x%p\n", __func__
, i
, data
->graph_Sources
[i
].gs_Entries
);)
781 CALLHOOKPKT(data
->graph_Sources
[i
].gs_ReadHook
,
782 (APTR
)&data
->graph_Sources
[i
].gs_Entries
[data
->graph_EntryPtr
],
783 data
->graph_Sources
[i
].gs_ReadHook
->h_Data
);
787 data
->graph_EntryCount
++;
788 data
->graph_EntryPtr
++;
791 SET(obj
, MUIA_Graph_PeriodicTick
, TRUE
);