@@ -91,11 +91,11 @@ async function initCesium(): Promise<any> {
9191 // Disable Ion-dependent features
9292 geocoder : false ,
9393 baseLayerPicker : false ,
94- // Simplify UI
94+ // Simplify UI - hide all controls
9595 animation : false ,
9696 timeline : false ,
97- homeButton : true ,
98- sceneModePicker : true ,
97+ homeButton : false ,
98+ sceneModePicker : false ,
9999 navigationHelpButton : false ,
100100 fullscreenButton : false ,
101101 // Disable terrain (requires Ion)
@@ -245,21 +245,6 @@ function flyToBoundingBox(
245245 } ) ;
246246}
247247
248- /**
249- * Update the label display
250- */
251- function setLabel ( text : string | undefined ) : void {
252- const labelEl = document . getElementById ( "label" ) ;
253- if ( labelEl ) {
254- if ( text ) {
255- labelEl . textContent = text ;
256- labelEl . style . display = "block" ;
257- } else {
258- labelEl . style . display = "none" ;
259- }
260- }
261- }
262-
263248/**
264249 * Hide the loading indicator
265250 */
@@ -270,13 +255,86 @@ function hideLoading(): void {
270255 }
271256}
272257
258+ // Preferred height for inline mode (px)
259+ const PREFERRED_INLINE_HEIGHT = 400 ;
260+
261+ // Current display mode
262+ let currentDisplayMode : "inline" | "fullscreen" | "pip" = "inline" ;
263+
273264// Create App instance with tool capabilities
265+ // autoResize: false - we manually send size since map fills its container
274266const app = new App (
275267 { name : "CesiumJS Globe" , version : "1.0.0" } ,
276268 { tools : { listChanged : true } } ,
277- { autoResize : false } , // Cesium handles its own sizing
269+ { autoResize : false } ,
278270) ;
279271
272+ /**
273+ * Update fullscreen button visibility and icon based on current state
274+ */
275+ function updateFullscreenButton ( ) : void {
276+ const btn = document . getElementById ( "fullscreen-btn" ) ;
277+ const expandIcon = document . getElementById ( "expand-icon" ) ;
278+ const compressIcon = document . getElementById ( "compress-icon" ) ;
279+ if ( ! btn || ! expandIcon || ! compressIcon ) return ;
280+
281+ // Check if fullscreen is available from host
282+ const context = app . getHostContext ( ) ;
283+ const availableModes = context ?. availableDisplayModes ?? [ "inline" ] ;
284+ const canFullscreen = availableModes . includes ( "fullscreen" ) ;
285+
286+ // Show button only if fullscreen is available
287+ btn . style . display = canFullscreen ? "flex" : "none" ;
288+
289+ // Toggle icons based on current mode
290+ const isFullscreen = currentDisplayMode === "fullscreen" ;
291+ expandIcon . style . display = isFullscreen ? "none" : "block" ;
292+ compressIcon . style . display = isFullscreen ? "block" : "none" ;
293+ btn . title = isFullscreen ? "Exit fullscreen" : "Enter fullscreen" ;
294+ }
295+
296+ /**
297+ * Request display mode change from host
298+ */
299+ async function toggleFullscreen ( ) : Promise < void > {
300+ const targetMode =
301+ currentDisplayMode === "fullscreen" ? "inline" : "fullscreen" ;
302+ log . info ( "Requesting display mode:" , targetMode ) ;
303+
304+ try {
305+ const result = await app . requestDisplayMode ( { mode : targetMode } ) ;
306+ log . info ( "Display mode result:" , result . mode ) ;
307+ // Note: actual mode change will come via onhostcontextchanged
308+ } catch ( error ) {
309+ log . error ( "Failed to change display mode:" , error ) ;
310+ }
311+ }
312+
313+ /**
314+ * Handle display mode changes - resize Cesium and update UI
315+ */
316+ function handleDisplayModeChange (
317+ newMode : "inline" | "fullscreen" | "pip" ,
318+ ) : void {
319+ if ( newMode === currentDisplayMode ) return ;
320+
321+ log . info ( "Display mode changed:" , currentDisplayMode , "->" , newMode ) ;
322+ currentDisplayMode = newMode ;
323+
324+ // Update button state
325+ updateFullscreenButton ( ) ;
326+
327+ // Tell Cesium to resize to new container dimensions
328+ if ( viewer ) {
329+ // Small delay to let the host finish resizing
330+ setTimeout ( ( ) => {
331+ viewer . resize ( ) ;
332+ viewer . scene . requestRender ( ) ;
333+ log . info ( "Cesium resized for" , newMode , "mode" ) ;
334+ } , 100 ) ;
335+ }
336+ }
337+
280338// Register handlers BEFORE connecting
281339app . onteardown = async ( ) => {
282340 log . info ( "App is being torn down" ) ;
@@ -289,6 +347,22 @@ app.onteardown = async () => {
289347
290348app . onerror = log . error ;
291349
350+ // Listen for host context changes (display mode, theme, etc.)
351+ app . onhostcontextchanged = ( params ) => {
352+ log . info ( "Host context changed:" , params ) ;
353+
354+ if ( params . displayMode ) {
355+ handleDisplayModeChange (
356+ params . displayMode as "inline" | "fullscreen" | "pip" ,
357+ ) ;
358+ }
359+
360+ // Update button if available modes changed
361+ if ( params . availableDisplayModes ) {
362+ updateFullscreenButton ( ) ;
363+ }
364+ } ;
365+
292366// Handle initial tool input (bounding box from show-map tool)
293367app . ontoolinput = ( params ) => {
294368 log . info ( "Received tool input:" , params ) ;
@@ -339,7 +413,6 @@ app.ontoolinput = (params) => {
339413 Cesium . Math . toDegrees ( viewer ! . camera . pitch ) ,
340414 ) ;
341415 } ) ;
342- setLabel ( args ?. label ) ;
343416 } , 500 ) ;
344417 }
345418 }
@@ -411,6 +484,29 @@ async function init() {
411484 // Connect to host (auto-creates PostMessageTransport)
412485 await app . connect ( ) ;
413486 log . info ( "Connected to host" ) ;
487+
488+ // Get initial display mode from host context
489+ const context = app . getHostContext ( ) ;
490+ if ( context ?. displayMode ) {
491+ currentDisplayMode = context . displayMode as
492+ | "inline"
493+ | "fullscreen"
494+ | "pip" ;
495+ }
496+ log . info ( "Initial display mode:" , currentDisplayMode ) ;
497+
498+ // Tell host our preferred size for inline mode
499+ if ( currentDisplayMode === "inline" ) {
500+ app . sendSizeChanged ( { height : PREFERRED_INLINE_HEIGHT } ) ;
501+ log . info ( "Sent initial size:" , PREFERRED_INLINE_HEIGHT ) ;
502+ }
503+
504+ // Set up fullscreen button
505+ updateFullscreenButton ( ) ;
506+ const fullscreenBtn = document . getElementById ( "fullscreen-btn" ) ;
507+ if ( fullscreenBtn ) {
508+ fullscreenBtn . addEventListener ( "click" , toggleFullscreen ) ;
509+ }
414510 } catch ( error ) {
415511 log . error ( "Failed to initialize:" , error ) ;
416512 const loadingEl = document . getElementById ( "loading" ) ;
0 commit comments