From 5fb516f6aae6ebc511714a5726552d760d31dc0a Mon Sep 17 00:00:00 2001 From: Jakob Pinterits Date: Sun, 21 Apr 2024 13:23:22 +0200 Subject: [PATCH] work on the new theming system --- frontend/code/componentManagement.ts | 2 +- frontend/code/components/align.ts | 2 +- frontend/code/components/button.ts | 2 +- frontend/code/components/card.ts | 2 +- frontend/code/components/classContainer.ts | 2 +- frontend/code/components/codeExplorer.ts | 2 +- frontend/code/components/colorPicker.ts | 2 +- frontend/code/components/componentBase.ts | 2 +- frontend/code/components/componentTree.ts | 2 +- frontend/code/components/customListItem.ts | 2 +- frontend/code/components/drawer.ts | 2 +- frontend/code/components/flowContainer.ts | 2 +- .../components/fundamentalRootComponent.ts | 2 +- frontend/code/components/grid.ts | 2 +- frontend/code/components/icon.ts | 2 +- frontend/code/components/keyEventListener.ts | 2 +- frontend/code/components/linearContainers.ts | 4 +- frontend/code/components/link.ts | 2 +- frontend/code/components/listView.ts | 2 +- frontend/code/components/margin.ts | 2 +- frontend/code/components/mediaPlayer.ts | 14 +- .../code/components/mouseEventListener.ts | 2 +- frontend/code/components/nodeInput.ts | 2 +- frontend/code/components/nodeOutput.ts | 2 +- frontend/code/components/overlay.ts | 2 +- frontend/code/components/placeholder.ts | 2 +- frontend/code/components/plot.ts | 2 +- frontend/code/components/popup.ts | 2 +- frontend/code/components/progressCircle.ts | 2 +- frontend/code/components/rectangle.ts | 2 +- frontend/code/components/revealer.ts | 2 +- frontend/code/components/scrollContainer.ts | 2 +- frontend/code/components/scrollTarget.ts | 2 +- frontend/code/components/separator.ts | 2 +- frontend/code/components/slideshow.ts | 2 +- frontend/code/components/stack.ts | 2 +- frontend/code/components/switcher.ts | 2 +- frontend/code/components/switcherBar.ts | 2 +- frontend/code/components/text.ts | 2 +- .../code/components/themeContextSwitcher.ts | 2 +- frontend/code/components/tooltip.ts | 2 +- frontend/code/cssUtils.ts | 2 +- frontend/code/designApplication.ts | 2 +- frontend/code/layoutHelpers.ts | 2 +- frontend/css/style.scss | 2 + rio/color.py | 13 +- .../client_side_debugger/component_details.py | 2 +- rio/session.py | 4 +- rio/text_style.py | 11 +- rio/theme.py | 228 ++++++++---------- 50 files changed, 177 insertions(+), 185 deletions(-) diff --git a/frontend/code/componentManagement.ts b/frontend/code/componentManagement.ts index 85005374..1682fe84 100644 --- a/frontend/code/componentManagement.ts +++ b/frontend/code/componentManagement.ts @@ -7,7 +7,7 @@ import { CodeExplorerComponent } from './components/codeExplorer'; import { ColorPickerComponent } from './components/colorPicker'; import { ColumnComponent, RowComponent } from './components/linearContainers'; import { ComponentBase, ComponentState } from './components/componentBase'; -import { ComponentId } from './models'; +import { ComponentId } from './dataModels'; import { ComponentTreeComponent } from './components/componentTree'; import { CustomListItemComponent } from './components/customListItem'; import { DebuggerConnectorComponent } from './components/debuggerConnector'; diff --git a/frontend/code/components/align.ts b/frontend/code/components/align.ts index 9bae5592..6fa87f3f 100644 --- a/frontend/code/components/align.ts +++ b/frontend/code/components/align.ts @@ -1,6 +1,6 @@ import { componentsById } from '../componentManagement'; import { LayoutContext } from '../layouting'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; export type AlignState = ComponentState & { diff --git a/frontend/code/components/button.ts b/frontend/code/components/button.ts index f2b95e26..6b536a86 100644 --- a/frontend/code/components/button.ts +++ b/frontend/code/components/button.ts @@ -1,5 +1,5 @@ import { applyColorSet } from '../designApplication'; -import { ColorSet, ComponentId } from '../models'; +import { ColorSet, ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; import { MDCRipple } from '@material/ripple'; import { LayoutContext } from '../layouting'; diff --git a/frontend/code/components/card.ts b/frontend/code/components/card.ts index 273c7c7f..6d0032a0 100644 --- a/frontend/code/components/card.ts +++ b/frontend/code/components/card.ts @@ -1,5 +1,5 @@ import { applyColorSet } from '../designApplication'; -import { ColorSet, ComponentId } from '../models'; +import { ColorSet, ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; import { SingleContainer } from './singleContainer'; diff --git a/frontend/code/components/classContainer.ts b/frontend/code/components/classContainer.ts index 13da0936..ed2362ce 100644 --- a/frontend/code/components/classContainer.ts +++ b/frontend/code/components/classContainer.ts @@ -1,6 +1,6 @@ import { SingleContainer } from './singleContainer'; import { ComponentBase, ComponentState } from './componentBase'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; export type ClassContainerState = ComponentState & { _type_: 'ClassContainer-builtin'; diff --git a/frontend/code/components/codeExplorer.ts b/frontend/code/components/codeExplorer.ts index b603dda3..b4d9f01a 100644 --- a/frontend/code/components/codeExplorer.ts +++ b/frontend/code/components/codeExplorer.ts @@ -2,7 +2,7 @@ import hljs from 'highlight.js/lib/common'; import { componentsByElement, componentsById } from '../componentManagement'; import { getElementDimensions, getElementHeight } from '../layoutHelpers'; import { LayoutContext } from '../layouting'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; import { applyIcon } from '../designApplication'; import { commitCss, disableTransitions, enableTransitions } from '../utils'; diff --git a/frontend/code/components/colorPicker.ts b/frontend/code/components/colorPicker.ts index ce43f989..997e9e96 100644 --- a/frontend/code/components/colorPicker.ts +++ b/frontend/code/components/colorPicker.ts @@ -1,4 +1,4 @@ -import { Color } from '../models'; +import { Color } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; import { hsvToRgb, rgbToHsv, rgbToHex, rgbaToHex } from '../colorConversion'; import { LayoutContext } from '../layouting'; diff --git a/frontend/code/components/componentBase.ts b/frontend/code/components/componentBase.ts index dec2ea33..9d25d826 100644 --- a/frontend/code/components/componentBase.ts +++ b/frontend/code/components/componentBase.ts @@ -9,7 +9,7 @@ import { ClickHandler, } from '../eventHandling'; import { DebuggerConnectorComponent } from './debuggerConnector'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; /// Base for all component states. Updates received from the backend are /// partial, hence most properties may be undefined. diff --git a/frontend/code/components/componentTree.ts b/frontend/code/components/componentTree.ts index cb4855d8..8b73ba57 100644 --- a/frontend/code/components/componentTree.ts +++ b/frontend/code/components/componentTree.ts @@ -1,6 +1,6 @@ import { componentsById, getRootScroller } from '../componentManagement'; import { applyIcon } from '../designApplication'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; import { DebuggerConnectorComponent } from './debuggerConnector'; diff --git a/frontend/code/components/customListItem.ts b/frontend/code/components/customListItem.ts index 2602ed6a..4f7823b3 100644 --- a/frontend/code/components/customListItem.ts +++ b/frontend/code/components/customListItem.ts @@ -2,7 +2,7 @@ import { MDCRipple } from '@material/ripple'; import { ComponentBase, ComponentState } from './componentBase'; import { componentsById } from '../componentManagement'; import { LayoutContext } from '../layouting'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; const PADDING_X: number = 1.5; const PADDING_Y: number = 0.7; diff --git a/frontend/code/components/drawer.ts b/frontend/code/components/drawer.ts index e22f84bc..f3382807 100644 --- a/frontend/code/components/drawer.ts +++ b/frontend/code/components/drawer.ts @@ -3,7 +3,7 @@ import { commitCss } from '../utils'; import { componentsById } from '../componentManagement'; import { ComponentBase, ComponentState } from './componentBase'; import { LayoutContext } from '../layouting'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; export type DrawerState = ComponentState & { _type_: 'Drawer-builtin'; diff --git a/frontend/code/components/flowContainer.ts b/frontend/code/components/flowContainer.ts index 7da18a02..d6eb2b58 100644 --- a/frontend/code/components/flowContainer.ts +++ b/frontend/code/components/flowContainer.ts @@ -1,5 +1,5 @@ import { LayoutContext } from '../layouting'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; export type FlowState = ComponentState & { diff --git a/frontend/code/components/fundamentalRootComponent.ts b/frontend/code/components/fundamentalRootComponent.ts index 3c796397..b9c57a9c 100644 --- a/frontend/code/components/fundamentalRootComponent.ts +++ b/frontend/code/components/fundamentalRootComponent.ts @@ -1,7 +1,7 @@ import { pixelsPerRem } from '../app'; import { componentsById } from '../componentManagement'; import { LayoutContext } from '../layouting'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { setConnectionLostPopupVisibleUnlessGoingAway } from '../rpc'; import { ComponentBase, ComponentState } from './componentBase'; diff --git a/frontend/code/components/grid.ts b/frontend/code/components/grid.ts index 893bb2ac..47784a63 100644 --- a/frontend/code/components/grid.ts +++ b/frontend/code/components/grid.ts @@ -1,6 +1,6 @@ import { componentsById } from '../componentManagement'; import { LayoutContext } from '../layouting'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { range } from '../utils'; import { ComponentBase, ComponentState } from './componentBase'; diff --git a/frontend/code/components/icon.ts b/frontend/code/components/icon.ts index a58ffae2..a4caac33 100644 --- a/frontend/code/components/icon.ts +++ b/frontend/code/components/icon.ts @@ -1,4 +1,4 @@ -import { ColorSet, Fill } from '../models'; +import { ColorSet, Fill } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; import { applyFillToSVG } from '../designApplication'; import { pixelsPerRem } from '../app'; diff --git a/frontend/code/components/keyEventListener.ts b/frontend/code/components/keyEventListener.ts index 2c9f6968..2f4f0bdb 100644 --- a/frontend/code/components/keyEventListener.ts +++ b/frontend/code/components/keyEventListener.ts @@ -1,6 +1,6 @@ import { SingleContainer } from './singleContainer'; import { ComponentBase, ComponentState } from './componentBase'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { firstDefined } from '../utils'; // https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_code_values diff --git a/frontend/code/components/linearContainers.ts b/frontend/code/components/linearContainers.ts index fc86acfb..1b863727 100644 --- a/frontend/code/components/linearContainers.ts +++ b/frontend/code/components/linearContainers.ts @@ -1,7 +1,7 @@ import { pixelsPerRem } from '../app'; import { componentsById } from '../componentManagement'; import { LayoutContext } from '../layouting'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; export type LinearContainerState = ComponentState & { @@ -364,7 +364,7 @@ export class ColumnComponent extends LinearContainer { let spacing = Math.max(this.children.size - 1, 0) * this.state.spacing; let proportionSize = - (this.allocatedWidth - spacing) / this.totalProportions; + (this.allocatedHeight - spacing) / this.totalProportions; for (let i = 0; i < proportions.length; i++) { let child = componentsById[this.state.children[i]]!; diff --git a/frontend/code/components/link.ts b/frontend/code/components/link.ts index b83f6e31..ce25601c 100644 --- a/frontend/code/components/link.ts +++ b/frontend/code/components/link.ts @@ -1,7 +1,7 @@ import { componentsById } from '../componentManagement'; import { getTextDimensions } from '../layoutHelpers'; import { LayoutContext } from '../layouting'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; export type LinkState = ComponentState & { diff --git a/frontend/code/components/listView.ts b/frontend/code/components/listView.ts index 3aba21ff..22f5bd01 100644 --- a/frontend/code/components/listView.ts +++ b/frontend/code/components/listView.ts @@ -1,5 +1,5 @@ import { componentsByElement } from '../componentManagement'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { ComponentBase } from './componentBase'; import { CustomListItemComponent } from './customListItem'; import { HeadingListItemComponent } from './headingListItem'; diff --git a/frontend/code/components/margin.ts b/frontend/code/components/margin.ts index b7230e20..e0b8c177 100644 --- a/frontend/code/components/margin.ts +++ b/frontend/code/components/margin.ts @@ -1,7 +1,7 @@ import { ComponentBase, ComponentState } from './componentBase'; import { componentsById } from '../componentManagement'; import { LayoutContext } from '../layouting'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; export type MarginState = ComponentState & { _type_: 'Margin-builtin'; diff --git a/frontend/code/components/mediaPlayer.ts b/frontend/code/components/mediaPlayer.ts index b5eabf2a..bc27278c 100644 --- a/frontend/code/components/mediaPlayer.ts +++ b/frontend/code/components/mediaPlayer.ts @@ -1,7 +1,7 @@ import { fillToCss } from '../cssUtils'; import { applyIcon } from '../designApplication'; import { LayoutContext } from '../layouting'; -import { Fill } from '../models'; +import { Fill } from '../dataModels'; import { sleep } from '../utils'; import { ComponentBase, ComponentState } from './componentBase'; @@ -209,7 +209,11 @@ export class MediaPlayerComponent extends ComponentBase { this._isFullScreen = document.fullscreenElement === this.element; if (this._isFullScreen) { - applyIcon(this.fullscreenButton, 'material/fullscreen-exit', 'white'); + applyIcon( + this.fullscreenButton, + 'material/fullscreen-exit', + 'white' + ); } else { applyIcon(this.fullscreenButton, 'material/fullscreen', 'white'); } @@ -644,7 +648,11 @@ export class MediaPlayerComponent extends ComponentBase { this.volumeCurrent.style.width = `${humanVolume * 100}%`; if (humanVolume < 0.5) { - applyIcon(this.muteButton, 'material/volume-down:fill', 'white'); + applyIcon( + this.muteButton, + 'material/volume-down:fill', + 'white' + ); } else { applyIcon(this.muteButton, 'material/volume-up:fill', 'white'); } diff --git a/frontend/code/components/mouseEventListener.ts b/frontend/code/components/mouseEventListener.ts index fb68b3c2..5f5abd68 100644 --- a/frontend/code/components/mouseEventListener.ts +++ b/frontend/code/components/mouseEventListener.ts @@ -3,7 +3,7 @@ import { SingleContainer } from './singleContainer'; import { ComponentBase, ComponentState } from './componentBase'; import { DragHandler } from '../eventHandling'; import { tryGetComponentByElement } from '../componentManagement'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; function eventMouseButtonToString(event: MouseEvent): object { return { diff --git a/frontend/code/components/nodeInput.ts b/frontend/code/components/nodeInput.ts index 507dc2d5..b8f23f21 100644 --- a/frontend/code/components/nodeInput.ts +++ b/frontend/code/components/nodeInput.ts @@ -1,6 +1,6 @@ import { ComponentBase, ComponentState } from './componentBase'; import { LayoutContext } from '../layouting'; -import { Color } from '../models'; +import { Color } from '../dataModels'; import { getTextDimensions } from '../layoutHelpers'; import { colorToCssString } from '../cssUtils'; diff --git a/frontend/code/components/nodeOutput.ts b/frontend/code/components/nodeOutput.ts index 4790db6f..76c6951a 100644 --- a/frontend/code/components/nodeOutput.ts +++ b/frontend/code/components/nodeOutput.ts @@ -1,6 +1,6 @@ import { ComponentBase, ComponentState } from './componentBase'; import { LayoutContext } from '../layouting'; -import { Color } from '../models'; +import { Color } from '../dataModels'; import { getTextDimensions } from '../layoutHelpers'; import { colorToCssString } from '../cssUtils'; diff --git a/frontend/code/components/overlay.ts b/frontend/code/components/overlay.ts index 5c577b5b..c0a731ec 100644 --- a/frontend/code/components/overlay.ts +++ b/frontend/code/components/overlay.ts @@ -1,6 +1,6 @@ import { componentsById, getRootComponent } from '../componentManagement'; import { LayoutContext } from '../layouting'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; export type OverlayState = ComponentState & { diff --git a/frontend/code/components/placeholder.ts b/frontend/code/components/placeholder.ts index 2050efcc..14236996 100644 --- a/frontend/code/components/placeholder.ts +++ b/frontend/code/components/placeholder.ts @@ -1,6 +1,6 @@ import { SingleContainer } from './singleContainer'; import { ComponentBase, ComponentState } from './componentBase'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; export type PlaceholderState = ComponentState & { _type_: 'Placeholder'; // Not 'Placeholder-builtin'! diff --git a/frontend/code/components/plot.ts b/frontend/code/components/plot.ts index 45eed987..62aaeec1 100644 --- a/frontend/code/components/plot.ts +++ b/frontend/code/components/plot.ts @@ -1,7 +1,7 @@ import { pixelsPerRem } from '../app'; import { fillToCss } from '../cssUtils'; import { LayoutContext } from '../layouting'; -import { Fill } from '../models'; +import { Fill } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; type PlotlyPlot = { diff --git a/frontend/code/components/popup.ts b/frontend/code/components/popup.ts index ad5920e9..8b3fe237 100644 --- a/frontend/code/components/popup.ts +++ b/frontend/code/components/popup.ts @@ -2,7 +2,7 @@ import { pixelsPerRem } from '../app'; import { componentsById } from '../componentManagement'; import { applyColorSet } from '../designApplication'; import { LayoutContext } from '../layouting'; -import { ColorSet, ComponentId } from '../models'; +import { ColorSet, ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; export type PopupState = ComponentState & { diff --git a/frontend/code/components/progressCircle.ts b/frontend/code/components/progressCircle.ts index 640c04bf..9fc64550 100644 --- a/frontend/code/components/progressCircle.ts +++ b/frontend/code/components/progressCircle.ts @@ -1,5 +1,5 @@ import { applyColorSet } from '../designApplication'; -import { ColorSet } from '../models'; +import { ColorSet } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; export type ProgressCircleState = ComponentState & { diff --git a/frontend/code/components/rectangle.ts b/frontend/code/components/rectangle.ts index b2c030d3..7f0c7e6c 100644 --- a/frontend/code/components/rectangle.ts +++ b/frontend/code/components/rectangle.ts @@ -1,4 +1,4 @@ -import { Color, ComponentId, Fill } from '../models'; +import { Color, ComponentId, Fill } from '../dataModels'; import { colorToCssString, fillToCssString } from '../cssUtils'; import { ComponentBase, ComponentState } from './componentBase'; import { MDCRipple } from '@material/ripple'; diff --git a/frontend/code/components/revealer.ts b/frontend/code/components/revealer.ts index aedad3be..269c530a 100644 --- a/frontend/code/components/revealer.ts +++ b/frontend/code/components/revealer.ts @@ -4,7 +4,7 @@ import { applyIcon } from '../designApplication'; import { easeInOut } from '../easeFunctions'; import { getTextDimensions } from '../layoutHelpers'; import { LayoutContext, updateLayout } from '../layouting'; -import { ComponentId, TextStyle } from '../models'; +import { ComponentId, TextStyle } from '../dataModels'; import { firstDefined } from '../utils'; import { ComponentBase, ComponentState } from './componentBase'; diff --git a/frontend/code/components/scrollContainer.ts b/frontend/code/components/scrollContainer.ts index 64025a7d..04709875 100644 --- a/frontend/code/components/scrollContainer.ts +++ b/frontend/code/components/scrollContainer.ts @@ -1,7 +1,7 @@ import { pixelsPerRem, scrollBarSize } from '../app'; import { componentsById } from '../componentManagement'; import { LayoutContext } from '../layouting'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; export type ScrollContainerState = ComponentState & { diff --git a/frontend/code/components/scrollTarget.ts b/frontend/code/components/scrollTarget.ts index 978c2263..05dd02c9 100644 --- a/frontend/code/components/scrollTarget.ts +++ b/frontend/code/components/scrollTarget.ts @@ -1,4 +1,4 @@ -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; import { SingleContainer } from './singleContainer'; diff --git a/frontend/code/components/separator.ts b/frontend/code/components/separator.ts index 22543efb..b2ec9611 100644 --- a/frontend/code/components/separator.ts +++ b/frontend/code/components/separator.ts @@ -1,4 +1,4 @@ -import { Color } from '../models'; +import { Color } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; import { pixelsPerRem } from '../app'; import { LayoutContext } from '../layouting'; diff --git a/frontend/code/components/slideshow.ts b/frontend/code/components/slideshow.ts index 20899fb5..f695e3ff 100644 --- a/frontend/code/components/slideshow.ts +++ b/frontend/code/components/slideshow.ts @@ -1,7 +1,7 @@ import { ComponentBase, ComponentState } from './componentBase'; import { easeIn, easeInOut, easeOut } from '../easeFunctions'; import { SingleContainer } from './singleContainer'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; const switchDuration = 0.8; const progressBarFadeDuration = 0.2; diff --git a/frontend/code/components/stack.ts b/frontend/code/components/stack.ts index 6640ce95..eb235255 100644 --- a/frontend/code/components/stack.ts +++ b/frontend/code/components/stack.ts @@ -1,4 +1,4 @@ -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; import { SingleContainer } from './singleContainer'; diff --git a/frontend/code/components/switcher.ts b/frontend/code/components/switcher.ts index 77bf91eb..a8bb4fc8 100644 --- a/frontend/code/components/switcher.ts +++ b/frontend/code/components/switcher.ts @@ -1,4 +1,4 @@ -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; import { componentsById } from '../componentManagement'; import { LayoutContext, updateLayout } from '../layouting'; diff --git a/frontend/code/components/switcherBar.ts b/frontend/code/components/switcherBar.ts index d4e1ccbc..e53a017c 100644 --- a/frontend/code/components/switcherBar.ts +++ b/frontend/code/components/switcherBar.ts @@ -1,6 +1,6 @@ import { ComponentBase, ComponentState } from './componentBase'; import { MDCRipple } from '@material/ripple'; -import { ColorSet, TextStyle } from '../models'; +import { ColorSet, TextStyle } from '../dataModels'; import { applyColorSet } from '../designApplication'; import { getTextDimensions } from '../layoutHelpers'; import { LayoutContext } from '../layouting'; diff --git a/frontend/code/components/text.ts b/frontend/code/components/text.ts index 38e7f8cf..bdaf86fd 100644 --- a/frontend/code/components/text.ts +++ b/frontend/code/components/text.ts @@ -1,4 +1,4 @@ -import { TextStyle } from '../models'; +import { TextStyle } from '../dataModels'; import { textStyleToCss } from '../cssUtils'; import { ComponentBase, ComponentState } from './componentBase'; import { LayoutContext } from '../layouting'; diff --git a/frontend/code/components/themeContextSwitcher.ts b/frontend/code/components/themeContextSwitcher.ts index c3f1d3e6..8e687718 100644 --- a/frontend/code/components/themeContextSwitcher.ts +++ b/frontend/code/components/themeContextSwitcher.ts @@ -1,5 +1,5 @@ import { applyColorSet } from '../designApplication'; -import { ColorSet, ComponentId } from '../models'; +import { ColorSet, ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; import { SingleContainer } from './singleContainer'; diff --git a/frontend/code/components/tooltip.ts b/frontend/code/components/tooltip.ts index a7a2603a..0c5629df 100644 --- a/frontend/code/components/tooltip.ts +++ b/frontend/code/components/tooltip.ts @@ -1,6 +1,6 @@ import { componentsById } from '../componentManagement'; import { LayoutContext } from '../layouting'; -import { ComponentId } from '../models'; +import { ComponentId } from '../dataModels'; import { ComponentBase, ComponentState } from './componentBase'; import { SingleContainer } from './singleContainer'; diff --git a/frontend/code/cssUtils.ts b/frontend/code/cssUtils.ts index 91584a09..29b56772 100644 --- a/frontend/code/cssUtils.ts +++ b/frontend/code/cssUtils.ts @@ -1,4 +1,4 @@ -import { Color, Fill, TextStyle } from './models'; +import { Color, Fill, TextStyle } from './dataModels'; export function colorToCssString(color: Color): string { const [r, g, b, a] = color; diff --git a/frontend/code/designApplication.ts b/frontend/code/designApplication.ts index ce851639..1177d76a 100644 --- a/frontend/code/designApplication.ts +++ b/frontend/code/designApplication.ts @@ -1,4 +1,4 @@ -import { Color, ColorSet, Fill } from './models'; +import { Color, ColorSet, Fill } from './dataModels'; import { colorToCssString } from './cssUtils'; const ICON_PROMISE_CACHE: { [key: string]: Promise } = {}; diff --git a/frontend/code/layoutHelpers.ts b/frontend/code/layoutHelpers.ts index caf2edbc..0dbc9c91 100644 --- a/frontend/code/layoutHelpers.ts +++ b/frontend/code/layoutHelpers.ts @@ -1,6 +1,6 @@ import { pixelsPerRem } from './app'; import { textStyleToCss } from './cssUtils'; -import { TextStyle } from './models'; +import { TextStyle } from './dataModels'; const _textDimensionsCache = new Map(); diff --git a/frontend/css/style.scss b/frontend/css/style.scss index 9471809c..d9f471a9 100644 --- a/frontend/css/style.scss +++ b/frontend/css/style.scss @@ -2727,6 +2727,8 @@ textarea:not(:placeholder-shown) ~ .rio-input-box-label, } .rio-code-explorer-source-code { + pointer-events: auto; + display: block; cursor: text; white-space: pre; diff --git a/rio/color.py b/rio/color.py index 58779f5d..98b6ef3e 100644 --- a/rio/color.py +++ b/rio/color.py @@ -1,6 +1,7 @@ from __future__ import annotations import colorsys +import math from typing import * # type: ignore from typing_extensions import TypeAlias @@ -392,15 +393,9 @@ class Color(SelfSerializing): `1.0` is full brightness. """ - # Account for the nonlinearity of human vision / gamma / sRGB - red_linear = self.red**2.2 - green_linear = self.green**2.2 - blue_linear = self.blue**2.2 - - # Calculate the perceived brightness - brightness = 0.299 * red_linear + 0.587 * green_linear + 0.114 * blue_linear - - return brightness + return math.sqrt( + 0.299 * self.red**2 + 0.587 * self.green**2 + 0.114 * self.blue**2 + ) @property def hex(self) -> str: diff --git a/rio/debug/client_side_debugger/component_details.py b/rio/debug/client_side_debugger/component_details.py index 59f078bd..15681092 100644 --- a/rio/debug/client_side_debugger/component_details.py +++ b/rio/debug/client_side_debugger/component_details.py @@ -309,7 +309,7 @@ class ComponentDetails(rio.Component): # Link to docs if type(target)._rio_builtin_: - docs_url = rio.docs.documentation_url(type(target).__name__) + docs_url = rio.docs.build_documentation_url(type(target).__name__) link_color = self.session.theme.secondary_color result.add( diff --git a/rio/session.py b/rio/session.py index 2f4107a5..e786def7 100644 --- a/rio/session.py +++ b/rio/session.py @@ -1881,7 +1881,9 @@ a.remove(); ) # CSS variables for the fill - assert style.fill is not None, "Text fills must be defined in the theme." + assert ( + style.fill is not None + ), "Text fills must be defined the theme's text styles." fill_variables = self._host_and_get_fill_as_css_variables(style.fill) for var, value in fill_variables.items(): diff --git a/rio/text_style.py b/rio/text_style.py index b8a24ee5..3e83ffd5 100644 --- a/rio/text_style.py +++ b/rio/text_style.py @@ -18,6 +18,13 @@ __all__ = [ ] +class UnsetType: + pass + + +UNSET = UnsetType() + + @dataclass(frozen=True) class Font(SelfSerializing): name: str @@ -68,7 +75,7 @@ class TextStyle(SelfSerializing): self, *, font: Font | None = None, - fill: FillLike | None = None, + fill: FillLike | None | UnsetType = UNSET, font_size: float | None = None, italic: bool | None = None, font_weight: Literal["normal", "bold"] | None = None, @@ -77,7 +84,7 @@ class TextStyle(SelfSerializing): ) -> TextStyle: return type(self)( font=self.font if font is None else font, - fill=self.fill if fill is None else fill, + fill=self.fill if isinstance(fill, UnsetType) else fill, font_size=self.font_size if font_size is None else font_size, italic=self.italic if italic is None else italic, font_weight=self.font_weight if font_weight is None else font_weight, diff --git a/rio/theme.py b/rio/theme.py index aa40c87f..644fb292 100644 --- a/rio/theme.py +++ b/rio/theme.py @@ -21,6 +21,10 @@ __all__ = [ T = TypeVar("T") +def lerp(a: float, b: float, frac: float) -> float: + return a + frac * (b - a) + + def map_range(value: float, in1: float, in2: float, out1: float, out2: float) -> float: """ Maps a value from one range to another. @@ -30,6 +34,42 @@ def map_range(value: float, in1: float, in2: float, out1: float, out2: float) -> return out1 + frac * (out2 - out1) +def color_from_tone(hue: float, saturation: float, tone: float) -> rio.Color: + """ + Creates a color from a hue, saturation, and tone. Tone 0 is pure black, 0.5 + the pure color and 1 pure white. + """ + # If the tone is below 0.5 use it to darken the color + if tone < 0.5: + return rio.Color.from_hsv( + hue=hue, + saturation=saturation, + value=2 * tone, + ) + + # Otherwise lighten it + frac = 2 * (tone - 0.5) + + return rio.Color.from_hsv( + hue=hue, + saturation=lerp(saturation, 0, frac), + value=1, + ) + + +def tone_from_color(color: rio.Color) -> float: + """ + Returns the tone of a color. Tone 0 is pure black, 0.5 the pure color and 1 + pure white. + """ + hue, saturation, value = color.hsv + + if value < 1: + return value / 2 + + return 1 - saturation + + def color_with_brightness(color: rio.Color, target_brightness: float) -> rio.Color: """ Returns the same shade of color, but with a different brightness. Brightness @@ -47,7 +87,7 @@ def color_with_brightness(color: rio.Color, target_brightness: float) -> rio.Col # Otherwise keep the color and adjust the brightness return rio.Color.from_hsv( hue=hue, - saturation=map_range(saturation, 0.5, 1, 1, 0), + saturation=map_range(target_brightness, 0.5, 1, 1, 0), value=min(target_brightness * 2, 1), opacity=color.opacity, ) @@ -68,31 +108,34 @@ class Palette: color: rio.Color, *, colorful: bool, + brightness_threshold: float = 0.5, ) -> Self: # For the foreground color, keep the same shade but adjust the # brightness to make it readable. current_brightness = color.perceived_brightness + brighten = current_brightness <= brightness_threshold if colorful: - brightness_offset = 0.5 - brightness_cutoff = 0.2 + brightness_offset = 0.45 + brightness_cutoff = 0.23 else: - brightness_offset = 0.8 - brightness_cutoff = 0.08 + brightness_offset = 0.7 + brightness_cutoff = 0.1 target_brightness = ( - current_brightness - brightness_offset - if current_brightness > 0.55 # Bias towards bright labels - else current_brightness + brightness_offset + current_brightness + brightness_offset + if brighten + else current_brightness - brightness_offset ) target_brightness = max( min(target_brightness, 1 - brightness_cutoff), brightness_cutoff ) + # Try to brighten colors, but darken if the color is already very bright return cls( background=color, - background_variant=color.brighter(0.05), - background_active=color.brighter(0.15), + background_variant=color.brighter(0.08 if brighten else -0.08), + background_active=color.brighter(0.15 if brighten else -0.15), foreground=color_with_brightness(color, target_brightness), ) @@ -124,10 +167,6 @@ class Theme: The `Theme` contains all colors, text styles, and other visual properties that are used throughout the application. If you wish to change the appearance of your app, this is the place to do it. - - TODO: Finalize theming and document it - - TODO: Give an example for how to create a theme and use it in an app. """ _: KW_ONLY @@ -187,126 +226,61 @@ class Theme: if secondary_color is None: secondary_color = rio.Color.from_hex("0083ff") + if background_color is None: + if light: + background_color = rio.Color.from_grey(1.00).blend(primary_color, 0.05) + else: + background_color = rio.Color.from_grey(0.08).blend(primary_color, 0.05) + + if neutral_color is None: + if light: + neutral_color = rio.Color.from_grey(0.95).blend(primary_color, 0.12) + else: + neutral_color = rio.Color.from_grey(0.16).blend(primary_color, 0.12) + + if hud_color is None: + hud_color = rio.Color.from_grey(0.2) + + if disabled_color is None: + disabled_color = rio.Color.from_grey(0.7) + if success_color is None: - success_color = rio.Color.from_hex("1E8E3E") + success_color = rio.Color.from_hex("1e8e3e") if warning_color is None: - warning_color = rio.Color.from_hex("F9A825") + warning_color = rio.Color.from_hex("f9a825") if danger_color is None: - danger_color = rio.Color.from_hex("B3261E") + danger_color = rio.Color.from_hex("b3261e") # Extract palettes from the material theme - primary_palette = Palette._from_color(primary_color, colorful=False) - secondary_palette = Palette._from_color(secondary_color, colorful=False) + primary_palette = Palette._from_color( + primary_color, + colorful=False, + brightness_threshold=0.55, # Often used for buttons. Prefer light texts + ) - if light: - if background_color is None: - background_palette = Palette( - background=rio.Color.WHITE, - background_variant=rio.Color.from_grey(0.96).blend( - primary_color, 0.04 - ), - background_active=rio.Color.from_grey(0.96).blend( - primary_color, 0.1 - ), - foreground=rio.Color.from_grey(0.15), - ) - else: - background_palette = Palette._from_color( - background_color, colorful=False - ) + secondary_palette = Palette._from_color( + secondary_color, + colorful=False, + brightness_threshold=0.65, # Often used for buttons. Prefer light texts + ) - if neutral_color is None: - neutral_palette = Palette( - background=rio.Color.from_grey(0.97).blend(primary_color, 0.04), - background_variant=rio.Color.from_grey(0.93).blend( - primary_color, 0.07 - ), - background_active=rio.Color.from_grey(0.93).blend( - primary_color, 0.15 - ), - foreground=rio.Color.from_grey(0.1), - ) - else: - neutral_palette = Palette._from_color(neutral_color, colorful=False) + background_palette = Palette._from_color(background_color, colorful=False) + neutral_palette = Palette._from_color(neutral_color, colorful=False) - if hud_color is None: - hud_palette = Palette._from_color( - rio.Color.from_grey( - 0.06, - opacity=0.9, - ), - colorful=False, - ) - else: - hud_palette = Palette._from_color(hud_color, colorful=False) + hud_palette = Palette._from_color(hud_color, colorful=False) - if disabled_color is None: - disabled_palette = Palette( - rio.Color.from_grey(0.7), - rio.Color.from_grey(0.75), - rio.Color.from_grey(0.80), - rio.Color.from_grey(0.4), - ) - else: - disabled_palette = Palette._from_color(disabled_color, colorful=False) + # Keep the disabled palette subdued. It's not meant to be perfectly + # readable + disabled_palette = Palette._from_color(disabled_color, colorful=False) + disabled_palette = disabled_palette.replace( + foreground=disabled_palette.foreground.blend( + disabled_palette.background, 0.7 + ) + ) - shadow_color = rio.Color.from_rgb(0.1, 0.1, 0.4, 0.3) - - else: - if background_color is None: - background_palette = Palette( - background=rio.Color.from_grey(0.08).blend(primary_color, 0.02), - background_variant=rio.Color.from_grey(0.14).blend( - primary_color, 0.04 - ), - background_active=rio.Color.from_grey(0.14).blend( - primary_color, 0.10 - ), - foreground=rio.Color.from_grey(0.9), - ) - else: - background_palette = Palette._from_color( - background_color, colorful=False - ) - - if neutral_color is None: - neutral_palette = Palette( - background=rio.Color.from_grey(0.16).blend(primary_color, 0.03), - background_variant=rio.Color.from_grey(0.2).blend( - primary_color, 0.04 - ), - background_active=rio.Color.from_grey(0.2).blend( - primary_color, 0.10 - ), - foreground=rio.Color.from_grey(0.5), - ) - else: - neutral_palette = Palette._from_color(neutral_color, colorful=False) - - if hud_color is None: - hud_palette = Palette._from_color( - rio.Color.from_grey( - 0.2, - opacity=0.8, - ), - colorful=False, - ) - else: - hud_palette = Palette._from_color(hud_color, colorful=False) - - if disabled_color is None: - disabled_palette = Palette( - rio.Color.from_grey(0.2), - rio.Color.from_grey(0.15), - rio.Color.from_grey(0.10), - rio.Color.from_grey(0.6), - ) - else: - disabled_palette = Palette._from_color(disabled_color, colorful=False) - - shadow_color = rio.Color.from_rgb(0.0, 0.0, 0.1, 0.35) + shadow_color = rio.Color.from_rgb(0.1, 0.1, 0.4, 0.3) # Semantic colors success_palette = Palette._from_color(success_color, colorful=True) @@ -323,17 +297,21 @@ class Theme: color_headings = abs(brightness1 - brightness2) > 0.3 # Text styles - text_color = rio.Color.from_grey(0.1 if light else 0.9) + neutral_text_color = ( + rio.Color.from_grey(0.1) + if background_color.perceived_brightness > 0.5 + else rio.Color.from_grey(0.9) + ) heading1_style = rio.TextStyle( font_size=3.0, - fill=primary_color if color_headings else text_color, + fill=primary_color if color_headings else neutral_text_color, ) heading2_style = heading1_style.replace(font_size=1.8) heading3_style = heading1_style.replace(font_size=1.2) text_style = heading1_style.replace( font_size=1, - fill=text_color, + fill=neutral_text_color, ) return cls(