1. global $
  2.  
  3. global g_wx
  4.  
  5. global g_hMenuMain
  6. global g_isDark
  7. global g_showStatusBar
  8. global g_coords
  9.  
  10. ----------------------------------------
  11. --
  12. ----------------------------------------
  13. on startMovie
  14.  
  15.     -- g_isDark = appsUseDarkTheme()
  16.     g_isDark = TRUE
  17.  
  18.     g_showStatusBar = TRUE
  19.     the floatPrecision = 8
  20.     _movie.puppetTempo(30)
  21.  
  22.     ----------------------------------------
  23.     -- Events/callbacks triggered by a scripting xtra (like in this case WebView xtra) fail silently
  24.     -- in case of scripting errors, so without error dialogs and debug support. This can be fixed
  25.     -- by "detaching" the events from the xtra callback using provided detacher lib.
  26.     ----------------------------------------
  27.     -- $.import("detacher")
  28.  
  29.     ----------------------------------------
  30.     -- This demo uses Lingo's value() function to parse the JSON 'args' strings received from JS,
  31.     -- since here args only contains arrays of numbers.
  32.     -- In other cases the included JSON decoder/encoder should be used instead.
  33.     ----------------------------------------
  34.     --  $.import("json")
  35.  
  36.     -- Some WinAPI constants we use
  37.     $["MOD_ALT"] = 1
  38.     $["MOD_CONTROL"] = 2
  39.     $["MOD_SHIFT"] = 4
  40.     $["VK_F1"] = 112
  41.     $["VK_F11"] = 122
  42.     $["MB_ICONINFORMATION"] = 64
  43.  
  44.     -- Our menu command IDs - arbitrary integers, they only have to be unique
  45.     $["IDM_OPEN"] = 1001
  46.     $["IDM_EXIT"] = 1002
  47.     $["IDM_SEARCH"] = 2001
  48.     $["IDM_SHOW_STATUSBAR"] = 3001
  49.     $["IDM_DARK_MODE"] = 3002
  50.     $["IDM_FULLSCREEN"] = 3003
  51.     $["IDM_SHOW_MEESAGE_WIN"] = 3004
  52.     $["IDM_ABOUT"] = 4001
  53.  
  54.     if g_isDark then
  55.         bg_color = rgb("#000000")
  56.     else
  57.         bg_color = rgb("#FFFFFF")
  58.     end if
  59.  
  60.     -- window settings
  61.     _movie.stage.title = "WebView Map Demo"
  62.     _movie.stage.titlebarOptions.visible = TRUE
  63.     _movie.stage.rect = rect(0, 0, 1280, 960)
  64.     _movie.stage.bgcolor = bg_color
  65.     _movie.stage.resizable = 1
  66.     _movie.centerStage = 1
  67.  
  68.     g_wx = xtra("WebView").new()
  69.  
  70.     if g_isDark then
  71.         g_wx.useDarkMode(g_isDark)
  72.     end if
  73.  
  74.     createMenu()
  75.  
  76.     g_wx.statusBarCreate(200)
  77.  
  78.     _movie.updateStage()
  79.  
  80.     -- IMPORTANT: window *must* be visible when calling webviewCreate()!
  81.     _movie.stage.visible = 1
  82.  
  83.     g_wx.webviewCreate(TRUE, 1, bg_color)
  84.     g_wx.webviewSetAutoSize()
  85.  
  86.     g_wx.webviewJSBind("OnKeyDown")
  87.     g_wx.webviewJSBind("OnMapChanged")
  88.  
  89.     g_wx.webviewNavigate("https://59de44955ebd.github.io/map/?nofullscreen")
  90.  
  91.     ----------------------------------------
  92.     -- Unfortunately WebView2 doesn't forward key events to the host application,
  93.     -- so we have to handle key events manually in JS to make our menu shortcuts
  94.     -- work also when the WebView has keyboard focus.
  95.     ----------------------------------------
  96.     g_wx.webviewJSEval("window.addEventListener('keydown', (e) => {if(e.ctrlKey)e.preventDefault();window.OnKeyDown(e.keyCode, +e.altKey, +e.ctrlKey, +e.shiftKey)});")
  97. end
  98.  
  99. ----------------------------------------
  100. -- This is required when running the movie in Director, i.e. in the authoring IDE
  101. ----------------------------------------
  102. --on stopMovie
  103. --  if not voidP(g_wx) then
  104. --      g_wx.forget()
  105. --      g_wx = VOID
  106. --  end if
  107. --end
  108.  
  109. ----------------------------------------
  110. --
  111. ----------------------------------------
  112. on createMenu
  113.     g_hMenuMain = g_wx.createMenu()
  114.  
  115.     hSubmenu = g_wx.insertSubMenu(g_hMenuMain, -1, "&File")
  116.     g_wx.insertMenuItem(hSubmenu, -1, "&Load GPX File..." & TAB & "Ctrl+O", $.IDM_OPEN, chartonum("O"), $.MOD_CONTROL)
  117.     g_wx.insertSeparator(hSubmenu, -1)
  118.     g_wx.insertMenuItem(hSubmenu, -1, "&Exit" & TAB & "Ctrl+Q", $.IDM_EXIT, chartonum("Q"), $.MOD_CONTROL)
  119.     hSubmenu = g_wx.insertSubMenu(g_hMenuMain, -1, "&Edit")
  120.     g_wx.insertMenuItem(hSubmenu, -1, "&Search..." & TAB & "Ctrl+F", $.IDM_SEARCH, chartonum("F"), $.MOD_CONTROL)
  121.  
  122.     hSubmenu = g_wx.insertSubMenu(g_hMenuMain, -1, "&View")
  123.     g_wx.insertMenuItem(hSubmenu, -1, "&StatusBar" & TAB & "Alt+S", $.IDM_SHOW_STATUSBAR, chartonum("S"), $.MOD_ALT)
  124.     if g_showStatusBar then g_wx.checkMenuItem(g_hMenuMain, $.IDM_SHOW_STATUSBAR, TRUE)
  125.     g_wx.insertMenuItem(hSubmenu, -1, "&Dark Mode" & TAB & "Alt+D", $.IDM_DARK_MODE, chartonum("D"), $.MOD_ALT)
  126.     if g_isDark then g_wx.checkMenuItem(g_hMenuMain, $.IDM_DARK_MODE, TRUE)
  127.     g_wx.insertMenuItem(hSubmenu, -1, "&Fullscreen" & TAB & "F11", $.IDM_FULLSCREEN, $.VK_F11)
  128.     g_wx.insertSeparator(hSubmenu, -1)
  129.     g_wx.insertMenuItem(hSubmenu, -1, "Show &Message Window" & TAB & "Ctrl+M", $.IDM_SHOW_MEESAGE_WIN, chartonum("M"), $.MOD_CONTROL)
  130.  
  131.     hSubmenu = g_wx.insertSubMenu(g_hMenuMain, -1, "&Help")
  132.     g_wx.insertMenuItem(hSubmenu, -1, "&About" & TAB & "F1", $.IDM_ABOUT, $.VK_F1)
  133.  
  134.     g_wx.setMainMenu(g_hMenuMain)
  135. end
  136.  
  137. ----------------------------------------
  138. --
  139. ----------------------------------------
  140. on loadGPX
  141.     g_wx.webviewJSEval("document.querySelector('.leaflet-control-filelayer a').click();")
  142. end
  143.  
  144. ----------------------------------------
  145. --
  146. ----------------------------------------
  147. on toggleStatusBar
  148.     g_showStatusBar = not g_showStatusBar
  149.     g_wx.checkMenuItem(g_hMenuMain, 3001, g_showStatusBar)
  150.     g_wx.statusBarShow(g_showStatusBar)
  151. end
  152.  
  153. ----------------------------------------
  154. --
  155. ----------------------------------------
  156. on toggleDarkMode
  157.     g_isDark = not g_isDark
  158.     g_wx.checkMenuItem(g_hMenuMain, 3002, g_isDark)
  159.     g_wx.useDarkMode(g_isDark)
  160. end
  161.  
  162. ----------------------------------------
  163. --
  164. ----------------------------------------
  165. on toggleSearch
  166.     g_wx.webviewJSEval("document.querySelector('.search-button').click();")
  167. end
  168.  
  169. ----------------------------------------
  170. --
  171. ----------------------------------------
  172. on about
  173.     g_wx.ShowMessageBox("WebView Map Demo v1.0            "&RETURN&"(c) 2025 59de44955ebd", "About", $.MB_ICONINFORMATION)
  174.     -- After showing messagebox return mouse/keyboard focus to webview
  175.     g_wx.webviewSetFocus()
  176. end
  177.  
  178. ----------------------------------------
  179. -- @callback
  180. -- Called from browser JS in webview
  181. ----------------------------------------
  182. on OnKeyDown (args)
  183.     -- args: "[keyCode, altKey, ctrlKey, shiftKey]", all integers, so we can use value() to convert to Lingo list
  184.     args = value(args)
  185.     -- To avoid repeating code we just forward to OnCommand()
  186.     case TRUE of
  187.         (args[1] = chartonum("O") and args[3]): OnCommand($.IDM_OPEN)
  188.         (args[1] = chartonum("Q") and args[3]): OnCommand($.IDM_EXIT)
  189.         (args[1] = chartonum("F") and args[3]): OnCommand($.IDM_SEARCH)
  190.         (args[1] = chartonum("S") and args[2]): OnCommand($.IDM_SHOW_STATUSBAR)
  191.         (args[1] = chartonum("D") and args[2]): OnCommand($.IDM_DARK_MODE)
  192.         (args[1] = $.VK_F11): OnCommand($.IDM_FULLSCREEN)
  193.         (args[1] = chartonum("M") and args[3]): OnCommand($.IDM_SHOW_MEESAGE_WIN)
  194.         (args[1] = $.VK_F1): OnCommand($.IDM_ABOUT)
  195.     end case
  196. end
  197.  
  198. ----------------------------------------
  199. -- @callback
  200. -- Called from browser JS in webview
  201. ----------------------------------------
  202. on OnMapChanged (args)
  203.     -- args: "[zoom, lat, lon]", all integers or floats, so we can use value() to convert to Lingo list
  204.     g_coords = value(args)
  205.     g_wx.statusBarMsg(g_coords[1] & " / " & g_coords[2] & " / " & g_coords[3] , 1)
  206. end
  207.  
  208. ----------------------------------------
  209. -- @callback
  210. -- Called from WebView xtra
  211. ----------------------------------------
  212. on OnStatusBarClicked (isRightClick, sectionNum)
  213.     if sectionNum <> 1 or voidP(g_coords) then return
  214.     if isRightClick then
  215.         hMenu = g_wx.createPopupMenu()
  216.         g_wx.insertMenuItem(hMenu, -1, "Copy to Clipboard", 1)
  217.         g_wx.insertSeparator(hMenu, -1)
  218.         g_wx.insertMenuItem(hMenu, -1, "Open in Mapswitcher", 2)
  219.         cmdID = g_wx.showPopupMenu(hMenu)
  220.         g_wx.destroyMenu(hMenu)
  221.         if cmdID = 1 then
  222.             m = new(#field)
  223.             m.text = g_coords[1] & "/" & g_coords[2] & "/" & g_coords[3]
  224.             m.copyToClipboard()
  225.             m.erase()
  226.         end if
  227.         if cmdID <> 2 then return
  228.     end if
  229.     -- Open mapswitcher with current map coords in the user's default browser
  230.     u = "https://59de44955ebd.github.io/mapswitcher/#https://www.google.com/maps/@" & g_coords[2] & "," & g_coords[3] & "," & g_coords[1] & "z"
  231.     open QUOTE & u & QUOTE, "C:\windows\explorer.exe"
  232. end
  233.  
  234. ----------------------------------------
  235. -- @callback
  236. -- Called from WebView xtra
  237. ----------------------------------------
  238. on OnCommand (cmdID)
  239.     case cmdID of
  240.         ($.IDM_OPEN): loadGPX()
  241.         ($.IDM_EXIT): _player.quit()
  242.         ($.IDM_SEARCH): toggleSearch()
  243.         ($.IDM_SHOW_STATUSBAR): toggleStatusBar()
  244.         ($.IDM_DARK_MODE): toggleDarkMode()
  245.         ($.IDM_FULLSCREEN): g_wx.webviewToggleFullScreen()
  246.         ($.IDM_SHOW_MEESAGE_WIN):
  247.             _player.debugPlaybackEnabled = 1
  248.             printMsg xtra("WebView").interface() & "\n"
  249.         ($.IDM_ABOUT): about()
  250.     end case
  251. end
  252.  
  253. ----------------------------------------
  254. -- @callback
  255. -- Called from WebView xtra
  256. -- Alternative using detacher to make callback showing errors and allow debugging
  257. ----------------------------------------
  258. --on OnCommand (cmdID)
  259. --  $.detacher.detach(#OnCommandDetached, _movie, cmdID)
  260. --end
  261.  
  262. ----------------------------------------
  263. --
  264. ----------------------------------------
  265. --on OnCommandDetached (cmdID)
  266. --  ...
  267. --end
  268.  
[raw code]