Skip to content

Match graph canvas to industrial properties theme - #744

Draft
Leonhardmaster2 wants to merge 2 commits into
devfrom
feat/industrial-graph-theme
Draft

Leonhardmaster2 wants to merge 2 commits into
devfrom
feat/industrial-graph-theme

Conversation

@Leonhardmaster2

Copy link
Copy Markdown
Contributor

When the industrial properties design is active, the graph canvas now uses the same resolved meta::qt::Theme for node card surfaces, caption/icon/comment inks, borders, canvas background, and selection accent. Clear the category header-fill override in this mode so it cannot replace the shared neutral card surface. Typed ports and links retain their semantic data colours; fallback links use secondary ink and selected links use the theme accent.

Use the panel's section_card_radius for the shared node header/body outline and 1px ordinary/hover borders. All new assignments are guarded by properties_panel_design().has_own_chrome, leaving the stock style path intact. No GNodeGUI source or submodule revision changes are included.

Optional bevels and the currently hardcoded port-label ink are a separate upstream proposal: ottolink-dev/GNodeGUI#11. The 4px control radius and machined thumb gradients belong to embedded control renderers, not node cards.

Validation: build_hesiod.bat passed with existing dependency warnings; run_hesiod.bat launched the built executable and the process was confirmed running. git diff --check passed. Visual review is delegated to the user because screen capture is unavailable: compare canvas/card neutrals with the panel, inspect selection and hover, typed connections, pinned nodes and icons; restart with the stock design to check the original appearance. No visual approval is claimed.

The first pass cleared color_category so the saturated Solarized hues
would not fill a node header against the neutral card surface. That was
the right observation and the wrong remedy: it also cost what those
colours are for, which is telling an erosion node from a noise node at a
glance across the canvas.

Each category colour is blended towards the card instead, so a header is
a tinted neutral rather than a saturated slab. Categories stay apart
side by side and a canvas full of nodes still reads as one surface.

This is what the panel already does. A group accent there is a small
saturated mark against neutral chrome, never a whole surface, and Theme
deliberately keeps group_accents out of from_palette() because they
encode which family an operation belongs to rather than tracking a host
accent.
@barrulus
barrulus self-requested a review September 20, 2026 06:03

@barrulus barrulus left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this — the mapping itself is mostly sensible and the stock path is left untouched as promised. A few things need fixing before it can go in, though. First four are behaviour regressions I checked against the pinned GNodeGUI/Meta sources, the rest are placement/cleanup.

Description vs. code: the PR text says the category header fill is cleared in industrial mode, but the code tints it 22 % towards the category colour (and the inline comment says clearing was the abandoned first attempt). Worth updating the description.

Regressions

  1. "Node is computing" feedback is almost gone. GraphicsNode::paint signals computing by halving the header's alpha over the body (graphics_node.cpp:463-471). Body is now section_surface, and the header tint starts from section_header, which theme.hpp:125 documents as always equal to section_surface. So computing turns a 22 % tint into an 11 % tint over the same grey instead of visibly dimming a saturated header. Either tint from a colour that differs from the body, or keep the header darker/lighter than color_bg so the alpha dim has something to show.

  2. Nodes without a category colour lose their header entirely. color_bg_light is set to section_header == body colour, and the header is drawn with Qt::NoPen. Categories that fall through to it (Boundaries, Bridges, Export, Terrain Features are in node_documentation.json but not in the default category_color_map) render as a flat slab with no caption/ports separation. Stock at least had 108 vs 102.

  3. Pinned and selected are now the same colour. Both map to theme.accent, so they differ only by dash pattern, and pinned+selected draws two overlapping accent outlines on the same rect. Stock used cyan vs green for a reason — a second theme colour is needed here.

  4. Selection accent isn't actually shared. group.color_selected / group.color / comment.* keep their Dracula defaults, so with node groups enabled a selected group draws a green (80,250,123) outline next to orange-accented nodes and links.

Placement

  1. Two writers for viewer.color_bg. apply_global_style.cpp:93 already owns the "graph viewer style" block and sets viewer.color_bg = bg_primary. This PR sets it again from the GraphTabsWidget constructor, gated on a setting documented as the properties panel design. Anyone re-running or extending apply_global_style silently reverts the canvas while nodes stay themed, and since industrial is the default, every user's canvas changes with no setting that mentions the canvas. Suggest moving the block into apply_global_style (or a sibling next to properties_panel_design()), and putting the tint ratio on the Theme rather than a constant in a widget ctor.

  2. tint_towards is a copy of Meta's private mix() (MetaUI/qt/src/ui/theme.cpp). It also drops alpha (QColor::fromRgbF defaults to 1.0) and treats an invalid QColor as black, so a translucent or mistyped hex in hesiod.json silently changes meaning instead of failing loudly. Exposing mix() from meta_qt/ui/theme.hpp (or a Theme::tint(surface, accent, t)) and calling that would keep the panel and canvas from drifting.

  3. Library and canvas tint the same category differently. node_library_widget.cpp:182 blends at 50 % alpha over bg_primary; the canvas blends at 22 % towards the card surface. One category now reads as two shades between the tree and the placed node. Sharing one helper and ratio would fix it.

Cleanup

  1. Dead assignments. node.color_icon and node.color_port_selected have no reader in GNodeGUI (33735e9) or Hesiod, and link.color_default is only used when a link is constructed with a transparent colour — every real link comes through get_color_from_data_type. So the "icon ink" claim in the description isn't delivered; either drop these or land the GNodeGUI consumer first.

  2. Minor. color_category is assigned the raw map at line 40 and then overwritten with a copied temporary. Tinting in place after the existing assignment (for (auto &[k, c] : node.color_category) c = mix(...)) removes the extra map and the <map> include, and kCategoryTint can move inside the if.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants