3 This is a simple version of the preview class. No subtasks,
4 and no context menu. It also keeps it's copy of passed image,
5 so no need to keep if for yourself.
10 #define AROS_ALMOST_COMPATIBLE
12 #include <proto/muimaster.h>
13 #include <libraries/mui.h>
15 #include <proto/exec.h>
16 #include <proto/utility.h>
17 #include <exec/libraries.h>
18 #include <graphics/gfx.h>
19 #include <proto/alib.h>
20 #include <proto/graphics.h>
21 #include <graphics/rpattr.h>
27 #include <constructor.h>
28 #include <intuition/pointerclass.h>
30 #define SYSTEM_PRIVATE
31 #include <proto/cybergraphics.h>
32 #include <cybergraphx/cybergraphics.h>
35 #include <private/vapor/vapor.h>
36 #include "pageview_class.h"
37 #include "documentview_class.h"
38 #include "documentlayout_class.h"
39 #include "annotation_class.h"
41 #include "system/chunky.h"
42 #include "system/memory.h"
43 #include "system/functions.h"
48 typedef struct ThbImage_s
53 int bpp
; // can be 1 or 4
58 float x1
, y1
, x2
, y2
; // pdf document device coordinates
59 int ux1
, uy1
, ux2
, uy2
; // user space coordinates
64 struct annotationnode
{
67 int ux1
, uy1
, ux2
, uy2
;
73 struct markernode marker
;
74 struct pdfSelectionRegion
*oldregion
;
81 struct MUI_EventHandlerNode eh
;
82 struct PageViewRegion region
;
90 struct Rect32 refreshrect
;
97 int prevwidth
, prevheight
;
98 int mediawidth
, mediaheight
;
108 struct MinList markerlist
;
109 struct MinList annotationlist
;
111 struct SignalSemaphore sema
;
117 * MUI Standard methods
126 ObtainSemaphore(&data
->sema
);
127 if (data
->image
!= NULL
)
128 mfree(data
->image
->data
);
130 ReleaseSemaphore(&data
->sema
);
132 if (data
->lasso
.oldregion
!= NULL
)
133 pdfDisposeRegionForSelection(data
->doc
, data
->lasso
.oldregion
);
135 /* remove all markers and annotations (only links to annotation objects!) */
137 while(!ISLISTEMPTY(&data
->markerlist
))
139 struct markernode
*mn
= (struct markernode
*)GetHead(&data
->markerlist
);
144 while(!ISLISTEMPTY(&data
->annotationlist
))
146 struct annotationnode
*an
= (struct annotationnode
*)GetHead(&data
->annotationlist
);
151 /* dispose parent class */
160 static int getinformationspace(Object
*obj
, struct Data
*data
)
163 if (data
->information
& MUIV_PageView_Information_Number
)
164 space
+= _font(obj
)->tf_YSize
+ 2;
169 METHOD
ThbAskMinMax(struct IClass
*cl
,Object
*obj
,struct MUIP_AskMinMax
*msg
)
174 let our superclass first fill in what it thinks about sizes.
175 this will e.g. add the size of frame and inner spacing.
181 now add the values specific to our object. note that we
182 indeed need to *add* these values, not just set them!
185 msg
->MinMaxInfo
->MinWidth
+= data
->layoutwidth
;
186 msg
->MinMaxInfo
->DefWidth
+= data
->layoutwidth
;
187 msg
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
189 msg
->MinMaxInfo
->MinHeight
+= data
->layoutheight
+ getinformationspace(obj
, data
);
190 msg
->MinMaxInfo
->DefHeight
+= data
->layoutheight
+ getinformationspace(obj
, data
);
191 msg
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
202 obj
= DoSuperNew(cl
, obj
, MUIA_FillArea
, FALSE
,
203 // MUIA_CustomBackfill, TRUE,
204 // MUIA_Background, MUII_SHADOW,
211 memset(data
, 0, sizeof(struct Data
));
213 InitSemaphore(&data
->sema
);
214 NEWLIST(&data
->markerlist
);
215 NEWLIST(&data
->annotationlist
);
219 data
->refreshrect
.MinX
= -1;
220 data
->layoutwidth
= 128;
221 data
->layoutheight
= 128;
222 data
->information
= MUIV_PageView_Information_None
;
226 case MUIA_PageView_Rotation
:
227 data
->rotation
= tag
->ti_Data
;
230 case MUIA_PageView_PDFDocument
:
231 data
->doc
= (void*)tag
->ti_Data
;
233 case MUIA_PageView_Page
:
234 data
->page
= tag
->ti_Data
;
236 case MUIA_PageView_MediaWidth
:
237 data
->mediawidth
= tag
->ti_Data
;
239 case MUIA_PageView_MediaHeight
:
240 data
->mediaheight
= tag
->ti_Data
;
242 case MUIA_PageView_Information
:
243 data
->information
= tag
->ti_Data
;
245 case MUIA_PageView_IsPreview
:
246 data
->ispreview
= tag
->ti_Data
;
261 METHOD
riSetup(struct IClass
*cl
, Object
*obj
, struct MUIP_Setup
*msg
)
275 METHOD
riCleanup(struct IClass
*cl
,Object
*obj
,Msg msg
)
279 if (data
->flushmethodid
!= 0)
281 DoMethod(_app(obj
), MUIM_Application_UnpushMethod
, NULL
, data
->flushmethodid
, 0);
282 data
->flushmethodid
= 0;
285 DoMethod(obj
, MUIM_PageView_Flush
);
294 void kprintf(char *fmt
,...);
296 static void rendermarker(struct Data
*data
, struct RastPort
*rp
, struct markernode
*mn
, int x0
, int y0
)
298 int x1
= mn
->ux1
, y1
= mn
->uy1
;
299 int x2
= mn
->ux2
, y2
= mn
->uy2
;
301 SetRPAttrs(rp
, RPTAG_PenMode
, FALSE
, RPTAG_FgColor
, 0xffff0000, TAG_DONE
);
302 RectFill(rp
, x0
+ x1
- 2, y0
+ y2
- 2, x0
+ x2
+ 2, y0
+ y2
- 1);
303 RectFill(rp
, x0
+ x1
- 2, y0
+ y1
+ 1, x0
+ x2
+ 2, y0
+ y1
+ 2);
304 RectFill(rp
, x0
+ x1
- 2, y0
+ y2
, x0
+ x1
- 1, y0
+ y1
);
305 RectFill(rp
, x0
+ x2
+ 1, y0
+ y2
, x0
+ x2
+ 2, y0
+ y1
);
307 ProcessPixelArray(rp
, x0
+ x1
- 1, y0
+ y2
- 1, x2
- x1
, y1
- y2
, POP_DARKEN
, 10, NULL
);
310 METHOD
riDraw(struct IClass
*cl
,Object
*obj
,struct MUIP_Draw
*msg
)
312 unsigned int rc
= DOSUPER
;
314 /* If MADF_DRAWOBJECT is not set then we shoulnt draw anything */
316 if (msg
->flags
& (MADF_DRAWOBJECT
| MADF_DRAWUPDATE
))
321 ObtainSemaphore(&data
->sema
);
323 if (data
->parent
== NULL
)
324 data
->parent
= (void*)xget(obj
, MUIA_Parent
);
326 activepage
= xget(data
->parent
, MUIA_DocumentLayout_Page
);
328 if (data
->image
&& data
->image
->data
)
334 int prvwidth
, prvheight
;
336 ThbImage
*image
= data
->image
;
340 prvwidth
= _mwidth(obj
);
341 prvheight
= _mheight(obj
) - getinformationspace(obj
, data
);
343 /* calculate placement */
345 if (image
->height
< prvheight
)
347 y0
+= (prvheight
- image
->height
) / 2;
348 height
= image
->height
;
353 if (image
->width
< prvwidth
)
355 x0
+= (prvwidth
- image
->width
) / 2;
356 width
= image
->width
;
361 /* store offset for eventhandler */
363 data
->offsetx
= x0
- _mleft(obj
);
364 data
->offsety
= y0
- _mtop(obj
);
366 /* install cliprect and draw */
368 if (data
->quiet
== FALSE
)
370 if (0 && data
->refreshrect
.MinX
!= -1)
372 width
= data
->refreshrect
.MaxX
- data
->refreshrect
.MinX
;
373 height
= data
->refreshrect
.MaxY
- data
->refreshrect
.MinY
;
374 WritePixelArray(image
->data
, data
->refreshrect
.MinX
, data
->refreshrect
.MinY
, image
->width
* image
->bpp
, _rp(obj
), x0
+ data
->refreshrect
.MinX
, y0
+ data
->refreshrect
.MinY
, width
, height
, image
->bpp
== 4 ? RECTFMT_ARGB
: RECTFMT_GREY8
);
377 WritePixelArray(image
->data
, 0, 0, image
->width
* image
->bpp
, _rp(obj
), x0
, y0
, width
, height
, data
->image
->bpp
== 4 ? RECTFMT_ARGB
: RECTFMT_GREY8
);
379 /* draw remaining area with background */
381 if ((image
->width
< _mwidth(obj
) || image
->height
< _mheight(obj
)))
383 int lb
= x0
- _mleft(obj
);
384 int rb
= _mwidth(obj
) - image
->width
- lb
;
385 int tb
= y0
- _mtop(obj
);
386 int bb
= _mheight(obj
) - image
->height
- tb
;
389 DoMethod(obj
, MUIM_DrawBackground
, _mleft(obj
), _mtop(obj
), lb
, _mheight(obj
), 0, 0, 0);
391 DoMethod(obj
, MUIM_DrawBackground
, _mright(obj
) - rb
+ 1, _mtop(obj
), rb
, _mheight(obj
), 0, 0, 0);
397 DoMethod(obj
, MUIM_DrawBackground
, _mleft(obj
) + lb
, _mtop(obj
), _mwidth(obj
) - lb
- rb
, tb
, 0, 0, 0);
399 DoMethod(obj
, MUIM_DrawBackground
, _mleft(obj
) + lb
, _mbottom(obj
) - bb
+ 1, _mwidth(obj
) - lb
- rb
, bb
, 0, 0, 0);
403 /* render page number if requested */
405 if (data
->information
& MUIV_PageView_Information_Number
)
408 int informationspace
= getinformationspace(obj
, data
);
409 int textwidth
, textpos
;
410 unsigned int textdim
;
412 snprintf(buff
, sizeof(buff
), "%d", data
->page
);
414 textdim
= DoMethod(obj
, MUIM_TextDim
, buff
, strlen(buff
), 0, 0);
415 textwidth
= textdim
& 0xffff;
416 textpos
= _mwidth(obj
) /2 - textwidth
/ 2;
417 DoMethod(obj
, MUIM_Text
, _mleft(obj
) + textpos
, _mbottom(obj
) - informationspace
, _mwidth(obj
), informationspace
, buff
, strlen(buff
), 0, 0);
421 /* draw active page marker (TODO: make it flickerfree) */
423 if (data
->page
== activepage
)
425 SetRPAttrs(_rp(obj
), RPTAG_PenMode
, FALSE
, RPTAG_FgColor
, 0xffff0000, TAG_DONE
);
426 RectFill(_rp(obj
), x0
, y0
, x0
+ width
- 1, y0
+ 1);
427 RectFill(_rp(obj
), x0
, y0
+ height
- 2, x0
+ width
- 1, y0
+ height
- 1);
428 RectFill(_rp(obj
), x0
, y0
, x0
+ 1, y0
+ height
- 1);
429 RectFill(_rp(obj
), x0
+ width
- 2, y0
, x0
+ width
- 1, y0
+ height
- 1);
432 /* draw selection markers (TODO: make it flickerfree) */
434 if (!ISLISTEMPTY(&data
->markerlist
))
436 struct markernode
*mn
;
438 ITERATELIST(mn
, &data
->markerlist
)
440 rendermarker(data
, _rp(obj
), mn
, x0
, y0
);
446 if (data
->lasso
.enabled
)
448 rendermarker(data
, _rp(obj
), &data
->lasso
.marker
, x0
, y0
);
453 else if (data
->quiet
== FALSE
)
455 DoMethod(obj
, MUIM_DrawBackground
, _mleft(obj
), _mtop(obj
), _mwidth(obj
), _mheight(obj
), 0, 0, 0);
458 if (data
->image
== NULL
|| data
->image
->data
== NULL
|| data
->invalid
/*|| data->prevwidth != _mwidth(obj) || data->prevheight != _mheight(obj)*/)
460 /* setup needrefresh param so the main app can rerender page */
461 //data->prevwidth = _mwidth(obj);
462 //data->prevheight = _mheight(obj);
463 data
->invalid
= FALSE
;
464 SetAttrs(_parent(obj
), MUIA_Group_Forward
, FALSE
, MUIA_PageView_NeedRefresh
, data
->page
, TAG_DONE
);
467 ReleaseSemaphore(&data
->sema
);
475 /// render selection region
477 static void renderselectionregion(Object
*obj
, struct Data
*data
, struct pdfSelectionRegion
*selection
)
479 if (selection
!= NULL
&& data
->image
!= NULL
&& data
->image
->data
!= NULL
)
482 for(i
=0; i
<selection
->numrects
; i
++)
488 struct pdfSelectionRectangle
*rect
= &selection
->rectangles
[i
];
491 for(y
=rect
->y1
* data
->image
->height
; y
<=rect
->y2
* data
->image
->height
; y
++)
493 if (data
->image
->bpp
== 4)
495 unsigned int *img
= (unsigned int*)data
->image
->data
;
496 int width
= data
->image
->width
;
498 for(x
=rect
->x1
* data
->image
->width
; x
<=rect
->x2
* data
->image
->width
; x
++)
500 if (x
>= 0 && y
>= 0 && x
< data
->image
->width
&& y
< data
->image
->height
)
501 img
[x
+ width
* y
] = 0x00ffffff ^ img
[x
+ width
* y
];
504 else if (data
->image
->bpp
== 1)
506 unsigned char *img
= (unsigned char*)data
->image
->data
;
507 int width
= data
->image
->width
;
509 for(x
=rect
->x1
* data
->image
->width
; x
<=rect
->x2
* data
->image
->width
; x
++)
511 if (x
>= 0 && y
>= 0 && x
< data
->image
->width
&& y
< data
->image
->height
)
512 img
[x
+ width
* y
] = 0xff ^ img
[x
+ width
* y
];
522 /// updatemarkers (resize to device coords)
524 static void updatemarkers(Object
*obj
, struct Data
*data
, int all
)
526 struct markernode
*mn
;
527 struct annotationnode
*an
;
528 //pdfLock(data->doc);
530 if (data
->image
!= NULL
&& data
->image
->data
!= NULL
)
533 ITERATELIST(mn
, &data
->markerlist
)
535 //pdfConvertDeviceToUser(data->doc, data->page, mn->x1, mn->y1, &mn->ux1, &mn->uy1);
536 //pdfConvertDeviceToUser(data->doc, data->page, mn->x2, mn->y2, &mn->ux2, &mn->uy2);
538 float ox1
= mn
->x1
- 0.5f
, oy1
= mn
->y1
- 0.5f
;
539 float ox2
= mn
->x2
- 0.5f
, oy2
= mn
->y2
- 0.5f
;
540 float x1
, x2
, y1
, y2
;
543 if (data
->rotation
== 0)
548 else if (data
->rotation
== 1)
553 else if (data
->rotation
== 2)
555 x1
= -ox1
; y1
= -oy1
;
556 x2
= -ox2
; y2
= -oy2
;
558 else /*(data->rotation == 3)*/
564 if (x1
> x2
) /*can happen after rotation */
577 x1
+= 0.5f
; y1
+= 0.5f
;
578 x2
+= 0.5f
; y2
+= 0.5f
;
580 mn
->ux1
= x1
* data
->image
->width
;
581 mn
->uy1
= y1
* data
->image
->height
;
582 mn
->ux2
= x2
* data
->image
->width
;
583 mn
->uy2
= y2
* data
->image
->height
;
587 ITERATELIST(an
, &data
->annotationlist
)
589 //pdfConvertDeviceToUser(data->doc, data->page, mn->x1, mn->y1, &mn->ux1, &mn->uy1);
590 //pdfConvertDeviceToUser(data->doc, data->page, mn->x2, mn->y2, &mn->ux2, &mn->uy2);
592 float ox1
= an
->x1
- 0.5f
, oy1
= an
->y1
- 0.5f
;
593 float ox2
= an
->x2
- 0.5f
, oy2
= an
->y2
- 0.5f
;
594 float x1
, x2
, y1
, y2
;
597 if (data
->rotation
== 0)
602 else if (data
->rotation
== 1)
607 else if (data
->rotation
== 2)
609 x1
= -ox1
; y1
= -oy1
;
610 x2
= -ox2
; y2
= -oy2
;
612 else /*(data->rotation == 3)*/
618 if (x1
> x2
) /*can happen after rotation */
631 x1
+= 0.5f
; y1
+= 0.5f
;
632 x2
+= 0.5f
; y2
+= 0.5f
;
634 an
->ux1
= x1
* data
->image
->width
;
635 an
->uy1
= y1
* data
->image
->height
;
636 an
->ux2
= x2
* data
->image
->width
;
637 an
->uy2
= y2
* data
->image
->height
;
640 SetAttrs(an
->obj
, MUIA_Annotation_PosX
, an
->ux1
, MUIA_Annotation_PosY
, an
->uy1
, TAG_DONE
);
643 /* lasso. ignore page rotation as it can't change when marker is enabled */
646 struct markernode
*mn
= &data
->lasso
.marker
;
647 //pdfConvertDeviceToUser(data->doc, data->page, mn->x1, mn->y1, &mn->ux1, &mn->uy1);
648 //pdfConvertDeviceToUser(data->doc, data->page, mn->x2, mn->y2, &mn->ux2, &mn->uy2);
650 float ox1
= mn
->x1
- 0.5f
, oy1
= mn
->y1
- 0.5f
;
651 float ox2
= mn
->x2
- 0.5f
, oy2
= mn
->y2
- 0.5f
;
652 float x1
, x2
, y1
, y2
;
658 if (x1
> x2
) /*can happen for lasso */
671 x1
+= 0.5f
; y1
+= 0.5f
;
672 x2
+= 0.5f
; y2
+= 0.5f
;
674 mn
->ux1
= x1
* data
->image
->width
;
675 mn
->uy1
= y1
* data
->image
->height
;
676 mn
->ux2
= x2
* data
->image
->width
;
677 mn
->uy2
= y2
* data
->image
->height
;
682 //pdfRelease(data->doc);
696 case MUIA_PageView_LayoutWidth
:
697 data
->layoutwidth
= tag
->ti_Data
;
698 data
->invalid
= TRUE
;
701 case MUIA_PageView_LayoutHeight
:
702 data
->layoutheight
= tag
->ti_Data
;
703 data
->invalid
= TRUE
;
706 case MUIA_PageView_Page
:
707 data
->page
= tag
->ti_Data
;
710 case MUIA_PageView_PDFReady
:
711 data
->ready
= tag
->ti_Data
;
714 case MUIA_PageView_Quiet
:
715 data
->quiet
= tag
->ti_Data
;
718 case MUIA_PageView_PDFBitmap
:
720 /* delete old image if present and create new. can NOT refresh display! */
722 ObtainSemaphore(&data
->sema
);
724 if (tag
->ti_Data
== NULL
)
726 if (data
->image
!= NULL
)
728 mfree(data
->image
->data
);
729 data
->image
->data
= NULL
;
734 if (data
->image
== NULL
)
736 struct pdfBitmap
*bm
= (struct pdfBitmap
*)tag
->ti_Data
;
738 data
->image
= calloc(1, sizeof(ThbImage
));
742 data
->region
.x2
= bm
->width
- 1;
743 data
->region
.y2
= bm
->height
- 1;
746 if (data
->image
!= NULL
)
748 struct pdfBitmap
*bm
= (struct pdfBitmap
*)tag
->ti_Data
;
749 int isgrayscale
= TRUE
;
752 for(y
=0; y
<bm
->height
; y
++)
754 unsigned char *src
= bm
->data
+ bm
->stride
* y
;
755 unsigned int rowdiff
= 0;
756 for(x
=bm
->width
; x
>0; x
--)
761 int different
= (r
| g
| b
) - (r
& g
& b
); // hopefuly this works and is faster than two conditions
762 // when equal both terms should be equal so diff == 0
763 // also, when different it will always be > 0
765 rowdiff
+= different
;
776 D(kprintf("image is grayscale:%d\n", isgrayscale
));
778 data
->image
->width
= bm
->width
;
779 data
->image
->height
= bm
->height
;
780 data
->image
->bpp
= isgrayscale
? 1 : 4;
781 data
->image
->data
= mmalloc(bm
->width
* bm
->height
* data
->image
->bpp
);
782 if (data
->image
->data
!= NULL
)
785 for(i
=0; i
<bm
->height
; i
++)
787 unsigned char *src
= bm
->data
+ bm
->stride
* i
;
788 if (isgrayscale
== FALSE
)
789 memcpy((unsigned int*)data
->image
->data
+ i
* bm
->width
, src
, bm
->width
* 4);
792 unsigned char *dst
= data
->image
->data
+ data
->image
->width
* i
;
793 for(j
=bm
->width
; j
>0; j
--)
803 updatemarkers(obj
, data
, TRUE
);
804 renderselectionregion(obj
, data
, data
->lasso
.oldregion
);
807 ReleaseSemaphore(&data
->sema
);
811 case MUIA_PageView_Rotation
:
813 data
->rotation
= tag
->ti_Data
;
814 data
->invalid
= TRUE
;
831 switch (msg
->opg_AttrID
)
833 case MUIA_PageView_Width
:
834 *(msg
->opg_Storage
) = (ULONG
)(data
->image
? data
->image
->width
: 0);
837 case MUIA_PageView_Height
:
838 *(msg
->opg_Storage
) = (ULONG
)(data
->image
? data
->image
->height
: 0);
841 case MUIA_PageView_LayoutWidth
:
842 *(msg
->opg_Storage
) = (ULONG
)(data
->layoutwidth
);
845 case MUIA_PageView_LayoutHeight
:
846 *(msg
->opg_Storage
) = (ULONG
)(data
->layoutheight
);
849 case MUIA_PageView_Region
:
850 *(msg
->opg_Storage
) = (ULONG
)&data
->region
;
853 case MUIA_PageView_Page
:
854 *(msg
->opg_Storage
) = (ULONG
)data
->page
;
857 case MUIA_PageView_MediaWidth
:
858 *(msg
->opg_Storage
) = (ULONG
)data
->mediawidth
;
861 case MUIA_PageView_MediaHeight
:
862 *(msg
->opg_Storage
) = (ULONG
)data
->mediaheight
;
865 case MUIA_PageView_RedirectPage
:
868 case MUIA_PageView_NeedRefresh
:
871 case MUIA_PageView_RenderWidth
:
872 *(msg
->opg_Storage
) = xget(obj
, MUIA_Width
);
875 case MUIA_PageView_RenderHeight
:
876 *(msg
->opg_Storage
) = xget(obj
, MUIA_Height
) - getinformationspace(obj
, data
);
879 case MUIA_PageView_Rotation
:
880 *(msg
->opg_Storage
) = data
->rotation
;
892 DEFMMETHOD(PageView_Update
)
896 data
->refreshrect
.MinX
= msg
->x
;
897 data
->refreshrect
.MaxX
= msg
->x
+ msg
->width
;
898 data
->refreshrect
.MinY
= msg
->y
;
899 data
->refreshrect
.MaxY
= msg
->y
+ msg
->height
;
901 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
903 data
->refreshrect
.MinX
= -1;
911 METHOD
riHandleEvent(struct IClass
*cl
,Object
*obj
,struct MUIP_HandleEvent
*msg
)
913 #define _between(a,x,b) ((x)>=(a) && (x)<=(b))
914 #define _isinobject(obj,x,y) (_between(vl,(x),vl+vw) && _between(vt,(y),vt+vh))
915 #define _isinimage(obj,x,y) (_between(vl + data->offsetx, (x), vl + vw - data->offsetx) && _between(vt + data->offsety,(y), vt + vh - data->offsety))
918 int vl
= _mleft(obj
);
920 int vw
= _mwidth(obj
);
921 int vh
= _mheight(obj
);
923 if (msg
->imsg
!= NULL
&& _isinobject(obj
, msg
->imsg
->MouseX
, msg
->imsg
->MouseY
)/* || data->eh.ehn_Events & IDCMP_MOUSEMOVE*/)
925 if (msg
->imsg
!= NULL
)
927 switch (msg
->imsg
->Class
)
929 case IDCMP_MOUSEBUTTONS
:
931 int mx
= max(0, msg
->imsg
->MouseX
- _left(obj
) - data
->offsetx
);
932 int my
= max(0, msg
->imsg
->MouseY
- _top(obj
) - data
->offsety
);
934 if (msg
->imsg
->Code
== SELECTDOWN
)
936 if (_isinimage(obj
, msg
->imsg
->MouseX
, msg
->imsg
->MouseY
))
938 data
->mousedown
= TRUE
;
939 if (data
->ispreview
== FALSE
&& data
->lasso
.enabled
== FALSE
&& xget(objFindContainerByAttribute(obj
, MUIA_DocumentView_DragAction
), MUIA_DocumentView_DragAction
) == MUIV_DocumentView_DragAction_Mark
) /* first coord */
941 /* clear selection on all previous pages */
943 DoMethod(objFindContainerByAttribute(obj
, MUIA_DocumentView_DragAction
), MUIM_DocumentView_ClearSelection
);
945 data
->lasso
.marker
.x1
= data
->lasso
.marker
.x2
= (float)mx
/ data
->image
->width
;
946 data
->lasso
.marker
.y1
= data
->lasso
.marker
.y2
= (float)my
/ data
->image
->height
;
947 data
->lasso
.enabled
= TRUE
;
951 else if (msg
->imsg
->Code
== SELECTUP
)
953 if (data
->lasso
.enabled
)
955 data
->lasso
.enabled
= FALSE
;
957 else if (data
->ready
&& !data
->ispreview
)
961 void *link
= pdfFindLink(data
->doc
, data
->page
, x
, y
);
964 int page
= pdfGetActionPageFromLink(data
->doc
, link
);
965 //printf("find page:%d\n", page);
966 //char *url = linkGetActionURL(link);
968 set(_parent(obj
), MUIA_PageView_RedirectPage
, page
);
971 /* lookup annotation and toggle */
972 if (!ISLISTEMPTY(&data
->annotationlist
))
974 struct annotationnode
*an
;
975 ITERATELIST(an
, &data
->annotationlist
)
977 //printf("checking %d, %d vs %d,%d %d,%d\n", mx, my, an->ux1, an->uy1, an->ux2, an->uy2);
978 if (_between(an
->ux1
, mx
, an
->ux2
) && _between(an
->uy2
, my
, an
->uy1
))
980 DoMethod(an
->obj
, MUIM_Annotation_Toggle
);
987 else if (data
->ispreview
&& data
->mousedown
) /* for page preview, like in outlines */
989 set(_parent(obj
), MUIA_PageView_RedirectPage
, data
->page
);
992 data
->mousedown
= TRUE
;
997 case IDCMP_MOUSEMOVE
:
999 int mx
= max(0, msg
->imsg
->MouseX
- _left(obj
) - data
->offsetx
);
1000 int my
= max(0, msg
->imsg
->MouseY
- _top(obj
) - data
->offsety
);
1002 if (data
->lasso
.enabled
)
1004 struct pdfSelectionRegion
*selection
;
1006 data
->lasso
.marker
.x2
= min(1.0, (float)mx
/ data
->image
->width
);
1007 data
->lasso
.marker
.y2
= min(1.0, (float)my
/ data
->image
->height
);
1009 /* fetch selection from pdf document */
1011 if (data
->lasso
.oldregion
!= NULL
)
1013 renderselectionregion(obj
, data
, data
->lasso
.oldregion
);
1014 pdfDisposeRegionForSelection(data
->doc
, data
->lasso
.oldregion
);
1017 selection
= pdfBuildRegionForSelection(data
->doc
, data
->page
, data
->lasso
.marker
.x1
, data
->lasso
.marker
.y1
, data
->lasso
.marker
.x2
, data
->lasso
.marker
.y2
, NULL
);
1018 if (selection
!= NULL
)
1020 renderselectionregion(obj
, data
, selection
);
1021 data
->lasso
.oldregion
= selection
;
1024 updatemarkers(obj
, data
, TRUE
);
1025 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1026 return MUI_EventHandlerRC_Eat
;
1029 /* find area over which we are and setup appropriate pointer */
1030 if (data
->hasregion
&& data
->moveregion
== 0)
1032 int handle
= rectFindClosestHandle(data
, &data
->region
, mx
, my
, 0);
1033 int cursormapping
[9] = {
1034 POINTERTYPE_DIAGONALRESIZE2
,
1035 POINTERTYPE_DIAGONALRESIZE1
,
1036 POINTERTYPE_DIAGONALRESIZE2
,
1037 POINTERTYPE_DIAGONALRESIZE1
,
1038 POINTERTYPE_VERTICALRESIZE
,
1039 POINTERTYPE_HORIZONTALRESIZE
,
1040 POINTERTYPE_VERTICALRESIZE
,
1041 POINTERTYPE_HORIZONTALRESIZE
,
1044 if (_isinimage(obj
, msg
->imsg
->MouseX
, msg
->imsg
->MouseY
))
1046 if (data
->pointertype
!= cursormapping
[handle
- 1])
1047 SetWindowPointer(_window(obj
), WA_PointerType
, data
->pointertype
= cursormapping
[handle
- 1], TAG_DONE
);
1050 SetWindowPointer(_window(obj
), WA_PointerType
, data
->pointertype
= POINTERTYPE_NORMAL
, TAG_DONE
);
1052 else if (data
->hasregion
)
1054 rectSetCorner(data
, &data
->region
, data
->moveregion
, mx
, my
, 0);
1055 set(obj
, MUIA_PageView_Region
, (ULONG
)&data
->region
);
1057 else if (!data
->hasregion
&& data
->ready
)
1063 //link = pdfFindLink(data->doc, data->page, x, y);
1067 //char *description = linkGetDescription(link);
1071 //kprintf("mouse:%d,%d\n", (int)x, (int)y);
1088 DEFMMETHOD(Backfill
)
1090 //printf("%d, %d, %d, %d\n", msg->left, msg->top, msg->right, msg->bottom);
1102 /* hide is a bit tricky in virtgroups. it is called while scrolling so
1103 we just push the method and if show is called right after it then flush
1106 #if defined(__AROS__)
1107 kprintf("[Pageview::Hide] not implemented\n");
1108 // FIXME: implement MUIV_PushMethod_Delay in Zune/AROS
1109 data
->flushmethodid
= DoMethod(_app(obj
), MUIM_Application_PushMethod
, obj
, 1, MUIM_PageView_Flush
);
1111 data
->flushmethodid
= DoMethod(_app(obj
), MUIM_Application_PushMethod
, obj
, 1 | MUIV_PushMethod_Delay(150), MUIM_PageView_Flush
);
1113 D(kprintf("cleanup:%d\n", data
->page
));
1125 if (data
->flushmethodid
!= 0)
1127 DoMethod(_app(obj
), MUIM_Application_UnpushMethod
, NULL
, data
->flushmethodid
, 0);
1128 data
->flushmethodid
= 0;
1131 if ((1) && data
->eh
.ehn_Object
== NULL
)
1133 data
->eh
.ehn_Object
= obj
;
1134 data
->eh
.ehn_Class
= cl
;
1135 data
->eh
.ehn_Events
= IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE
;
1136 data
->eh
.ehn_Priority
= 100;
1137 data
->eh
.ehn_Flags
= MUI_EHF_GUIMODE
;
1139 DoMethod(_win(obj
), MUIM_Window_AddEventHandler
, &data
->eh
);
1149 DEFMMETHOD(PageView_Flush
)
1153 ObtainSemaphore(&data
->sema
);
1155 if (data
->image
!= NULL
)
1157 mfree(data
->image
->data
);
1158 data
->image
->data
= NULL
;
1161 if (data
->eh
.ehn_Object
!= NULL
)
1163 DoMethod(_win(obj
), MUIM_Window_RemEventHandler
, &data
->eh
);
1164 data
->eh
.ehn_Object
= NULL
;
1167 data
->flushmethodid
= 0;
1168 ReleaseSemaphore(&data
->sema
);
1177 DEFMMETHOD(PageView_AddMarker
)
1180 unsigned int id
= 0;
1182 struct markernode
*mn
;
1184 if (msg
->id
!= MUIV_PageView_AddMarker_New
)
1187 ITERATELIST(mn
, &data
->markerlist
)
1189 if (mn
->id
== msg
->id
)
1202 mn
= calloc(1, sizeof(*mn
));
1207 mn
->x1
= msg
->coords
[0];
1208 mn
->y1
= msg
->coords
[1];
1209 mn
->x2
= msg
->coords
[2];
1210 mn
->y2
= msg
->coords
[3];
1211 mn
->color
= msg
->color
;
1213 ADDTAIL(&data
->markerlist
, mn
);
1214 updatemarkers(obj
, data
, FALSE
);
1224 DEFMMETHOD(PageView_RemoveMarker
)
1228 /* TODO: add single marker removal */
1230 while(!ISLISTEMPTY(&data
->markerlist
))
1232 struct markernode
*mn
= (struct markernode
*)GetHead(&data
->markerlist
);
1244 DEFMMETHOD(PageView_AddAnnotation
)
1248 struct annotationnode
*an
;
1249 an
= calloc(1, sizeof(*an
));
1253 an
->x1
= msg
->coords
[0];
1254 an
->y1
= msg
->coords
[1];
1255 an
->x2
= msg
->coords
[2];
1256 an
->y2
= msg
->coords
[3];
1258 ADDTAIL(&data
->annotationlist
, an
);
1259 updatemarkers(obj
, data
, FALSE
);
1267 /// removeannotation
1269 DEFMMETHOD(PageView_RemoveAnnotation
)
1272 struct annotationnode
*an
;
1274 ITERATELIST(an
, &data
->annotationlist
)
1276 if (an
->obj
== msg
->obj
)
1291 DEFMMETHOD(PageView_ClearSelection
)
1295 if (data
->lasso
.oldregion
!= NULL
)
1297 renderselectionregion(obj
, data
, data
->lasso
.oldregion
);
1298 pdfDisposeRegionForSelection(data
->doc
, data
->lasso
.oldregion
);
1300 if (data
->image
!= NULL
&& data
->image
->data
!= NULL
) /* also have to refresh here! */
1301 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
1303 data
->lasso
.oldregion
= NULL
;
1304 data
->lasso
.marker
.x2
= data
->lasso
.marker
.x1
;
1305 data
->lasso
.marker
.y2
= data
->lasso
.marker
.y1
;
1315 DEFMMETHOD(PageView_GetSelection
)
1319 if (data
->lasso
.oldregion
== NULL
)
1322 msg
->region
.x1
= data
->lasso
.marker
.x1
; msg
->region
.y1
= data
->lasso
.marker
.y1
;
1323 msg
->region
.x2
= data
->lasso
.marker
.x2
; msg
->region
.y2
= data
->lasso
.marker
.y2
;
1331 case MUIM_Draw
: return(riDraw(cl
,obj
,(APTR
)msg
));
1332 case MUIM_Setup
: return(riSetup(cl
,obj
,(APTR
)msg
));
1333 case MUIM_Cleanup
: return(riCleanup(cl
,obj
,(APTR
)msg
));
1334 case MUIM_HandleEvent
: return(riHandleEvent(cl
,obj
,(APTR
)msg
));
1335 case MUIM_AskMinMax
: return(ThbAskMinMax(cl
,obj
,(APTR
)msg
));
1342 DECMMETHOD(Backfill
)
1343 DECMMETHOD(PageView_AddMarker
)
1344 DECMMETHOD(PageView_AddAnnotation
)
1345 DECMMETHOD(PageView_RemoveMarker
)
1346 DECMMETHOD(PageView_RemoveAnnotation
)
1347 DECMMETHOD(PageView_Update
)
1348 DECMMETHOD(PageView_Flush
)
1349 DECMMETHOD(PageView_ClearSelection
)
1350 DECMMETHOD(PageView_GetSelection
)
1353 DECSUBCLASS_NC(MUIC_Area
, PageViewClass
)