htmlview.monkey2 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. Namespace mojox
  2. #rem monkeydoc The HtmlView class.
  3. #end
  4. Class HtmlView Extends ScrollableView
  5. #rem monkeydoc Invoked when an anchor is clicked.
  6. #end
  7. Field AnchorClicked:Void( url:String )
  8. #rem monkeydoc Creates a new HtmlView.
  9. #end
  10. Method New()
  11. Layout="fill"
  12. Style=GetStyle( "HtmlView" )
  13. _context=New litehtml.context
  14. _context.load_master_stylesheet( stringio.LoadString( "theme::htmlview_master_css.css" ) )
  15. _container=New document_container( Self )
  16. _baseUrl=filesystem.CurrentDir()
  17. AnchorClicked=Go
  18. End
  19. #rem monkeydoc Base URL.
  20. This is used as the root directory for relative anchors in the page.
  21. #end
  22. Property BaseUrl:String()
  23. Return _baseUrl
  24. Setter( baseUrl:String )
  25. If Not baseUrl.EndsWith( "/" ) baseUrl+="/"
  26. _baseUrl=baseUrl
  27. End
  28. #rem monkeydoc HTML source.
  29. #end
  30. Property HtmlSource:String()
  31. Return _source
  32. Setter( htmlSource:String )
  33. _source=htmlSource
  34. _document=New litehtml.document( _source,_container,_context )
  35. _layoutSize=New Vec2i( 0,0 )
  36. _renderSize=New Vec2i( 0,0 )
  37. RequestRender()
  38. End
  39. #rem monkeydoc Goto a url.
  40. #end
  41. Method Go( url:String )
  42. If url.Contains( "#" )
  43. Return
  44. Endif
  45. Local root:=ExtractRootDir( url )
  46. If root="http://" Or root="https://"
  47. #If __DESKTOP_TARGET__
  48. requesters.OpenUrl( url )
  49. #Endif
  50. Return
  51. Endif
  52. If Not root
  53. url=BaseUrl+url
  54. Endif
  55. Local src:=stringio.LoadString( url )
  56. If ExtractExt( url )=".md"
  57. src=hoedown.MarkdownToHtml( src )
  58. Local wrapper:=stringio.LoadString( "theme::markdown_wrapper.html" )
  59. src=wrapper.Replace( "${CONTENT}",src )
  60. End
  61. BaseUrl=ExtractDir( url )
  62. HtmlSource=src
  63. End
  64. Private
  65. Field _context:litehtml.context
  66. Field _container:litehtml.document_container
  67. Field _anchorClicked:String
  68. Field _baseUrl:String
  69. Field _source:String
  70. Field _document:litehtml.document
  71. Field _layoutSize:Vec2i
  72. Field _renderSize:Vec2i
  73. Method OnMeasureContent2:Vec2i( size:Vec2i ) Override
  74. If Not _document Return New Vec2i( 0,0 )
  75. If size.x=_layoutSize.x Return _renderSize
  76. _layoutSize=size
  77. _document.render( size.x )
  78. _renderSize=New Vec2i( _document.width(),_document.height() )
  79. Return _renderSize
  80. End
  81. Method OnRenderContent( canvas:Canvas ) Override
  82. If Not _document Return
  83. Local clip:litehtml.position
  84. clip.x=canvas.Scissor.X
  85. clip.y=canvas.Scissor.Y
  86. clip.width=canvas.Scissor.Width
  87. clip.height=canvas.Scissor.Height
  88. _document.draw( canvas,0,0,Varptr clip )
  89. End
  90. Method OnContentMouseEvent( event:MouseEvent ) Override
  91. If Not _document Return
  92. Local x:=event.Location.X
  93. Local y:=event.Location.Y
  94. _anchorClicked=""
  95. Select event.Type
  96. Case EventType.MouseDown
  97. _document.on_lbutton_down( x,y,x,y )
  98. Case EventType.MouseMove
  99. _document.on_mouse_over( x,y,x,y )
  100. Case EventType.MouseUp
  101. _document.on_lbutton_up( x,y,x,y )
  102. _document.on_mouse_leave()
  103. Case EventType.MouseWheel
  104. Return
  105. End
  106. event.Eat()
  107. RequestRender() 'Not ideal, but necessary for link highlighting...
  108. If _anchorClicked AnchorClicked( _anchorClicked )
  109. End
  110. End
  111. Class document_container Extends litehtml.document_container
  112. Field _view:HtmlView
  113. Global _fontScale:=1
  114. Global _imageCache:=New StringMap<Image>
  115. Method New( view:HtmlView )
  116. _view=view
  117. End
  118. Method set_color( canvas:Canvas,color:litehtml.web_color )
  119. canvas.Color=New Color( color.red/255.0,color.green/255.0,color.blue/255.0,1 )
  120. End
  121. Method make_url:String( href:String )
  122. Return _view._baseUrl+href
  123. End
  124. Method create_font:Object( faceName:String,size:Int,weight:Int,style:litehtml.font_style,decoration:UInt,fm:litehtml.font_metrics Ptr ) Override
  125. Local font:Font
  126. If faceName.Contains( "monospace" )
  127. font=Font.Open( "font::DejaVuSansMono.ttf",size )
  128. Else
  129. font=Font.Open( "font::DejaVuSans.ttf",size )
  130. Endif
  131. Local height:=size
  132. fm[0].height=height
  133. fm[0].ascent=height
  134. fm[0].descent=0
  135. fm[0].x_height=height
  136. fm[0].draw_spaces=True
  137. Return font
  138. End
  139. Method delete_font( font:Object ) Override
  140. End
  141. Method text_width:Int( text:String,hfont:Object ) Override
  142. Local font:=Cast<Font>( hfont )
  143. Return font.TextWidth( text ) * _fontScale
  144. End
  145. Method draw_text( hdc:Object,text:String,hfont:Object,color:litehtml.web_color Ptr,pos:litehtml.position Ptr ) Override
  146. Local canvas:=Cast<Canvas>( hdc )
  147. Local font:=Cast<Font>( hfont )
  148. canvas.Font=font
  149. set_color( canvas,color[0] )
  150. canvas.DrawText( text,pos[0].x,pos[0].y )
  151. Return
  152. #rem
  153. canvas.PushMatrix()
  154. canvas.Translate( pos[0].x,pos[0].y )
  155. canvas.Scale( _fontScale,1 )
  156. canvas.DrawText( text,0,0 )
  157. canvas.PopMatrix()
  158. #end
  159. End
  160. Method pt_to_px:Int( pt:Int ) Override
  161. Return 0
  162. End
  163. Method get_default_font_size:Int() Override
  164. Return 16
  165. End
  166. Method get_default_font_name:String() Override
  167. Return "mojo"
  168. End
  169. Method draw_list_marker( hdc:Object,marker:litehtml.list_marker Ptr ) Override
  170. If marker[0].marker_type=litehtml.list_style_type_none Return
  171. Local canvas:=Cast<Canvas>( hdc )
  172. set_color( canvas,marker[0].color )
  173. Select marker[0].marker_type
  174. Case litehtml.list_style_type_disc
  175. canvas.DrawOval( marker[0].pos.x,marker[0].pos.y,marker[0].pos.width,marker[0].pos.height )
  176. Default
  177. canvas.DrawRect( marker[0].pos.x,marker[0].pos.y,marker[0].pos.width,marker[0].pos.height )
  178. End
  179. End
  180. Method load_image( src:String,baseurl:String,redraw_on_ready:Bool ) Override
  181. If _imageCache.Contains( src ) Return
  182. Local image:=Image.Load( make_url( src ) )
  183. _imageCache.Set( src,image )
  184. End
  185. Method get_image_size( src:String,baseurl:String,sz:litehtml.size Ptr ) Override
  186. Local image:=_imageCache.Get( src )
  187. If Not image Return
  188. sz[0].width=image.Width
  189. sz[0].height=image.Height
  190. End
  191. Method draw_background( hdc:Object,img_src:String,img_baseurl:String,bg:litehtml.background_paint Ptr ) Override
  192. Local canvas:=Cast<Canvas>( hdc )
  193. Local image:=_imageCache.Get( img_src )
  194. If image
  195. canvas.Color=Color.White
  196. canvas.DrawImage( image,bg[0].position_x,bg[0].position_y )
  197. Return
  198. Endif
  199. set_color( canvas,bg[0].color )
  200. ' canvas.DrawRect( bg[0].clip_box.x,bg[0].clip_box.y,bg[0].clip_box.width,bg[0].clip_box.height )
  201. canvas.DrawRect( bg[0].border_box.x,bg[0].border_box.y,bg[0].border_box.width,bg[0].border_box.height )
  202. End
  203. Method draw_border( canvas:Canvas,border:litehtml.border,x:Int,y:Int,w:Int,h:Int )
  204. If border.style<>litehtml.border_style_solid Or border.width<1 Return
  205. set_color( canvas,border.color )
  206. canvas.DrawRect( x,y,w,h )
  207. End
  208. Method draw_borders( hdc:Object,borders:litehtml.borders Ptr,pos:litehtml.position Ptr,root:Bool ) Override
  209. Local canvas:=Cast<Canvas>( hdc )
  210. Local x:=pos[0].x,y:=pos[0].y
  211. Local w:=pos[0].width,h:=pos[0].height
  212. draw_border( canvas,borders[0].left,x,y,1,h )
  213. draw_border( canvas,borders[0].top,x,y,w,1 )
  214. draw_border( canvas,borders[0].right,x+w-1,y,1,h )
  215. draw_border( canvas,borders[0].bottom,x,y+h-1,w,1 )
  216. End
  217. Method set_caption( caption:String ) Override
  218. End
  219. Method set_base_url( baseurl:String ) Override
  220. End
  221. Method on_anchor_click( url:String ) Override
  222. _view._anchorClicked=url
  223. End
  224. Method set_cursor( cursor:String ) Override
  225. End
  226. Method import_css:String( url:String,baseurl:String ) Override
  227. Local css:=stringio.LoadString( make_url( url ) )
  228. Return css
  229. End
  230. Method set_clip( pos:litehtml.position Ptr,radiuses:litehtml.border_radiuses Ptr ) Override
  231. End
  232. Method del_clip() Override
  233. End
  234. Method get_client_rect( client:litehtml.position Ptr ) Override
  235. ' If _view._rendering Print "get client rect"
  236. client[0].x=0
  237. client[0].y=0
  238. client[0].width=_view._layoutSize.x
  239. client[0].height=_view._layoutSize.y
  240. End
  241. Method get_media_features( media:litehtml.media_features Ptr ) Override
  242. ' If _view._rendering Print "get media features"
  243. media[0].type=litehtml.media_type_screen
  244. media[0].width=_view._layoutSize.x
  245. media[0].height=_view._layoutSize.y
  246. media[0].device_width=1920
  247. media[0].device_height=1080
  248. media[0].color=8
  249. media[0].color_index=0
  250. media[0].monochrome=0
  251. media[0].resolution=96
  252. End
  253. Method get_language:String() Override
  254. Return ""
  255. End
  256. Method get_culture:String() Override
  257. Return ""
  258. End
  259. End