Skip to content

Commit

Permalink
Merge pull request #87 from andrewisen-tikab/feature
Browse files Browse the repository at this point in the history
Add `settings` drawer
  • Loading branch information
andrewisen-tikab authored Oct 5, 2023
2 parents 61eb373 + b9f4564 commit 7f549ea
Show file tree
Hide file tree
Showing 11 changed files with 491 additions and 103 deletions.
3 changes: 2 additions & 1 deletion example/react/components/FlexLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Three from './Three';
import Issues from './Issues';
import IssueSorter from './IssueSorter';
import IssueDetails from './IssueDetails';
import Settings from './Settings';

function LeftFlexLayout() {
return <Issues />;
Expand All @@ -24,7 +25,7 @@ function RightTopFlexLayout() {
<Panel title="Issue details" sx={{ flexBasis: '50%', overflowY: 'scroll' }}>
<IssueDetails />
</Panel>
<Panel title="3D" sx={{ flexBasis: '50%' }}>
<Panel title="3D" sx={{ flexBasis: '50%' }} action={<Settings />}>
<Three />
</Panel>
</Box>
Expand Down
151 changes: 151 additions & 0 deletions example/react/components/Settings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import React, { useState } from 'react';
import { useSelector } from 'react-redux';

import SettingsIcon from '@mui/icons-material/Settings';
import Box from '@mui/material/Box';

import Button from '@mui/material/Button';
import Drawer from '@mui/material/Drawer';
import CardContent from '@mui/material/CardContent';
import Typography from '@mui/material/Typography';

import SettingsTwoToneIcon from '@mui/icons-material/SettingsTwoTone';
import Panel from './Panel';

import { DataGrid } from '@mui/x-data-grid';
import type { GridRenderCellParams, GridColDef, GridRowSelectionModel } from '@mui/x-data-grid';
import Checkbox from '@mui/material/Checkbox';

import VisibilityIcon from '@mui/icons-material/Visibility';
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
import { RootState } from '../state/store';
import { IFCSomething } from '../../types';
import BCFViewer from '../../viewer/BCFViewer';

function RenderCheckBox(props: GridRenderCellParams<any, boolean>) {
const [checked, setChecked] = React.useState(props.value);

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(event.target.checked);
BCFViewer.setVisibility([props.id as number], event.target.checked);
};

return (
<Checkbox
icon={<VisibilityIcon />}
checkedIcon={<VisibilityOffIcon />}
checked={checked}
onChange={handleChange}
/>
);
}

const columns: GridColDef[] = [
{ field: 'type', headerName: 'Type', width: 100 },
{ field: 'objectType', headerName: 'Object Type', width: 250 },
{ field: 'name', headerName: 'Name', width: 380 },
{
field: 'visible',
headerName: 'Visible',
width: 100,
renderCell: RenderCheckBox,
},
];

function getRowId(row: IFCSomething) {
return row.expressID;
}

const onRowSelectionModelChange = (rowSelectionModel: GridRowSelectionModel) => {
BCFViewer.setSelection(rowSelectionModel as number[]);
};

function SettingsContent() {
const state = useSelector((store: RootState) => store.bcf.IFCSomething);

return (
<Box
sx={{
width: '66vw',
height: '100vh',
// bgcolor: 'text.secondary',
// bgcolor: 'rgba(0,0,0,0.1)',
// bgcolor: 'rgba(0,0,0,0.5)',
backgroundColor: 'transparent',
}}
>
<Panel title="Settings" sx={{ mt: 4 }}>
<CardContent>
<Typography variant="body1">
This panel allows you to control the selection and visibility of the
elements in the model.
<br />
These settings are unique to each BCF issue.
</Typography>
<br />
<Typography variant="body1">
This means that you can have different settings for each BCF issue.
</Typography>
<br />
<Typography variant="body1">
The checkbox controls the selection. A selected object will be highlighted
in green.
<br />
The eye icon controls the visibility of the object.
<br />
<br />
N.B: A hidden object will be highlighted if selected (!).
</Typography>
<br />
<Box sx={{ height: '50vh' }}>
<DataGrid
density="compact"
checkboxSelection
disableRowSelectionOnClick
rows={state}
columns={columns}
getRowId={getRowId}
onRowSelectionModelChange={onRowSelectionModelChange}
/>
</Box>
</CardContent>
</Panel>
</Box>
);
}

export default function Settings() {
const [open, setOpen] = useState(false);

const onClick = () => {
setOpen((prev) => !prev);
};

return (
<>
<Button
aria-label="settings"
startIcon={open ? <SettingsTwoToneIcon /> : <SettingsIcon />}
onClick={onClick}
>
Settings
</Button>
<Drawer
open={open}
onClose={() => {
setOpen(false);
}}
variant="persistent"
hideBackdrop={true}
PaperProps={{
sx: {
backgroundColor: 'rgba(0,0,0,0.1)',
backdropFilter: 'blur(5px)',
},
}}
>
<SettingsContent />
</Drawer>
</>
);
}
36 changes: 28 additions & 8 deletions example/react/state/bcfSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createSlice } from '@reduxjs/toolkit';
import type { PayloadAction } from '@reduxjs/toolkit';
// @ts-ignore
import worker from '../../../src/worker/worker?worker';
import { TopicCameraState } from '../../types';
import { IFCSomething, TopicCameraState } from '../../types';
import BCFViewer from '../../viewer/BCFViewer';
import * as BCF from '../../../src';
import type {
Expand All @@ -15,6 +15,7 @@ import {
Coloring_Three,
Component_Three,
Components_Three,
Selection_Three,
TopicViewpoint_Three,
} from '../../../src/three';

Expand All @@ -25,11 +26,13 @@ const bcf = new BCF.ThreeBCF({
export type BCFState = {
topics: TopicFolder_ThreeJSON[];
selectedTopic: TopicFolder_ThreeJSON | null;
IFCSomething: IFCSomething[];
};

const initialState: BCFState = {
topics: [],
selectedTopic: null,
IFCSomething: [],
};

type CreateTopicParams = {
Expand Down Expand Up @@ -85,25 +88,38 @@ export const bcfSlice = createSlice({
const viewpoint = new TopicViewpoint_Three(screenshot);
topic.addViewpoint(viewpoint);

// Determine selection
const selectionState = BCFViewer.getSelection();

const components = new Components_Three();

const selection = new Selection_Three();
components.addSelection(selection);

const coloring = new Coloring_Three();
components.addColoring(coloring);

coloring.setColor('FF00FF00');
const component = new Component_Three();

const { componentState } = BCFViewer;

if (componentState) {
const { ifcGuid, originatingSystem, authoringToolId } = componentState;
component.set({
ifcGuid,
originatingSystem,
authoringToolId,
selectionState.forEach((selectedObject) => {
const state = componentState[selectedObject];
if (state == null) return;
const component = new Component_Three();

const { ifcGuid, originatingSystem, authoringToolId } = state;
component.set({
ifcGuid,
originatingSystem,
authoringToolId,
});

coloring.addComponent(component);
selection.addComponent(component);
});
}
coloring.addComponent(component);

topic.addComponents(components);

Expand Down Expand Up @@ -339,6 +355,9 @@ export const bcfSlice = createSlice({
header,
});
},
setIFCSomething: (state, action: PayloadAction<IFCSomething[]>) => {
state.IFCSomething = action.payload;
},
},
});

Expand All @@ -353,6 +372,7 @@ export const {
addTopicComment,
updateTopicComment,
removeTopicComment,
setIFCSomething,
} = bcfSlice.actions;

export default bcfSlice.reducer;
10 changes: 10 additions & 0 deletions example/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as THREE from 'three';

import type { TopicFolderBase_Three } from '../src/types';

export interface CameraControlsState {
Expand All @@ -16,3 +17,12 @@ export interface BCFCameraState {
position: THREE.Vector3Tuple;
up: THREE.Vector3Tuple;
}

export type IFCSomething = {
expressID: number;
type: string;
objectType: string;
name: string;
selected: boolean;
visible: boolean;
};
Loading

0 comments on commit 7f549ea

Please sign in to comment.