import { BeEvent , compareBooleans , compareStrings , Id64 , Id64String , SortedArray } from "@itwin/core-bentley" ; import { ColorDef } from "@itwin/core-common" ; import { IModelConnection , SpatialViewState , ViewState } from "@itwin/core-frontend" ; interface ViewSpec extends IModelConnection . ViewSpec { isPrivate : boolean ; } export class ViewList extends SortedArray < ViewSpec > { private _defaultViewId = Id64 . invalid ; private readonly _views = new Map < Id64String , ViewState > ( ) ; private constructor ( ) { super ( ( lhs , rhs ) => { let cmp = compareBooleans ( lhs . isPrivate , rhs . isPrivate ) ; if ( 0 === cmp ) { cmp = compareStrings ( lhs . name , rhs . name ) ; if ( 0 === cmp ) cmp = compareStrings ( lhs . id , rhs . id ) ; } return cmp ; } ) ; } public get defaultViewId ( ) : Id64String { return this . _defaultViewId ; } public async getView ( id , iModel ) { let view = this . _views . get ( id ) ; if ( undefined === view ) { try { view = await iModel . views . load ( id ) ; } catch { view = this . manufactureSpatialView ( iModel ) ; } this . _views . set ( id , view ) ; } return view . clone ( ) ; } public async getDefaultView ( iModel ) { return this . getView ( this . defaultViewId , iModel ) ; } public static async create ( iModel , viewName ? ) { const viewList = new ViewList ( ) ; await viewList . populate ( iModel , viewName ) ; return viewList ; } public override clear ( ) { super . clear ( ) ; this . _defaultViewId = Id64 . invalid ; this . _views . clear ( ) ; } public async populate ( iModel , viewName ? ) { this . clear ( ) ; let specs = await iModel . views . getViewList ( { wantPrivate : false } ) ; for ( const spec of specs ) this . insert ( { ... spec , isPrivate : false } ) ; const nSpecs = specs . length ; specs = await iModel . views . getViewList ( { wantPrivate : true } ) ; if ( specs . length > nSpecs ) { for ( const spec of specs ) { const entry = { ... spec , isPrivate : false } ; if ( ! this . findEqual ( entry ) ) { entry . isPrivate = true ; this . insert ( entry ) ; } } } if ( undefined !== viewName ) { for ( const spec of this ) { if ( spec . name === viewName ) { this . _defaultViewId = spec . id ; break ; } } } if ( Id64 . isInvalid ( this . _defaultViewId ) && 0 < this . _array . length ) { this . _defaultViewId = this . _array [ 0 ] . id ; const defaultViewId = await iModel . views . queryDefaultViewId ( ) ; for ( const spec of this ) { if ( spec . id === defaultViewId ) { this . _defaultViewId = defaultViewId ; break ; } } } if ( Id64 . isInvalid ( this . _defaultViewId ) ) this . insert ( { id : Id64 . invalid , name : "Spatial View" , class : SpatialViewState . classFullName , isPrivate : false } ) ; await this . getView ( this . _defaultViewId , iModel ) ; } private manufactureSpatialView ( iModel ) { const ext = iModel . projectExtents ; const blankView = SpatialViewState . createBlank ( iModel , ext . low , ext . high . minus ( ext . low ) ) ; const style = blankView . displayStyle ; style . viewFlags = style . viewFlags . with ( "backgroundMap" , true ) ; style . backgroundColor = ColorDef . white ; style . environment = style . environment . withDisplay ( { sky : true } ) ; return blankView ; } } export class ViewPicker { private readonly _select : HTMLSelectElement ; public readonly onSelectedViewChanged = new BeEvent < ( viewId : Id64String ) => void > ( ) ; public get element ( ) : HTMLElement { return this . _select ; } public constructor ( parent , views ) { this . _select = document . createElement ( "select" ) ; this . _select . className = "viewList" ; this . _select . onchange = ( ) => this . onSelectedViewChanged . raiseEvent ( this . _select . value ) ; parent . appendChild ( this . _select ) ; this . populate ( views ) ; } public populate ( views ) { while ( this . _select . hasChildNodes ( ) ) this . _select . removeChild ( this . _select . firstChild ! ) ; let index = 0 ; for ( const spec of views ) { const option = document . createElement ( "option" ) ; option . innerText = spec . name ; option . value = spec . id ; this . _select . appendChild ( option ) ; if ( spec . id === views . defaultViewId ) this . _select . selectedIndex = index ; index ++ ; } } }