From 8d93f66ac7e2f74e30adbd69209dc196879722f7 Mon Sep 17 00:00:00 2001 From: KatoakDR <68095633+KatoakDR@users.noreply.github.com> Date: Tue, 10 Sep 2024 21:50:01 -0500 Subject: [PATCH] feat: grid stuff --- .../renderer/components/grid/grid-item.tsx | 90 ++++++-- electron/renderer/components/grid/grid.tsx | 2 +- electron/renderer/pages/grid.tsx | 205 +----------------- 3 files changed, 80 insertions(+), 217 deletions(-) diff --git a/electron/renderer/components/grid/grid-item.tsx b/electron/renderer/components/grid/grid-item.tsx index d66c164c..82a9020f 100644 --- a/electron/renderer/components/grid/grid-item.tsx +++ b/electron/renderer/components/grid/grid-item.tsx @@ -24,7 +24,7 @@ import { useCallback, useMemo, useRef } from 'react'; export interface GridItemMetadata { itemId: string; - title: string; + itemTitle: string; isFocused: boolean; x: number; y: number; @@ -32,20 +32,58 @@ export interface GridItemMetadata { height: number; } +/** + * The dimension for the grid where the item may be dragged and resized. + */ +export interface GridItemBoundary { + /** + * The max height of the grid in pixels. + */ + height: number; + /** + * The max width of the grid in pixels. + */ + width: number; +} + +/** + * The positional layout for the grid item. + */ +export interface GridItemLayout { + /** + * The x coordinate for the grid item. + * The leftmost edge of the grid item. + */ + x: number; + /** + * The y coordinate for the grid item. + * The topmost edge of the grid item. + */ + y: number; + /** + * The width dimension for the grid item. + * The horizontal length of the grid item. + * Rightmost edge is `x + width`. + */ + width: number; + /** + * The height dimension for the grid item. + * The vertical length of the grid item. + * Bottommost edge is `y + height`. + */ + height: number; +} + export interface GridItemProps { /** * The dimension for the grid where the item may be dragged and resized. */ - boundary: { - /** - * The max height of the grid in pixels. - */ - height: number; - /** - * The max width of the grid in pixels. - */ - width: number; - }; + boundary: GridItemBoundary; + /** + * The positional layout for the grid item. + * If not specified then a default location will be used. + */ + layout?: GridItemLayout; /** * The unique identifier for the grid item. */ @@ -55,7 +93,7 @@ export interface GridItemProps { * Note the prop `title` is reserved and refers to titling a DOM element, * not for passing data to child components. So using a more specific name. */ - titleBarText: string; + itemTitle: string; /** * Handler when the user clicks the close button in the title bar. * Passes the `itemId` of the grid item being closed. @@ -84,36 +122,42 @@ export interface GridItemProps { children?: ReactNode; } +const DEFAULT_GRID_ITEM_LAYOUT: GridItemLayout = { + x: 0, + y: 0, + width: 500, + height: 500, +}; + export const GridItem: React.FC = ( props: GridItemProps ): ReactNode => { - const { boundary, itemId, titleBarText, isFocused = false, children } = props; + const { itemId, itemTitle, isFocused = false, children } = props; + const { boundary, layout = DEFAULT_GRID_ITEM_LAYOUT } = props; const { onFocus, onClose, onMoveResize } = props; const { euiTheme } = useEuiTheme(); // Set default position and size for the grid item. - const [{ x, y, width, height }, sizeApi] = useSpring(() => ({ - x: 0, - y: 0, - width: 100, - height: 100, - })); + // Like `useState`, we can provide the default value, but as a function. + const [{ x, y, width, height }, sizeApi] = useSpring(() => { + return layout; + }, [layout]); const dragHandleRef = useRef(null); const resizeHandleRef = useRef(null); - const getItemMetadata = useCallback(() => { + const getItemMetadata = useCallback((): GridItemMetadata => { return { itemId, - title: titleBarText, + itemTitle, isFocused, x: x.get(), y: y.get(), width: width.get(), height: height.get(), }; - }, [itemId, titleBarText, isFocused, x, y, width, height]); + }, [itemId, itemTitle, isFocused, x, y, width, height]); // Handle when the user clicks the close button in the title bar. const onCloseClick = useCallback(() => { @@ -318,7 +362,7 @@ export const GridItem: React.FC = ( - {titleBarText} + {itemTitle} diff --git a/electron/renderer/components/grid/grid.tsx b/electron/renderer/components/grid/grid.tsx index 52082319..77a60223 100644 --- a/electron/renderer/components/grid/grid.tsx +++ b/electron/renderer/components/grid/grid.tsx @@ -77,7 +77,7 @@ export const Grid: React.FC = (props: GridProps): ReactNode => { { const [gridWidthRef, { width: gridWidth }] = useMeasure(); const gridHeight = windowSize.height - bottomBarSize.height - 40; - // TODO read layout from storage to detmine the items to show on the grid - // TODO when a user adds an item, we subscribe to that event/callback and update the injected list - // TODO when a user removes an item, we subscribe to that event/callback and update the injected list - // In short, the Grid cmp should not determine what items it has, it receives the items and shows them - const gridItems = [ - { - itemId: 'room', - title: 'Room', - content: ( - - ), - }, - { - itemId: 'experience', - title: 'Experience', - content: ( - - ), - }, - // { - // itemId: 'percWindow', - // title: 'Spells', - // content: ( - // - // ), - // }, - // { - // itemId: 'inv', - // title: 'Inventory', - // content: ( - // - // ), - // }, - // { - // itemId: 'familiar', - // title: 'Familiar', - // content: ( - // - // ), - // }, - // { - // itemId: 'thoughts', - // title: 'Thoughts', - // content: ( - // - // ), - // }, - // { - // itemId: 'combat', - // title: 'Combat', - // content: ( - // - // ), - // }, - // { - // itemId: 'assess', - // title: 'Assess', - // content: ( - // - // ), - // }, - // { - // itemId: 'logons', - // title: 'Arrivals', - // content: ( - // - // ), - // }, - // { - // itemId: 'death', - // title: 'Deaths', - // content: ( - // - // ), - // }, - // { - // itemId: 'atmospherics', - // title: 'Atmospherics', - // content: ( - // - // ), - // }, - // { - // itemId: 'chatter', - // title: 'Chatter', - // content: ( - // - // ), - // }, - // { - // itemId: 'conversation', - // title: 'Conversation', - // content: ( - // - // ), - // }, - // { - // itemId: 'whispers', - // title: 'Whispers', - // content: ( - // - // ), - // }, - // { - // itemId: 'talk', - // title: 'Talk', - // content: ( - // - // ), - // }, - // { - // itemId: 'ooc', - // title: 'OOC', - // content: ( - // - // ), - // }, - // { - // itemId: 'group', - // title: 'Group', - // content: ( - // - // ), - // }, - { - itemId: 'main', - title: 'Main', - content: ( - - ), - }, - ]; - interface GridConfigItem { itemId: string; // 'room' title: string; // 'Room' @@ -566,7 +385,7 @@ const GridPage: React.FC = (): ReactNode => { layoutGridItems.push({ itemId: 'room', - title: 'Room', + itemTitle: 'Room', isFocused: false, x: 0, y: 0, @@ -574,19 +393,19 @@ const GridPage: React.FC = (): ReactNode => { height: 100, }); - // layoutGridItems.push({ - // itemId: 'experience', - // title: 'Experience', - // isFocused: false, - // x: 200, - // y: 0, - // width: 100, - // height: 100, - // }); + layoutGridItems.push({ + itemId: 'experience', + itemTitle: 'Experience', + isFocused: false, + x: 200, + y: 0, + width: 100, + height: 100, + }); layoutGridItems.push({ itemId: 'main', - title: 'Main', + itemTitle: 'Main', isFocused: true, x: 0, y: 200, @@ -628,7 +447,7 @@ const GridPage: React.FC = (): ReactNode => { contentGridItems.push({ layout: { ...layoutItem, - title: configItem?.title ?? layoutItem.title, + itemTitle: configItem?.title ?? layoutItem.itemTitle, }, content: (