@@ -52,7 +52,8 @@ import '@material/mwc-dialog';
5252import '@material/mwc-switch' ;
5353import '@material/mwc-select' ;
5454import '@material/mwc-textfield' ;
55- import { EditCompletedEvent } from '@openscd/core' ;
55+ import { nothing } from 'lit' ;
56+
5657
5758@customElement ( 'oscd-layout' )
5859export class OscdLayout extends LitElement {
@@ -61,6 +62,8 @@ export class OscdLayout extends LitElement {
6162 return html `
6263 <div
6364 @open-plugin-download = ${ ( ) => this . pluginDownloadUI . show ( ) }
65+ @oscd-activate-editor = ${ this . handleActivateEditorByEvent }
66+ @oscd-run-menu = ${ this . handleRunMenuByEvent }
6467 >
6568 <slot> </ slot>
6669 ${ this . renderHeader ( ) } ${ this . renderAside ( ) } ${ this . renderContent ( ) }
@@ -155,6 +158,7 @@ export class OscdLayout extends LitElement {
155158 } ,
156159 disabled : ( ) : boolean => ! this . historyState . canUndo ,
157160 kind : 'static' ,
161+ content : ( ) => html `` ,
158162 } ,
159163 {
160164 icon : 'redo' ,
@@ -165,6 +169,7 @@ export class OscdLayout extends LitElement {
165169 } ,
166170 disabled : ( ) : boolean => ! this . historyState . canRedo ,
167171 kind : 'static' ,
172+ content : ( ) => html `` ,
168173 } ,
169174 ...validators ,
170175 {
@@ -175,6 +180,7 @@ export class OscdLayout extends LitElement {
175180 this . dispatchEvent ( newHistoryUIEvent ( true , HistoryUIKind . log ) ) ;
176181 } ,
177182 kind : 'static' ,
183+ content : ( ) => html `` ,
178184 } ,
179185 {
180186 icon : 'history' ,
@@ -184,6 +190,7 @@ export class OscdLayout extends LitElement {
184190 this . dispatchEvent ( newHistoryUIEvent ( true , HistoryUIKind . history ) ) ;
185191 } ,
186192 kind : 'static' ,
193+ content : ( ) => html `` ,
187194 } ,
188195 {
189196 icon : 'rule' ,
@@ -193,6 +200,7 @@ export class OscdLayout extends LitElement {
193200 this . dispatchEvent ( newHistoryUIEvent ( true , HistoryUIKind . diagnostic ) ) ;
194201 } ,
195202 kind : 'static' ,
203+ content : ( ) => html `` ,
196204 } ,
197205 'divider' ,
198206 ...middleMenu ,
@@ -203,13 +211,15 @@ export class OscdLayout extends LitElement {
203211 this . dispatchEvent ( newSettingsUIEvent ( true ) ) ;
204212 } ,
205213 kind : 'static' ,
214+ content : ( ) => html `` ,
206215 } ,
207216 ...bottomMenu ,
208217 {
209218 icon : 'extension' ,
210219 name : 'plugins.heading' ,
211220 action : ( ) : void => this . pluginUI . show ( ) ,
212221 kind : 'static' ,
222+ content : ( ) => html `` ,
213223 } ,
214224 ] ;
215225 }
@@ -333,7 +343,10 @@ export class OscdLayout extends LitElement {
333343 ) ;
334344 } ,
335345 disabled : ( ) : boolean => plugin . requireDoc ! && this . doc === null ,
336- content : plugin . content ,
346+ content : ( ) => {
347+ if ( plugin . content ) { return plugin . content ( ) ; }
348+ return html `` ;
349+ } ,
337350 kind : kind ,
338351 }
339352 } )
@@ -358,29 +371,32 @@ export class OscdLayout extends LitElement {
358371 ) ;
359372 } ,
360373 disabled : ( ) : boolean => this . doc === null ,
361- content : plugin . content ,
374+ content : plugin . content ?? ( ( ) => html `` ) ,
362375 kind : 'validator' ,
363376 }
364377 } ) ;
365378 }
366379
367380 private renderMenuItem ( me : MenuItem | 'divider' ) : TemplateResult {
368- if ( me === 'divider' ) { return html `<li divider padded role = "separator" > < / li > ` ; }
369- if ( me . actionItem ) { return html `` ; }
381+ const isDivider = me === 'divider' ;
382+ const hasActionItem = me !== 'divider' && me . actionItem ;
370383
384+ if ( isDivider ) { return html `<li divider padded role= "separator" > </ li> ` ; }
385+ if ( hasActionItem ) { return html `` ; }
371386 return html `
372387 <mwc- lis t- item
373388 class= "${ me . kind } "
374389 iconid = "${ me . icon } "
375390 graphic = "icon"
391+ data-name = "${ me . name } "
376392 .disabled = ${ me . disabled ?.( ) || ! me . action }
377393 > <mwc- icon slot= "graphic" > ${ me . icon } </ mwc- icon>
378394 <span> ${ get ( me . name ) } </ span>
379395 ${ me . hint
380396 ? html `<span slot= "secondary" > <tt> ${ me . hint } </ tt> </ span> `
381397 : '' }
382398 </ mwc- lis t- item>
383- ${ me . content ?? '' }
399+ ${ me . content ? me . content ( ) : nothing }
384400 ` ;
385401 }
386402
@@ -456,24 +472,32 @@ export class OscdLayout extends LitElement {
456472
457473 }
458474
475+ private calcActiveEditors ( ) {
476+ const hasActiveDoc = Boolean ( this . doc ) ;
477+
478+ return this . editors
479+ . filter ( editor => {
480+ // this is necessary because `requireDoc` can be undefined
481+ // and that is not the same as false
482+ const doesNotRequireDoc = editor . requireDoc === false
483+ return doesNotRequireDoc || hasActiveDoc
484+ } )
485+ }
486+
459487 /** Renders the enabled editor plugins and a tab bar to switch between them*/
460488 protected renderContent ( ) : TemplateResult {
461- const hasActiveDoc = Boolean ( this . doc ) ;
462489
463- const activeEditors = this . editors
464- . filter ( editor => {
465- // this is necessary because `requireDoc` can be undefined
466- // and that is not the same as false
467- const doesNotRequireDoc = editor . requireDoc === false
468- return doesNotRequireDoc || hasActiveDoc
469- } )
470- . map ( this . renderEditorTab )
490+ const activeEditors = this . calcActiveEditors ( )
491+ . map ( this . renderEditorTab )
471492
472493 const hasActiveEditors = activeEditors . length > 0 ;
473494 if ( ! hasActiveEditors ) { return html `` ; }
474495
475496 return html `
476- <mwc- tab- bar @MDCTabBar : activated= ${ ( e : CustomEvent ) => ( this . activeTab = e . detail . index ) } >
497+ <mwc- tab- bar
498+ @MDCTabBar : activated= ${ this . handleActivatedEditorTabByUser }
499+ activeIndex= ${ this . activeTab }
500+ >
477501 ${ activeEditors }
478502 </ mwc- tab- bar>
479503 ${ renderEditorContent ( this . editors , this . activeTab , this . doc ) }
@@ -487,10 +511,39 @@ export class OscdLayout extends LitElement {
487511 const content = editor ?. content ;
488512 if ( ! content ) { return html `` }
489513
490- return html `${ content } ` ;
514+ return html `${ content ( ) } ` ;
491515 }
492516 }
493517
518+ private handleActivatedEditorTabByUser ( e : CustomEvent ) : void {
519+ const tabIndex = e . detail . index ;
520+ this . activateTab ( tabIndex ) ;
521+ }
522+
523+ private handleActivateEditorByEvent ( e : CustomEvent < { name : string , src : string } > ) : void {
524+ const { name, src} = e . detail ;
525+ const editors = this . calcActiveEditors ( )
526+ const wantedEditorIndex = editors . findIndex ( editor => editor . name === name || editor . src === src )
527+ if ( wantedEditorIndex < 0 ) { return ; } // TODO: log error
528+
529+ this . activateTab ( wantedEditorIndex ) ;
530+ }
531+
532+ private activateTab ( index : number ) {
533+ this . activeTab = index ;
534+ }
535+
536+ private handleRunMenuByEvent ( e : CustomEvent < { name : string } > ) : void {
537+
538+ // TODO: this is a workaround, fix it
539+ this . menuUI . open = true ;
540+ const menuEntry = this . menuUI . querySelector ( `[data-name="${ e . detail . name } "]` ) as HTMLElement
541+ const menuElement = menuEntry . nextElementSibling
542+ if ( ! menuElement ) { return ; } // TODO: log error
543+
544+ ( menuElement as unknown as MenuPlugin ) . run ( )
545+ }
546+
494547 /**
495548 * Renders the landing buttons (open project and new project)
496549 * it no document loaded we display the menu item that are in the position
0 commit comments