root/trunk/examples/sumatrapdf/pdfviewer.d

Revision 17, 12.9 kB (checked in by bobef, 4 years ago)

Updated to HTMLayout 3.2.2.8 and added a new example (see change log for more details)

Line 
1 import flowerd.dfl;
2 import dfl.all;
3 import flowerd.common;
4 import sumatra;
5 import tango.stdc.stringz;
6 import tango.sys.win32.Types;
7
8 class PDFControl : HElement
9 {
10     this(HElement parent,HElement toolbar)
11     {
12         sumatra=new Sumatra;
13         sumatra.onRepaint=&onRepaint;
14         sumatra.onSetScrollbarSize=&onSetScrollbarSize;
15         sumatra.onSetCursor=&onSetCursor;
16         sumatra.onPageChanged=&onPageChanged;
17         sumatra.onHandleLink=&onHandleLink;
18
19         wrap=new HElement("div");
20         wrap.className="sumatra";
21         self=new HElement("div");
22         super(self);
23         if(toolbar) adopt(toolbar);
24         sbh=new HScrollBar(new HElement("widget"));
25         sbh.attribute("type","hscrollbar");
26         sbv=new HScrollBar(new HElement("widget"));
27         sbv.attribute("type","vscrollbar");
28         wrap.adopt(self,wrap.children);
29         wrap.adopt(sbv,wrap.children);
30         wrap.adopt(sbh,wrap.children);
31         parent.adopt(wrap,parent.children);
32
33         sbv.handleEvent(delegate(HScroll p)
34         {
35             auto oo=cast(PDFControl)p.param;
36             if(p.cmd==SCROLL_POS) oo.sumatra.scrollY(1,p.pos);
37             else if(p.cmd==SCROLL_HOME) oo.sumatra.firstPage;
38             else if(p.cmd==SCROLL_END) oo.sumatra.firstPage;
39             else if(p.cmd==SCROLL_STEP_PLUS) oo.sumatra.scrollY(2,16);
40             else if(p.cmd==SCROLL_STEP_MINUS) oo.sumatra.scrollY(2,-16);
41             else if(p.cmd==SCROLL_PAGE_PLUS) oo.sumatra.nextPage;
42             else if(p.cmd==SCROLL_PAGE_MINUS) oo.sumatra.prevPage;
43             return false;
44         },this);
45         sbv.handleEvent(delegate(HFocus p)
46         {
47             if(p.cmd==(FOCUS_GOT|SINKING)) (cast(HElement)p.param).focus();
48             return true;
49         },self);
50         sbv.handleEvent(delegate(HMouse p)
51         {
52             if(p.cmd==(MOUSE_WHEEL|SINKING))
53             {
54                 auto oo=cast(PDFControl)p.param;
55                 if(p.alt_state&CONTROL_KEY_PRESSED)
56                 {
57                     if(cast(int)p.button_state>0) oo.sumatra.zoomIn;
58                     else oo.sumatra.zoomOut;
59                 }
60                 else oo.sumatra.scrollY(2,cast(int)p.button_state>0?-48:48);
61                 return true;
62             }
63             return false;
64         },this);
65         sbh.handleEvent(delegate(HScroll p)
66         {
67             auto oo=cast(PDFControl)p.param;
68             if(p.cmd==SCROLL_POS) oo.sumatra.scrollX(1,p.pos);
69             else if(p.cmd==SCROLL_HOME) oo.sumatra.scrollX(1,0);
70             else if(p.cmd==SCROLL_END) oo.sumatra.scrollX(1,oo.sbh.getValue.max);
71             else if(p.cmd==SCROLL_STEP_PLUS) oo.sumatra.scrollX(2,16);
72             else if(p.cmd==SCROLL_STEP_MINUS) oo.sumatra.scrollX(2,-16);
73             else if(p.cmd==SCROLL_PAGE_PLUS) oo.sumatra.scrollX(2,oo.sbh.getValue.page);
74             else if(p.cmd==SCROLL_PAGE_MINUS) oo.sumatra.scrollX(2,-oo.sbh.getValue.page);
75             return false;
76         },this);
77         sbh.handleEvent(delegate(HFocus p)
78         {
79             if(p.cmd==(FOCUS_GOT|SINKING)) (cast(HElement)p.param).focus();
80             return true;
81         },self);
82         sbh.handleEvent(delegate(HMouse p)
83         {
84             if(p.cmd==(MOUSE_WHEEL|SINKING))
85             {
86                 auto oo=cast(PDFControl)p.param;
87                 if(p.alt_state&CONTROL_KEY_PRESSED)
88                 {
89                     if(cast(int)p.button_state>0) oo.sumatra.zoomIn;
90                     else oo.sumatra.zoomOut;
91                 }
92                 else oo.sumatra.scrollX(2,cast(int)p.button_state>0?-48:48);
93                 return true;
94             }
95             return false;
96         },this);
97
98         handleEvent(&draw,this);
99         handleEvent(&size,this);
100         handleEvent(&key,this);
101         handleEvent(&mouse,this);
102         handleEvent(&mtimer);
103         focusable=true;
104     }
105
106     HElement wrap,self;
107     HScrollBar sbh,sbv;
108     Sumatra sumatra;
109     int pagesize;
110
111     bool mtimer(HTimer)
112     {
113         wrap.parent.update;
114         return false;
115     }
116
117     int onHandleLink(int type,void* data)
118     {
119         if(type==1)
120         {
121             int page=cast(int)data;
122             if(page>0 && page<sumatra.pages)
123             {
124                 myform.hSmartGo(page);
125                 return 1;
126             }
127         }
128         else if(type==2)
129         {
130             char[] uri=fromStringz(cast(char*)data).dup;
131             msgBox(uri);
132             return 1;
133         }
134         return 0;
135     }
136
137     int onPageChanged()
138     {
139         if(myform is null) return 0;
140         myform.toolbar2.timer(1);
141         return 1;
142     }
143
144     void onRepaint(bool now)
145     {
146         if(now) timer(1);
147         else timer(400);
148     }
149
150     void onSetCursor(int type)
151     {
152         static int lastcursor=1;
153         if(lastcursor!=type)
154         {
155             if(lastcursor==2) delClass("cursor_hand");
156             else if(lastcursor==3) delClass("cursor_drag");
157
158             if(type==2) addClass("cursor_hand");
159             else if(type==3) addClass("cursor_drag");
160
161             timer(1);
162         }
163         lastcursor=type;
164     }
165
166     void onSetScrollbarSize(int type,int pos,int min,int max,uint page)
167     {
168         static bool h,v;
169         if(type==1)
170         {
171             sbh.setValue(pos,min,max,page,16);
172             if(page>max)
173             {
174                 sbh.style("height","0");
175                 timer(1);
176                 h=false;
177             }
178             else
179             {
180                 if(h==false) sbh.style("height","max-intrinsic");
181                 h=true;
182             }
183         }
184         else if(type==2)
185         {
186             sbv.setValue(pos,min,max,page,16);
187             if(page>max)
188             {
189                 pagesize=0;
190                 sbv.style("height","0");
191                 timer(1);
192                 v=false;
193             }
194             else
195             {
196                 pagesize=page;
197                 if(v==false) sbv.style("height","max-intrinsic");
198                 v=true;
199             }
200         }
201     }
202
203     bool mouse(HMouse p)
204     {
205         if(p.cmd==MOUSE_WHEEL)
206         {
207             if(p.alt_state&CONTROL_KEY_PRESSED)
208             {
209                 if(cast(int)p.button_state>0) sumatra.zoomIn;
210                 else sumatra.zoomOut;
211             }
212             else sumatra.scrollY(2,cast(int)p.button_state>0?-48:48);
213             return true;
214         }
215         else if(p.cmd==MOUSE_MOVE)
216         {
217             sumatra.mouseMove(p.pos.x,p.pos.y,0);
218             return true;
219         }
220         else if(p.cmd==MOUSE_DOWN && p.button_state==MAIN_MOUSE_BUTTON)
221         {
222             sumatra.mouseDown(p.pos.x,p.pos.y,p.alt_state&CONTROL_KEY_PRESSED?MK_CONTROL:0);
223             capture(true);
224             return true;
225         }
226         else if(p.cmd==MOUSE_UP && p.button_state==MAIN_MOUSE_BUTTON)
227         {
228             sumatra.mouseUp(p.pos.x,p.pos.y,p.alt_state&CONTROL_KEY_PRESSED?MK_CONTROL:0);
229             capture(false);
230             return true;
231         }
232         return false;
233     }
234
235     bool key(HKey p)
236     {
237         if(p.cmd==KEY_DOWN)
238         {
239             auto k=p.key_code;
240             if(k==8) //backspace
241             {
242                 if(myform) myform.hBack;
243                 return true;
244             }
245             else if(k==32) //space
246             {
247                 if(pagesize<=16) return false;
248                 if(p.alt_state&SHIFT_KEY_PRESSED) sumatra.scrollY(2,-(pagesize-16));
249                 else sumatra.scrollY(2,(pagesize-16));
250             }
251             else if(k==13) //enter
252             {
253                 if(p.alt_state&CONTROL_KEY_PRESSED) sumatra.zoom=ZOOM_FIT_WIDTH;
254                 else if(p.alt_state&SHIFT_KEY_PRESSED) sumatra.zoom=ZOOM_FIT_PAGE;
255                 else sumatra.zoom=100;
256                 return true;
257             }
258             else if(k==187 || k==107) //plus
259             {
260                 sumatra.zoomIn;
261                 return true;
262             }
263             else if(k==189 || k==109) //minus
264             {
265                 sumatra.zoomOut;
266                 return true;
267             }
268             else if(k==33) //page up
269             {
270                 sumatra.prevPage;
271                 return true;
272             }
273             else if(k==34) //page down
274             {
275                 sumatra.nextPage;
276                 return true;
277             }
278             else if(k==38) //arrow up
279             {
280                 sumatra.scrollY(2,-16);
281                 return true;
282             }
283             else if(k==40) //arrow down
284             {
285                 sumatra.scrollY(2,16);
286                 return true;
287             }
288             else if(k==37) //arrow left
289             {
290                 sumatra.scrollX(2,-16);
291                 return true;
292             }
293             else if(k==39) //arrow right
294             {
295                 sumatra.scrollX(2,16);
296                 return true;
297             }
298             else if(k==36) //home
299             {
300                 sumatra.firstPage;
301                 return true;
302             }
303             else if(k==35) //end
304             {
305                 sumatra.lastPage;
306                 return true;
307             }
308         }
309         return false;
310     }
311
312     void size(HSize p) // size
313     {
314         auto a=p.element.viewSize;
315         sumatra.resize(a.cx,a.cy);
316     }
317
318     bool draw(HDraw p)
319     {
320         if(p.cmd==DRAW_CONTENT)
321         {
322             auto a=p.area;
323             int w=a.right-a.left,h=a.bottom-a.top;
324             sumatra.render(p.hdc,a.left,a.top,w,h);
325             return true;
326         }
327         return false;
328     }
329 }
330
331 class PdfForm : HLayoutForm
332 {
333     this()
334     {
335         super();
336         form.text="Sumatra PDF demo";
337         form.size=Size(800,700);
338         form.centerToScreen();
339
340         setOption(HTMLAYOUT_FONT_SMOOTHING,3); // force ClearType
341
342         HLayoutBase.handleEvent(&onDomReady);   //this handler is used for both
343                                                 //HLN_DOCUMENT_COMPLETE - document fully complete
344                                                 //HLN_DOCUMENT_LOADED - dom tree ready
345
346         loadHTML("pdfviewer/index.html");
347     }
348
349     HElement right,mybutton,toolbar,toolbar2,forward,back,zoom,zoomin,zoomout,zoompage,zoomwidth,currentpage,go,pdf; //keep the references or the gc will collect the event handlers away
350     PDFControl pdfcontrol;
351
352     bool myTimer6(HTimer p)
353     {
354         currentpage.innerText=Int.toString(pdfcontrol.sumatra.page)~" / "~Int.toString(pdfcontrol.sumatra.pages);
355         currentpage.update;
356         return false;
357     }
358
359     bool onDomReady(HReady event)
360     {
361         if(event.event!=HLN_DOCUMENT_COMPLETE) return false;
362
363         right=rootElement;
364         (mybutton=right.getId("open")).handleEvent(delegate(HBehaviorEvent p)
365         {
366             if(p.cmd==BUTTON_CLICK)
367             {
368                 auto dlg=new OpenFileDialog;
369                 dlg.showDialog();
370                 if(dlg.fileName.length)
371                 {
372                     auto oo=(cast(PdfForm)p.param);
373                     oo.pdfcontrol.sumatra.loadFile(dlg.fileName);
374                     oo.pdfcontrol.sumatra.displayMode=DM_CONTINUOUS;
375                     oo.pdfcontrol.sumatra.zoom=150;
376                     oo.pdf.display="block";
377                     oo.right.update;
378                     auto s=oo.pdfcontrol.viewSize;
379                     oo.pdfcontrol.sumatra.resize(s.cx,s.cy);
380                 }
381                 return true; //handled the event
382             }
383             return false; //call other handlers
384         },this);
385
386         toolbar=right.getId("toolbar");
387         /*(toolbar=right.getId("toolbar")).handleEvent(delegate(HMouse p)
388         {
389             if(p.cmd==MOUSE_ENTER)
390             {
391                 p.element.addClass("expanded");
392                 p.element.parent.update;
393                 return true;
394             }
395             else if(p.cmd==MOUSE_LEAVE)
396             {
397                 p.element.delClass("expanded");
398                 p.element.parent.update;
399                 return true;
400             }
401             return false;
402         });*/
403         (toolbar2=toolbar.getId("toolbar2")).handleEvent(&myTimer6);
404         (forward=toolbar.getId("forward")).handleEvent(delegate(HMouse p)
405         {
406             if(p.cmd==MOUSE_DOWN)
407             {
408                 myform.hForward();
409                 return true;
410             }
411             return false;
412         },this);
413         (back=toolbar.getId("back")).handleEvent(delegate(HMouse p)
414         {
415             if(p.cmd==MOUSE_DOWN)
416             {
417                 myform.hBack();
418                 return true;
419             }
420             return false;
421         },this);
422         /*(zoompage=toolbar.getId("zoompage")).handleEvent(delegate(HMouse p)
423         {
424             if(p.cmd==MOUSE_DOWN)
425             {
426                 myform.pdfcontrol.sumatra.zoom(ZOOM_FIT_PAGE);
427                 return true;
428             }
429             return false;
430         },this);*/
431         (zoom=toolbar.getId("zoom")).handleEvent(delegate(HMouse p)
432         {
433             if(p.cmd==MOUSE_DOWN)
434             {
435                 myform.pdfcontrol.sumatra.zoom(100);
436                 return true;
437             }
438             return false;
439         },this);
440         (zoomwidth=toolbar.getId("zoomwidth")).handleEvent(delegate(HMouse p)
441         {
442             if(p.cmd==MOUSE_DOWN)
443             {
444                 myform.pdfcontrol.sumatra.zoom(ZOOM_FIT_WIDTH);
445                 return true;
446             }
447             return false;
448         },this);
449         (zoomin=toolbar.getId("zoomin")).handleEvent(delegate(HMouse p)
450         {
451             if(p.cmd==MOUSE_DOWN)
452             {
453                 myform.pdfcontrol.sumatra.zoomIn;
454                 return true;
455             }
456             return false;
457         },this);
458         (zoomout=toolbar.getId("zoomout")).handleEvent(delegate(HMouse p)
459         {
460             if(p.cmd==MOUSE_DOWN)
461             {
462                 myform.pdfcontrol.sumatra.zoomOut;
463                 return true;
464             }
465             return false;
466         },this);
467         (currentpage=toolbar.getId("currentpage")).handleEvent(delegate(HKey p)
468         {
469             if(p.cmd==KEY_CHAR && p.key_code==13)
470             {
471                 uint page=0;
472                 try page=cast(uint)Int.toLong(p.element.innerText);
473                 catch(Object o) {}
474                 if(page>0 && page<=myform.pdfcontrol.sumatra.pages)
475                 {
476                     myform.hSmartGo(page);
477                     myform.right.focus;
478                     return true;
479                 }
480             }
481             return false;
482         },this);
483         (go=toolbar.getId("go")).handleEvent(delegate(HMouse p)
484         {
485             if(p.cmd==MOUSE_DOWN)
486             {
487                 uint page=0;
488                 try page=cast(uint)Int.toLong(myform.currentpage.innerText);
489                 catch(Object o) {}
490                 if(page>0 && page<=myform.pdfcontrol.sumatra.pages)
491                 {
492                     myform.hSmartGo(page);
493                     return true;
494                 }
495             }
496             return false;
497         },this);
498         pdf=right.getId("content_pdf");
499         pdfcontrol=new PDFControl(pdf,toolbar);
500
501         history=new History;
502
503         return true;
504     }
505
506     void hSmartGo(uint v)
507     {
508         auto cv=myform.hCurrentValue;
509         if(v!=cv) myform.hReplace(cv);
510         myform.hGo(v,v!=cv);
511     }
512
513     alias GrowStack!(uint) History;
514
515     History history;
516     uint hpointer;
517
518     void hBack()
519     {
520         if(hpointer>0)
521         {
522             hReplace(hCurrentValue);
523             --hpointer;
524             hGo(history[hpointer],0);
525             forward.disabled=false;
526             forward.update;
527         }
528         if(hpointer==0) back.disabled=true;
529         else back.disabled=false;
530         back.update;
531     }
532
533     void hForward()
534     {
535         if(hpointer<history.length-1)
536         {
537             hReplace(hCurrentValue);
538             ++hpointer;
539             hGo(history[hpointer],0);
540             back.disabled=false;
541             back.update;
542         }
543         if(hpointer==history.length-1) forward.disabled=true;
544         else forward.disabled=false;
545         forward.update;
546     }
547
548     void hReplace(uint val)
549     {
550         if(history.length==0) hAdd(val);
551         else history[hpointer]=val;
552     }
553
554     void hAdd(uint val)
555     {
556         history.length=hpointer+1;
557         history.push(val);
558         hpointer=history.length-1;
559         forward.disabled=true;
560         forward.update;
561         back.disabled=hpointer==0;
562         back.update;
563     }
564
565     uint hCurrentValue()
566     {
567         auto v=pdfcontrol.sumatra.page;
568         return v==-1?uint.max:pdfcontrol.sumatra.page;
569     }
570
571     void hGo(uint uval,int add)
572     {
573         if(add==1) hAdd(uval);
574         pdfcontrol.sumatra.page=uval;
575     }
576 }
577
578 PdfForm myform;
579
580 void main()
581 {
582     htmlayout.capi.loadHTMLayout(); //load the dll
583     loadSumatra(); //load sumatra
584     myform=new PdfForm;
585     Application.run(cast(Form)myform);
586 }
Note: See TracBrowser for help on using the browser.