Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/`

Expand Down Expand Up @@ -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

Expand Down
3 changes: 2 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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',
Expand Down
13 changes: 10 additions & 3 deletions packages/dbscope_vscode_dark_plugin/lib/src/theme.dart
Original file line number Diff line number Diff line change
@@ -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;
83 changes: 61 additions & 22 deletions packages/widgets/lib/src/themes/vscode_dark_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
Loading