Skip to content
Snippets Groups Projects
util.ts 7.06 KiB
Newer Older
Xiao Gui's avatar
Xiao Gui committed
import { InjectionToken } from '@angular/core'
import { Observable, pipe } from 'rxjs'
import { filter, scan, take } from 'rxjs/operators'
Xiao Gui's avatar
Xiao Gui committed
import { getExportNehuba, getViewer } from 'src/util/fn'
Xiao Gui's avatar
Xiao Gui committed
import { NehubaViewerUnit } from './nehubaViewer/nehubaViewer.component'
import { userInterface } from 'src/state'
Xiao Gui's avatar
Xiao Gui committed
const flexContCmnCls = ['w-100', 'h-100', 'd-flex', 'justify-content-center', 'align-items-stretch']

Xiao Gui's avatar
Xiao Gui committed
const makeRow = (...els: HTMLElement[]) => {
Xiao Gui's avatar
Xiao Gui committed
  const container = document.createElement('div')
  container.classList.add(...flexContCmnCls, 'flex-row')
Xiao Gui's avatar
Xiao Gui committed
  for (const el of els) {
Xiao Gui's avatar
Xiao Gui committed
    container.appendChild(el)
  }
  return container
}

Xiao Gui's avatar
Xiao Gui committed
const makeCol = (...els: HTMLElement[]) => {
Xiao Gui's avatar
Xiao Gui committed
  const container = document.createElement('div')
  container.classList.add(...flexContCmnCls, 'flex-column')
Xiao Gui's avatar
Xiao Gui committed
  for (const el of els) {
Xiao Gui's avatar
Xiao Gui committed
    container.appendChild(el)
  }
  return container
}

Xiao Gui's avatar
Xiao Gui committed
const washPanels = (panels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement]) => {
  for (const panel of panels) {
    if (panel) { panel.className = `position-relative` }
  }
  return panels
}
const top = true
const left = true
const right = true
const bottom = true

const mapModeIdxClass = new Map<
  userInterface.PanelMode, Map<number,{
    top?: boolean
    bottom?: boolean
    left?: boolean
    right?: boolean
  }>
>()
mapModeIdxClass.set("FOUR_PANEL", new Map([
  [0, { top, left }],
  [1, { top, right }],
  [2, { bottom, left }],
Xiao Gui's avatar
Xiao Gui committed
  [3, { right, bottom }],
mapModeIdxClass.set("SINGLE_PANEL", new Map([
  [0, { top, left, right, bottom }],
  [1, {}],
  [2, {}],
Xiao Gui's avatar
Xiao Gui committed
  [3, {}],
mapModeIdxClass.set("PIP_PANEL", new Map([
  [0, { top, left, right, bottom }],
  [1, {}],
  [2, {}],
  [3, {}],
]))

mapModeIdxClass.set("H_ONE_THREE", new Map([
  [0, { top, left, bottom }],
  [1, { top, right }],
  [2, { right }],
Xiao Gui's avatar
Xiao Gui committed
  [3, { bottom, right }],
mapModeIdxClass.set("V_ONE_THREE", new Map([
  [0, { top, left, right }],
  [1, { bottom, left }],
  [2, { bottom }],
Xiao Gui's avatar
Xiao Gui committed
  [3, { bottom, right }],
Xiao Gui's avatar
Xiao Gui committed
type PanelTouchSide = 'left' | 'right' | 'top' | 'bottom'
/**
 * gives a clue of the approximate location of the panel, allowing position of checkboxes/scale bar to be placed in unobtrustive places
 */
Xiao Gui's avatar
Xiao Gui committed
export const panelTouchSide = (panel: HTMLElement, { top: touchTop, left: touchLeft, right: touchRight, bottom: touchBottom }: Partial<Record<PanelTouchSide, boolean>>): HTMLElement => {
Xiao Gui's avatar
Xiao Gui committed
  if (touchTop) { panel.classList.add(`touch-top`) }
  if (touchLeft) { panel.classList.add(`touch-left`) }
  if (touchRight) { panel.classList.add(`touch-right`) }
  if (touchBottom) { panel.classList.add(`touch-bottom`) }
Xiao Gui's avatar
Xiao Gui committed
export const addTouchSideClasses = (panel: HTMLElement, actualOrderIndex: number, panelMode: userInterface.PanelMode): HTMLElement => {
Xiao Gui's avatar
Xiao Gui committed

  if (actualOrderIndex < 0) { return panel }

  const mapIdxClass = mapModeIdxClass.get(panelMode)
Xiao Gui's avatar
Xiao Gui committed
  if (!mapIdxClass) { return panel }

  const classArg = mapIdxClass.get(actualOrderIndex)
Xiao Gui's avatar
Xiao Gui committed
  if (!classArg) { return panel }

  return panelTouchSide(panel, classArg)
}
Xiao Gui's avatar
Xiao Gui committed
export const getHorizontalOneThree = (panels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement]): HTMLElement => {
Xiao Gui's avatar
Xiao Gui committed
  washPanels(panels)
  panels.forEach((panel, idx) => addTouchSideClasses(panel, idx, "H_ONE_THREE"))
Xiao Gui's avatar
Xiao Gui committed

Xiao Gui's avatar
Xiao Gui committed
  const majorContainer = makeCol(panels[0])
  const minorContainer = makeCol(panels[1], panels[2], panels[3])

  majorContainer.style.flexBasis = '67%'
  minorContainer.style.flexBasis = '33%'
Xiao Gui's avatar
Xiao Gui committed

Xiao Gui's avatar
Xiao Gui committed
  return makeRow(majorContainer, minorContainer)
}

Xiao Gui's avatar
Xiao Gui committed
export const getVerticalOneThree = (panels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement]): HTMLDivElement => {
Xiao Gui's avatar
Xiao Gui committed
  washPanels(panels)
Xiao Gui's avatar
Xiao Gui committed

  panels.forEach((panel, idx) => addTouchSideClasses(panel, idx, "V_ONE_THREE"))
Xiao Gui's avatar
Xiao Gui committed
  const majorContainer = makeRow(panels[0])
  const minorContainer = makeRow(panels[1], panels[2], panels[3])

  majorContainer.style.flexBasis = '67%'
  minorContainer.style.flexBasis = '33%'
Xiao Gui's avatar
Xiao Gui committed

Xiao Gui's avatar
Xiao Gui committed
  return makeCol(majorContainer, minorContainer)
}

Xiao Gui's avatar
Xiao Gui committed
export const getFourPanel = (panels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement]): HTMLDivElement => {
Xiao Gui's avatar
Xiao Gui committed
  washPanels(panels)
Xiao Gui's avatar
Xiao Gui committed

  panels.forEach((panel, idx) => addTouchSideClasses(panel, idx, "FOUR_PANEL"))
Xiao Gui's avatar
Xiao Gui committed
  const majorContainer = makeRow(panels[0], panels[1])
  const minorContainer = makeRow(panels[2], panels[3])

  majorContainer.style.flexBasis = '50%'
  minorContainer.style.flexBasis = '50%'
Xiao Gui's avatar
Xiao Gui committed

Xiao Gui's avatar
Xiao Gui committed
  return makeCol(majorContainer, minorContainer)
}

export const getSinglePanel = (panels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement]): HTMLDivElement => {
Xiao Gui's avatar
Xiao Gui committed
  washPanels(panels)

  return getFullViewPanel(panels)
}

export const getPipPanel = (panels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement]): HTMLDivElement => {
Xiao Gui's avatar
Xiao Gui committed
  washPanels(panels)
  
  return getFullViewPanel(panels)
}

const getFullViewPanel = (panels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement]): HTMLDivElement => {
Xiao Gui's avatar
Xiao Gui committed

  panels.forEach((panel, idx) => addTouchSideClasses(panel, idx, "SINGLE_PANEL"))
Xiao Gui's avatar
Xiao Gui committed
  const majorContainer = makeRow(panels[0])
  majorContainer.style.flexBasis = '100%'

  const minorContainer = makeRow(panels[1], panels[2], panels[3])
  minorContainer.style.flexBasis = '0%'
  minorContainer.className = ''
Daviti Gogshelidze's avatar
Daviti Gogshelidze committed

  return makeRow(majorContainer, minorContainer)
Xiao Gui's avatar
Xiao Gui committed
export const isIdentityQuat = (ori: number[]): boolean => Math.abs(ori[0]) < 1e-6
  && Math.abs(ori[1]) < 1e-6
  && Math.abs(ori[2]) < 1e-6
  && Math.abs(ori[3] - 1) < 1e-6
Xiao Gui's avatar
Xiao Gui committed
export const importNehubaFactory = (appendSrc: (src: string) => Promise<void>): () => Promise<void> => {
  let pr: Promise<void>
  return () => {
Xiao Gui's avatar
Xiao Gui committed
    if (getExportNehuba()) return Promise.resolve()
    pr = appendSrc('main.bundle.js')
export const takeOnePipe = () => {

  return pipe(
    scan((acc: Event[], event: Event) => {
      const target = (event as Event).target as HTMLElement
      /**
       * 0 | 1
       * 2 | 3
       *
       * 4 ???
       */
      const panels = getViewer()['display']['panels']
      const panelEls = Array.from(panels).map(({ element }) => element)

      const identifySrcElement = (element: HTMLElement) => {
        const idx = panelEls.indexOf(element)
        return idx
      }

      const key = identifySrcElement(target)
      const _ = {}
      _[key] = event
      return Object.assign({}, acc, _)
    }, []),
    filter(v => {
      const isdefined = (obj) => typeof obj !== 'undefined' && obj !== null
      return (isdefined(v[0]) && isdefined(v[1]) && isdefined(v[2]))
    }),
    take(1),
  )
}
Xiao Gui's avatar
Xiao Gui committed
export const NEHUBA_INSTANCE_INJTKN = new InjectionToken<Observable<NehubaViewerUnit>>('NEHUBA_INSTANCE_INJTKN')

Xiao Gui's avatar
Xiao Gui committed
export function serializeSegment(ngId: string, label: number | string): string{
Xiao Gui's avatar
Xiao Gui committed
  return `${ngId}#${label}`
}

Xiao Gui's avatar
Xiao Gui committed
export function deserializeSegment(id: string): {ngId: string, label: number} {
Xiao Gui's avatar
Xiao Gui committed
  const split = id.split('#')
  if (split.length !== 2) {
    throw new Error(`deserializeSegment error at ${id}. expecting splitting # to result in length 2, got ${split.length}`)
  }
  if (isNaN(Number(split[1]))) {
    throw new Error(`deserializeSegment error at ${id}. expecting second element to be numberable. It was not.`)
  }
  return {
    ngId: split[0],
    label: Number(split[1])
  }
}