From 99a7a6d3d0803d3c904e2489bb1cd038e66ce6b9 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 3 Nov 2026 09:19:19 +0000 Subject: [PATCH] Add orange VS Code theme and make it the default Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01EqzDdY4jk7HjWtr2eNPkpT --- CHANGELOG.md | 1 + docs/architecture.md | 4 +- lib/main.dart | 3 +- .../lib/dbscope_vscode_dark_plugin.dart | 19 ++++- .../lib/src/theme.dart | 13 ++- .../lib/src/themes/vscode_dark_theme.dart | 83 ++++++++++++++----- 6 files changed, 94 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d30c6ec..5264b2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ## 2026-11-03 +- New default theme "dbscope Orange": VS Code Dark Modern with the logo's orange as the accent. The blue VS Code theme stays in View > Theme. (2026-11-03) - Query result headers now also show the names of enums, domains and extension types (looked up once per connection) (2026-11-03) - The connection dialog's Read-only switch now proposes a default and says why: on when the name says prod/live/main or the server is remote, off for a database on this machine; it stops following once you flip it (2026-11-03) - Re-importing a connection link (or auto-connecting) for an open profile now reconnects when the host, user, password or other connection settings changed, instead of keeping the old connection (2026-11-03) diff --git a/docs/architecture.md b/docs/architecture.md index 007fe8d..3021ac8 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -109,7 +109,7 @@ Every theme ships as a standalone package; the host has no built-in themes. Curr - `packages/dbscope_doom_plugin/` — Doom theme + sprite assets + floating mugshot overlay. The theme's `overlays` list is what makes the mugshot appear; remove the plugin and the mugshot is gone. - `packages/dbscope_win95_plugin/` -- `packages/dbscope_vscode_dark_plugin/` +- `packages/dbscope_vscode_dark_plugin/` — registers two themes: "dbscope Orange" (`vsCodeOrange`, the default) and the original blue "VS Code Dark Modern" (`vsCodeDark`). - `packages/dbscope_warcraft_plugin/` - `packages/dbscope_portal_plugin/` @@ -222,7 +222,7 @@ Two mixins under `lib/util/` cover the repetitive State plumbing: `AppState.notifyChange()` is called from view widgets that mutate fields directly on the tab model — there's no separate per-tab notifier. This is intentional; don't introduce one. -Themes and reusable widgets live in `packages/widgets/` (Dart package name `widgets`, depended on via `path:`). Two palettes (`win95Palette`, `vsCodeDarkPalette`) implement the shared `AppPalette` `ThemeExtension`; widgets read role-based fields via `AppPalette.of(context)` and shape-adapt via `ChromeKind` (`bevel` vs `flat`). Anything outside the package imports from a single barrel: `import 'package:widgets/widgets.dart';`. The package ships the bundled MS Sans Serif TTF under `lib/assets/fonts/` so it works standalone in any consumer project. Typed-cell colors are driven by the `type*` roles on `AppPalette` (e.g. `typeString`, `typeNumber`, `typeJson`, `typeNull`); the PG-type → role mapping lives in `lib/grid/typed_value_text.dart`. +Themes and reusable widgets live in `packages/widgets/` (Dart package name `widgets`, depended on via `path:`). Three palettes (`win95Palette`, `vsCodeDarkPalette`, and `vsCodeOrangePalette`, the default theme: Dark Modern with the logo's orange as accent) implement the shared `AppPalette` `ThemeExtension`; widgets read role-based fields via `AppPalette.of(context)` and shape-adapt via `ChromeKind` (`bevel` vs `flat`). Anything outside the package imports from a single barrel: `import 'package:widgets/widgets.dart';`. The package ships the bundled MS Sans Serif TTF under `lib/assets/fonts/` so it works standalone in any consumer project. Typed-cell colors are driven by the `type*` roles on `AppPalette` (e.g. `typeString`, `typeNumber`, `typeJson`, `typeNull`); the PG-type → role mapping lives in `lib/grid/typed_value_text.dart`. ## The grid and pagination diff --git a/lib/main.dart b/lib/main.dart index 347dd00..ef69d7c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -211,7 +211,8 @@ void _registerPlugins() { registry.register(MetaPlugin()); // Theme plugins. The first one registered is the default (and the fallback - // when a saved theme no longer exists), so VS Code Dark goes first. + // when a saved theme no longer exists), so VS Code Dark goes first: it + // registers its orange variant (the default) before the original blue one. registry.register(VsCodeDarkThemePlugin()); // Doom theme wired out — re-enable by restoring the import + pubspec dep. // registry.register(DoomPlugin()); diff --git a/packages/dbscope_vscode_dark_plugin/lib/dbscope_vscode_dark_plugin.dart b/packages/dbscope_vscode_dark_plugin/lib/dbscope_vscode_dark_plugin.dart index ff0789a..22431a5 100644 --- a/packages/dbscope_vscode_dark_plugin/lib/dbscope_vscode_dark_plugin.dart +++ b/packages/dbscope_vscode_dark_plugin/lib/dbscope_vscode_dark_plugin.dart @@ -3,8 +3,18 @@ import 'package:dbscope/shell/theme_registry.dart'; import 'src/theme.dart'; -export 'src/theme.dart' show VsCodeDarkTheme, buildVsCodeDarkTheme, vsCodeDarkPalette; +export 'src/theme.dart' + show + VsCodeDarkTheme, + VsCodeOrangeTheme, + buildVsCodeDarkTheme, + buildVsCodeOrangeTheme, + vsCodeDarkPalette, + vsCodeOrangePalette; +/// Registers two VS Code Dark Modern themes: the dbscope orange variant +/// (registered first, so it is the app's default and fallback when this +/// plugin is registered first) and the original blue one. class VsCodeDarkThemePlugin extends DbscopePlugin { @override String get id => 'vsCodeDark'; @@ -13,6 +23,13 @@ class VsCodeDarkThemePlugin extends DbscopePlugin { @override void register(DbscopeHost host) { + host.themes.register( + const ThemePlugin( + id: 'vsCodeOrange', + label: 'dbscope Orange', + build: buildVsCodeOrangeTheme, + ), + ); host.themes.register( const ThemePlugin( id: 'vsCodeDark', diff --git a/packages/dbscope_vscode_dark_plugin/lib/src/theme.dart b/packages/dbscope_vscode_dark_plugin/lib/src/theme.dart index 3af2b3f..46f0d66 100644 --- a/packages/dbscope_vscode_dark_plugin/lib/src/theme.dart +++ b/packages/dbscope_vscode_dark_plugin/lib/src/theme.dart @@ -1,4 +1,11 @@ -// The VS Code Dark Modern theme lives in the shared `widgets` package so apps -// outside dbscope (the compledo admin tool) can use it without depending on +// The VS Code Dark Modern themes live in the shared `widgets` package so apps +// outside dbscope (the compledo admin tool) can use them without depending on // the dbscope app. Re-exported here so this plugin's API is unchanged. -export 'package:widgets/widgets.dart' show VsCodeDarkTheme, buildVsCodeDarkTheme, vsCodeDarkPalette; +export 'package:widgets/widgets.dart' + show + VsCodeDarkTheme, + VsCodeOrangeTheme, + buildVsCodeDarkTheme, + buildVsCodeOrangeTheme, + vsCodeDarkPalette, + vsCodeOrangePalette; diff --git a/packages/widgets/lib/src/themes/vscode_dark_theme.dart b/packages/widgets/lib/src/themes/vscode_dark_theme.dart index 45dd2cc..9dd7e5c 100644 --- a/packages/widgets/lib/src/themes/vscode_dark_theme.dart +++ b/packages/widgets/lib/src/themes/vscode_dark_theme.dart @@ -83,11 +83,36 @@ const vsCodeDarkPalette = AppPalette( smallFontSize: 12, ); +/// The logo's orange (`site/assets/dbscope_icon.svg` background). +const _dbscopeOrange = Color(0xFFE5452B); + +/// Deep rust that plays the role Dark Modern's `#04395E` navy plays: +/// selected rows and soft accent fills, dark enough for `#CCCCCC` text. +const _dbscopeOrangeSoft = Color(0xFF5C2216); + +/// VS Code Dark Modern with the blue accent swapped for the dbscope logo's +/// orange. Every other role (surfaces, text, syntax tokens) is unchanged. +final AppPalette vsCodeOrangePalette = vsCodeDarkPalette.copyWith( + accent: _dbscopeOrange, + accentSoft: _dbscopeOrangeSoft, + rowSelected: _dbscopeOrangeSoft, +); + /// Builds the VS Code Dark Modern [ThemeData]. The optional [fontFamily] /// overrides the default `.AppleSystemUIFont`. -ThemeData buildVsCodeDarkTheme({String? fontFamily}) { - final palette = - fontFamily == null ? vsCodeDarkPalette : vsCodeDarkPalette.copyWith(uiFontFamily: fontFamily); +ThemeData buildVsCodeDarkTheme({String? fontFamily}) => + buildVsCodeThemeFromPalette(vsCodeDarkPalette, fontFamily: fontFamily); + +/// Builds the orange variant of VS Code Dark Modern (see +/// [vsCodeOrangePalette]). The optional [fontFamily] overrides the default +/// `.AppleSystemUIFont`. +ThemeData buildVsCodeOrangeTheme({String? fontFamily}) => + buildVsCodeThemeFromPalette(vsCodeOrangePalette, fontFamily: fontFamily); + +/// Builds a flat, dark VS Code-style [ThemeData] from [base]. Both the blue +/// and orange variants go through here, so they differ only by palette. +ThemeData buildVsCodeThemeFromPalette(AppPalette base, {String? fontFamily}) { + final palette = fontFamily == null ? base : base.copyWith(uiFontFamily: fontFamily); final radius = BorderRadius.circular(palette.cornerRadius); OutlineInputBorder outline(Color color) => OutlineInputBorder( @@ -131,25 +156,25 @@ ThemeData buildVsCodeDarkTheme({String? fontFamily}) { titleMedium: boldText, titleSmall: boldText, ), - colorScheme: const ColorScheme.dark( - primary: _VsCodeDark.accent, - onPrimary: _VsCodeDark.accentText, - secondary: _VsCodeDark.accent, - onSecondary: _VsCodeDark.accentText, - surface: _VsCodeDark.editorBg, - onSurface: _VsCodeDark.foreground, - surfaceContainer: _VsCodeDark.sideBarBg, - surfaceContainerHigh: _VsCodeDark.tabActiveBg, - surfaceContainerHighest: _VsCodeDark.tabActiveBg, - error: Color(0xFFF48771), - onError: _VsCodeDark.accentText, - tertiaryContainer: _VsCodeDark.accentSoft, - onTertiaryContainer: _VsCodeDark.foreground, - errorContainer: Color(0xFF5A1D1D), - onErrorContainer: Color(0xFFFFB4AB), - primaryContainer: _VsCodeDark.accentSoft, - onPrimaryContainer: _VsCodeDark.foreground, - outline: _VsCodeDark.border, + colorScheme: ColorScheme.dark( + primary: palette.accent, + onPrimary: palette.onAccent, + secondary: palette.accent, + onSecondary: palette.onAccent, + surface: palette.surface, + onSurface: palette.text, + surfaceContainer: palette.surfaceRecessed, + surfaceContainerHigh: palette.surfaceRaised, + surfaceContainerHighest: palette.surfaceRaised, + error: const Color(0xFFF48771), + onError: palette.onAccent, + tertiaryContainer: palette.accentSoft, + onTertiaryContainer: palette.text, + errorContainer: const Color(0xFF5A1D1D), + onErrorContainer: const Color(0xFFFFB4AB), + primaryContainer: palette.accentSoft, + onPrimaryContainer: palette.text, + outline: palette.border, ), dialogTheme: DialogThemeData( backgroundColor: palette.surfaceRaised, @@ -334,3 +359,17 @@ class VsCodeDarkTheme implements AppTheme { @override ThemeData get themeData => buildVsCodeDarkTheme(fontFamily: fontFamily); } + +/// [AppTheme] wrapper around [buildVsCodeOrangeTheme] for theme registries. +class VsCodeOrangeTheme implements AppTheme { + const VsCodeOrangeTheme({this.fontFamily}); + + /// Overrides the default `.AppleSystemUIFont` — pass any platform font. + final String? fontFamily; + + @override + String get name => 'dbscope Orange'; + + @override + ThemeData get themeData => buildVsCodeOrangeTheme(fontFamily: fontFamily); +}