Compare commits

...
Author SHA1 Message Date
ExPikaPaka ebef912049 Move the help links to the action row as round buttons
Review feedback: the two links are easier to find on the panel's action
row than in the header, and the same placement can then be reused for
the rest of the UI.

The icons become the glyph alone, white on a solid teal disc, so they
read as links rather than as more of the panel's grey tool icons. ImGui
clamps an image button's frame rounding to its frame padding, so the
disc is drawn underneath on its own draw-list channel, which also lets
it carry the hover and pressed feedback.
2026-10-05 09:01:37 +02:00
SoftFever 4710ec274f Merge branch 'main' into feature/texdisp-help-links 2026-10-03 20:09:46 +08:00
SoftFever 019f6677b9 Merge branch 'main' into feature/texdisp-help-links 2026-10-02 20:20:06 +08:00
ExPikaPaka 561c9e38e0 Reserve header width for the two new icons 2026-10-02 09:10:46 +02:00
ExPikaPaka 92de8d3eae Link the texture displacement guide and wiki from the gizmo panel
Finding either piece of documentation currently means knowing it exists and
going looking for it outside the application, which is the hardest moment to
do that: the panel has a lot of controls and the feature is new.

Add two borderless icon buttons to the panel header, next to the dock toggle,
opening the video walkthrough and the wiki page in the default browser. Both
icons follow the set's existing convention of a grey outline with a teal
accent, so they read as part of the same panel.
2026-10-02 09:05:35 +02:00
3 changed files with 61 additions and 1 deletions
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M6 4.1 12.2 8 6 11.9z" style="fill:none;stroke:#f2f2f2;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round"/></svg>

After

Width:  |  Height:  |  Size: 216 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><circle cx="8" cy="3.6" r="1" style="fill:#f2f2f2"/><path d="M8 6.6v5.8" style="fill:none;stroke:#f2f2f2;stroke-width:1.8;stroke-linecap:round"/></svg>

After

Width:  |  Height:  |  Size: 235 B

@@ -3396,6 +3396,8 @@ void GLGizmoTextureDisplacement::ensure_panel_icons()
"texture_displacement_adjust.svg", "canvas_drag.svg", "texture_displacement_move_up.svg",
"texture_displacement_move_down.svg", "texture_displacement_drag.svg",
"texture_displacement_select_all.svg", "texture_displacement_erase_all.svg",
// Help links on the action row: the wiki page and the video walkthrough.
"texture_displacement_video_guide.svg", "texture_displacement_wiki.svg",
};
std::vector<std::string> paths;
paths.reserve(names.size());
@@ -5439,6 +5441,47 @@ void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float
m_imgui->tooltip(tip_text, wrap_w);
return clicked;
};
// Round link button: a white glyph on a solid teal disc, for the help links on the action row.
// ImGui clamps an image button's frame rounding to its frame padding, so the disc cannot be the
// button's own background; it is drawn underneath on a separate draw-list channel, which is what
// lets it be filled in after the button has reported its hover state.
const auto link_button = [&](int uid, const std::string &iconfile, float sz, const wxString &label,
const wxString &tip_text) -> bool {
const auto it = m_panel_icon_map.find(iconfile);
const float pad = std::max(1.f, std::round(sz * 0.26f));
ImDrawList *dl = ImGui::GetWindowDrawList();
bool clicked = false;
dl->ChannelsSplit(2);
dl->ChannelsSetCurrent(1);
ImGui::PushID(uid);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.f);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.f, 0.f, 0.f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.f, 0.f, 0.f, 0.f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.f, 0.f, 0.f, 0.f));
if (it != m_panel_icon_map.end() && !it->second.empty() && it->second[0]->is_valid()) {
const IconManager::Icon &ic = *it->second[0];
clicked = m_imgui->image_button((ImTextureID) (intptr_t) ic.tex_id, ImVec2(sz - 2.f * pad, sz - 2.f * pad),
ic.tl, ic.br, int(pad));
} else {
clicked = ImGui::Button(label.ToUTF8().data(), ImVec2(0.f, sz));
}
ImGui::PopStyleColor(3);
ImGui::PopStyleVar();
ImGui::PopID();
// The disc is the button's whole surface, so it has to carry the hover feedback that the
// transparent ImGui background no longer gives: lighter under the cursor, darker while held.
const bool hovered = ImGui::IsItemHovered();
const float lift = ImGui::IsItemActive() ? -0.12f : hovered ? 0.18f : 0.f;
const auto shade = [lift](float c) { return lift >= 0.f ? c + (1.f - c) * lift : c * (1.f + lift); };
const ImVec2 lo = ImGui::GetItemRectMin(), hi = ImGui::GetItemRectMax();
dl->ChannelsSetCurrent(0);
dl->AddCircleFilled(ImVec2(0.5f * (lo.x + hi.x), 0.5f * (lo.y + hi.y)), 0.5f * (hi.y - lo.y),
ImGui::GetColorU32(ImVec4(shade(orca.x), shade(orca.y), shade(orca.z), orca.w)));
dl->ChannelsMerge();
if (!tip_text.empty() && hovered)
m_imgui->tooltip(tip_text, wrap_w);
return clicked;
};
// A short vertical rule between groups of buttons on one row; call it right after an item.
const auto vsep = [&](float h) {
ImGui::SameLine(0.f, gap_s);
@@ -6890,7 +6933,22 @@ void GLGizmoTextureDisplacement::on_render_input_window(float x, float y, float
}
const float button_h = std::round(frame_h * 1.25f);
const float third = std::floor((panel_w - style.ItemSpacing.x) / 3.f);
// The help links lead the action row rather than sitting in the header: this row is the part of
// the panel that is always on screen, so a user who does not yet know the guide exists still
// passes over it on the way to Bake.
if (link_button(807, "texture_displacement_wiki.svg", button_h, _L("Documentation"),
_L("Open the texture displacement page of the OrcaSlicer wiki. Opens in your browser.")))
wxLaunchDefaultBrowser("https://www.orcaslicer.com/wiki/print_prepare/prepare_texture_displacement.html");
ImGui::SameLine(0.f, gap_s);
if (link_button(808, "texture_displacement_video_guide.svg", button_h, _L("Video guide"),
_L("Watch the texture displacement walkthrough on YouTube. Opens in your browser.")))
wxLaunchDefaultBrowser("https://www.youtube.com/watch?v=D7w3tG1kdvE");
ImGui::SameLine();
// Close and Bake keep their 1:2 split, over whatever the links left of the row.
const float links_w = 2.f * button_h + gap_s + style.ItemSpacing.x;
const float third = std::floor((panel_w - links_w - style.ItemSpacing.x) / 3.f);
if (busy) {
if (ImGui::Button((_u8L("Stop") + "##stop").c_str(), ImVec2(third, button_h)))
wxGetApp().plater()->get_ui_job_worker().cancel_all();