Skip to content

fix(gui): shrink the per-network connect button and name its network - #683

Merged
got3nks merged 5 commits into
amule-org:masterfrom
LSalami:connect-button-polish
Jul 29, 2026
Merged

fix(gui): shrink the per-network connect button and name its network#683
got3nks merged 5 commits into
amule-org:masterfrom
LSalami:connect-button-polish

Conversation

@LSalami

@LSalami LSalami commented Jul 28, 2026

Copy link
Copy Markdown

Follow-up to the #663/#677 review feedback ngosang left on #402 after the per-tab connect/disconnect toggle landed:

I think the button and the icon are too big and too close to the borders of the tab container. Just reduce the size and some padding.
Since the button is in the same place in both tabs [...] for me it's not clear what I'm disconnecting. Could you change the text to make it "Disconnect/Connect ED2K" or "Disconnect/Connect Kad"?

Changes

  • Icon size: connButImg's source pixel data is an inconsistent 32x32 (off/connected) vs 16x16 (connecting). SetConnectButtonState now scales all three to a uniform, FromDIP-aware size (so it stays crisp on HiDPI/Retina) rather than reworking the XPM data, and caches the three scaled bitmaps as statics instead of rescaling on every connection-state update.
  • Padding: the ED2K/Kad tabs' top row (containing the button) had no border and sat flush against the tab strip. Added Border(wxTOP, 5).
  • Label: SetConnectButtonState gained a networkName parameter, so the label now reads "Connect ED2K" / "Disconnect Kad" / "Cancel ED2K" etc. instead of the bare, ambiguous "Connect"/"Disconnect"/"Cancel". _("ED2K") / _("Kad") reuse the same translatable strings as the tab labels, so a translation stays consistent between the two.
  • Icon-label gap: SetBitmapMargins() is a real gap on wxMSW and wxOSX (both override DoSetBitmapMargins) but a silent no-op on wxGTK, which inherits the base class's empty implementation -- the previous comment here had this backwards (said only wxOSX implements it). Now calls SetBitmapMargins() on the ports that support it and keeps the old leading-space trick only for wxGTK.
  • Kad tab layout: dropped the two-column wxFlexGridSizer (graph in one column, "Bootstrap"/"New node" boxes in the other) in favor of the same vertical shape serverListDlgUp already uses: top row, full-width primary area (the graph, now with the full tab width instead of half), then a full-width manual-entry row below. That row also collapses the four-octet ID_NODE_IP1..4 fields into a single IP text field, matching the eD2k tab's IDC_IPADDRESS -- easier to read and paste. OnBnClickedBootstrapClient now splits that one field on . instead of reading four controls (still reverses the octets before StringIPtoUint32, same as before, since that function returns anti-host order and Kad wants host order).
  • Dead code removal: two buttons turned out to be redundant --

po/*.po regenerated via scripts/update-po.sh each time a commit touched a translatable string.

Testing

Built amule and amulegui clean on Windows (MSYS2/MinGW-w64). clang-format v18 applied via the exact CI image (ghcr.io/jidicula/clang-format:18 -- a substitute image with the same version string but a different point release, xianpengshen/clang-tools:18, disagreed with CI on a destructor-spacing edge case in an earlier push; fixed and confirmed idempotent against the real image).

Fixes #402 (follow-up review comments).

@ngosang

ngosang commented Jul 28, 2026

Copy link
Copy Markdown
Member

@LSalami I think this button does the same thing as connect and it can be removed too (if you didn't already)
imagen

@ngosang

ngosang commented Jul 28, 2026

Copy link
Copy Markdown
Member

Another improvement could be this. In ed2k tab we have this after the table
imagen
In the kad tab we could have a similar layout and use more space horizontal space for the graph. Also have the IP address in jut one field. It's easier to copy than 4 separated fields...
imagen

LSalami added a commit to LSalami/amule that referenced this pull request Jul 29, 2026
ngosang noted on amule-org#402/amule-org#683 that this button looked like it duplicated
Connect. Confirmed: OnBnClickedBootstrapKnown called the exact same
theApp->StartKad() as the Kad tab's own Connect/Cancel/Disconnect
toggle when off, so it was a second control for the same action
rather than a distinct one -- removed.
@LSalami

LSalami commented Jul 29, 2026

Copy link
Copy Markdown
Author

I think this button does the same thing as connect and it can be removed too

Confirmed and removed -- OnBnClickedBootstrapKnown called the exact same theApp->StartKad() the Connect toggle already calls when off, so it was a second control for the same action. Dropped the button, its event handler, and the ID; po/*.po regenerated to drop the now-unused strings.

Another improvement could be this [...] use more space horizontal space for the graph. Also have the IP address in jut one field.

Good idea, but I'd rather keep it out of this PR -- it's a real layout redesign (graph sizing, collapsing the 4-field IP entry into one, matching your WebUI reference) rather than a fix to what's already here, and this PR is getting long enough as review feedback accumulates. Happy to pick it up as a follow-up once this one's settled, or if you'd rather open a tracking issue for it that works too.

Rebuilt clean, clang-format v18 applied, po regenerated, pushed.

@LSalami
LSalami force-pushed the connect-button-polish branch from b22b026 to d8b2476 Compare July 29, 2026 05:25
LSalami added a commit to LSalami/amule that referenced this pull request Jul 29, 2026
ngosang noted on amule-org#402/amule-org#683 that this button looked like it duplicated
Connect. Confirmed: OnBnClickedBootstrapKnown called the exact same
theApp->StartKad() as the Kad tab's own Connect/Cancel/Disconnect
toggle when off, so it was a second control for the same action
rather than a distinct one -- removed.
@got3nks

got3nks commented Jul 29, 2026

Copy link
Copy Markdown

Reviewed and built this on three platforms at d8b247639 — macOS ARM64 (wx 3.3.2), Ubuntu ARM64 (wxGTK3 3.2.9) and Windows ARM64 (MSYS2 CLANGARM64), monolithic. All clean: Linux zero errors and six pre-existing wxGTK header warnings, Windows zero warnings.

Both removals verified. ID_BUTTONCONNECT really was inert — on master it appears only in the AddTool call and the #define, with no EVT_TOOL, no EVT_MENU, no dynamic Bind. One caution on the reasoning: "no EVT_TOOL binding" isn't sufficient on its own, since wxWidgets aliases wxEVT_TOOL to wxEVT_MENU and amuleDlg.cpp deliberately double-binds every other toolbar ID both ways — an EVT_MENU-only binding would have slipped past that check. ID_KNOWNNODECONNECT is a genuine alias as you found, and ID_NODECONNECTBootstrapKad(ip, port) is correctly left alone.

Please fold the Bootstrap removal into the PR body. It's explained in the thread, but the body's "Dead code removal" section still covers only the toolbar button, and the body is what survives as the record for whoever reads this later.

The SetBitmapMargins() comment is wrong about Windows, which matters because it's the stated reason for the leading-space trick. DoSetBitmapMargins is overridden in wx/msw/anybutton.h as well as wx/osx/anybutton.hwxGTK is the only port that inherits the base-class no-op. The visible consequence, comparing the built binaries side by side: the icon-to-label gap on Windows differs noticeably from Linux and macOS, because the spacing is the toolkit's own margin (native BUTTON_IMAGELIST placement on MSW, none at the wx level on GTK, wxOSX's own on Mac) plus a space glyph whose width follows the platform button font. The approach can't produce a consistent gap by construction. Suggest SetBitmapMargins() on the two ports that implement it, keeping the space or GTK-side padding only for GTK — which also drops the "space outside the translatable string" trick, which quietly depends on no translator trimming leading whitespace.

On the Kad tab layout: I'm with ngosang, and I'd like it done rather than deferred to a tracking issue. Concretely, KadDlg's item1 is a two-column wxFlexGridSizer with the graph in column 0 and the Bootstrap box in column 1. Dropping that and stacking vertically gives the graph the full width, with the Bootstrap / New node form as a full-width row underneath the legend labels — which is exactly the shape serverListDlgUp already has on the ED2K side (top row, full-width list, then the horizontal Name / IP / Port row). Worth doing the single IP field in the same pass: ED2K uses one IDC_IPADDRESS control, Kad splits it across ID_NODE_IP1..4, and collapsing it also simplifies OnBnClickedBootstrapClient, which currently re-joins the four fields with dots before StringIPtoUint32. If you'd rather not grow this PR further, a follow-up PR straight after is fine — but let's not park it as an issue.

Two more things to fix in this PR. ScaledConnButImg hard-codes 16x16 physical pixels, so a HiDPI display discards the 32x32 source that would otherwise serve as the 2x representation — please scale with FromDIP(16) instead. It would be the first use of FromDIP in the tree, which is fine; the icon is new code and shouldn't ship blurry on Retina and high-DPI Windows. And please cache the scaled bitmaps: the ConvertToImage + Rescale(wxIMAGE_QUALITY_HIGH) currently runs on every SetConnectButtonState call, i.e. on every connection-state update, and index 2 (connecting) is already 16x16 so it round-trips for nothing. Three statics covering the three states would do it.

LSalami added a commit to LSalami/amule that referenced this pull request Jul 29, 2026
ngosang noted on amule-org#402/amule-org#683 that this button looked like it duplicated
Connect. Confirmed: OnBnClickedBootstrapKnown called the exact same
theApp->StartKad() as the Kad tab's own Connect/Cancel/Disconnect
toggle when off, so it was a second control for the same action
rather than a distinct one -- removed.
LSalami added a commit to LSalami/amule that referenced this pull request Jul 29, 2026
… tab

Addresses got3nks's remaining PR amule-org#683 review items:

- SetBitmapMargins() now used on wxMSW/wxOSX (both implement
  DoSetBitmapMargins); the old comment had this backwards, claiming
  only wxOSX did. wxGTK keeps the leading-space trick since it's the
  actual no-op port.
- ScaledConnButImg scales via FromDIP and caches the three resulting
  bitmaps as statics instead of rescaling on every SetConnectButtonState
  call (previously on every connection-state update).
- Kad tab: dropped the two-column layout (graph | bootstrap box) for
  the same vertical shape serverListDlgUp uses -- full-width graph,
  then a full-width bootstrap-from-node row below. Collapsed the
  ID_NODE_IP1..4 four-octet fields into one, matching the eD2k tab's
  IDC_IPADDRESS.

Verified (build + run, not just compile): the first version of the Kad
redesign crashed reproducibly on tab switch -- amule.exe died inside
COMCTL32.dll (access violation) every time the Kad tab was selected.
Isolated via a stashed before/after comparison: the pre-redesign build
switches to Kad fine, the redesign crashed 100% of the time. Root
cause was the sizer restructuring -- replacing the wxFlexGridSizer that
wrapped the nodes-stats graph with a direct item0->Add() changed the
wrapping depth the graph's OScopeCtrl gets its first layout pass
through. Fixed by keeping the original wrapping (a wxBoxSizer around
the graph's wxStaticBoxSizer, same as before) and only removing the
second column, rather than flattening both. Re-verified clean: Kad tab
switches, populates (Nodes stats, Disconnect Kad, Bootstrap from node
row) and no crash, confirmed against Windows Event Log for Application
Error entries.
@LSalami
LSalami force-pushed the connect-button-polish branch from d8b2476 to ec13cc5 Compare July 29, 2026 09:50
@LSalami

LSalami commented Jul 29, 2026

Copy link
Copy Markdown
Author

All four addressed.

SetBitmapMargins(): you're right, the comment had it backwards. Now calls SetBitmapMargins() on wxMSW/wxOSX (both override DoSetBitmapMargins) and keeps the leading-space trick only for wxGTK, the actual no-op port.

Icons: ScaledConnButImg now scales via FromDIP and caches the three resulting bitmaps as statics -- computed once, not on every SetConnectButtonState call.

Kad tab redesign: done -- dropped the two-column layout for the same vertical shape serverListDlgUp uses (full-width graph, then a full-width bootstrap row below), and collapsed ID_NODE_IP1..4 into one field matching the eD2k tab's IDC_IPADDRESS.

Bootstrap removal: folded into the PR body now, alongside the toolbar button.

One thing worth flagging since it's exactly the kind of thing you asked me to watch for on the last round: the first version of the Kad redesign had a real crash bug. Switching to the Kad tab reproducibly killed amule.exe inside COMCTL32.dll (access violation) every single time. Caught it by actually running the build and clicking over to the tab rather than trusting a clean compile.

Root-caused by stashing the change and comparing: the pre-redesign build switches to Kad fine, the redesign crashed 100% of the time. The cause was sizer restructuring, not the single-IP-field change or the tooltip on it (both cleared as suspects first) -- replacing the wxFlexGridSizer that used to wrap the nodes-stats graph with a direct item0->Add() changed the wrapping depth the graph's OScopeCtrl gets its first layout pass through, and something in that first layout/paint sequence blew up inside comctl32. Fixed by keeping the original wrapping (a plain wxBoxSizer around the graph's wxStaticBoxSizer, same nesting as before) and only removing the second column, rather than flattening both levels at once. Re-verified clean afterward: switches tabs, populates, no crash, confirmed against Windows Event Log for Application Error entries before and after.

Rebuilt clean, clang-format v18 applied (the real CI image this time), po regenerated, rebased onto current master, force-pushed.

@got3nks

got3nks commented Jul 29, 2026

Copy link
Copy Markdown

All four review points are addressed, and I re-tested the result on three platforms at ec13cc556 — macOS ARM64, Ubuntu ARM64 and Windows ARM64, monolithic, all clean (Windows with zero warnings). The visual check looks good: the graph now uses the full tab width, the bootstrap row beneath it mirrors the ED2K tab, and the single IP field is a clear improvement.

I checked the IP-parsing rewrite for behavioural equivalence rather than taking the comment's word: the old code read fields 1→4 and built d.c.b.a, and the new split rebuilds the same string from octets[3..0], so StringIPtoUint32 receives identical input. Malformed input leaves ip = 0 and falls into the existing "Invalid ip to bootstrap" branch.

This needs a rebase before it can go in. Master moved after your last one — #689 landed and touched src/muuli_wdr.cpp along with all the catalogs, so this now shows as conflicting. Could you rebase onto current master and re-run ./scripts/update-po.sh? CI was green on ec13cc556, so I'd expect it back green once the conflicts clear.

Since you'll be pushing again anyway, it'd be good to fold these three in rather than leaving them for a follow-up:

Drop the explicit SetBitmapMargins() on wxMSW and keep it wxOSX-only. The icon gap still reads differently on Windows than on macOS, because the same value means different things per port: wxOSX stores it as the margins around the bitmap, so 4 px lands on both sides including between icon and button edge, while wxMSW applies it between bitmap and label only. On top of that, the Windows default being overridden is font-derived — m_margin.x = GetCharWidth(); m_margin.y = GetCharHeight() / 2; in src/msw/anybutton.cpp — so (4, 0) both narrows the gap and drops the vertical margin to zero, shrinking the button's best height and moving it away from standard Windows button metrics rather than toward them. wx's default is already the native convention there, so the explicit call is only earning its keep on wxOSX. (I checked NeedsOwnerDrawnForImageLayout as well — it only forces owner-drawn mode for wxRIGHT/wxBOTTOM bitmap positions, so the default left-aligned bitmap keeps the native themed control either way.)

Key the bitmap cache by DPI. static wxBitmap cache[3] is filled from whichever button triggers it first, with no wxEVT_DPI_CHANGED invalidation, so a window dragged between differently-scaled monitors on Windows keeps the stale size. The comment documents this, but with per-monitor DPI v2 it's reachable in normal use.

Trim whitespace on the pasted IP. The single field's whole point is easier copy-paste, and a paste carrying a leading or trailing space currently fails with "Invalid ip to bootstrap"; Trim(true).Trim(false) before the split covers it. Minor related note: wxSplit's third parameter defaults to \\ as an escape character — harmless for IPs, but non-obvious to a future reader.

The rest looks good as it stands — ping me when it's rebased and I'll merge.

LSalami added 5 commits July 29, 2026 12:50
…mule-org#402)

Follow-up review feedback on amule-org#663/amule-org#677's per-tab connect/disconnect
toggle: the button/icon were too large and sat flush against the tab
strip, and since the same button occupies the same spot on both the
ED2K and Kad tabs, its label ("Disconnect") didn't say which network
it affects. Icons are now a uniform 16x16 (down from an inconsistent
32x32/16x16 mix), each row gets a top border, and the label now reads
"Connect ED2K" / "Disconnect Kad" / etc.

Also drops the global Connect/Disconnect toolbar button
(ID_BUTTONCONNECT): it lost its click handler somewhere across
the combined both-networks action is still reachable from the tray
icon.
ngosang noted on amule-org#402/amule-org#683 that this button looked like it duplicated
Connect. Confirmed: OnBnClickedBootstrapKnown called the exact same
theApp->StartKad() as the Kad tab's own Connect/Cancel/Disconnect
toggle when off, so it was a second control for the same action
rather than a distinct one -- removed.
…e-equals-default

The previous commit was formatted with a different "clang-format 18"
Docker image (xianpengshen/clang-tools:18, actually 18.1.3) instead of
CI's ghcr.io/jidicula/clang-format:18 (18.1.8) -- they disagree on
~Dtor(){} spacing, which failed both the format check and, since that
line was now "changed", clang-tidy's modernize-use-equals-default.
… tab

Addresses got3nks's remaining PR amule-org#683 review items:

- SetBitmapMargins() now used on wxMSW/wxOSX (both implement
  DoSetBitmapMargins); the old comment had this backwards, claiming
  only wxOSX did. wxGTK keeps the leading-space trick since it's the
  actual no-op port.
- ScaledConnButImg scales via FromDIP and caches the three resulting
  bitmaps as statics instead of rescaling on every SetConnectButtonState
  call (previously on every connection-state update).
- Kad tab: dropped the two-column layout (graph | bootstrap box) for
  the same vertical shape serverListDlgUp uses -- full-width graph,
  then a full-width bootstrap-from-node row below. Collapsed the
  ID_NODE_IP1..4 four-octet fields into one, matching the eD2k tab's
  IDC_IPADDRESS.

Verified (build + run, not just compile): the first version of the Kad
redesign crashed reproducibly on tab switch -- amule.exe died inside
COMCTL32.dll (access violation) every time the Kad tab was selected.
Isolated via a stashed before/after comparison: the pre-redesign build
switches to Kad fine, the redesign crashed 100% of the time. Root
cause was the sizer restructuring -- replacing the wxFlexGridSizer that
wrapped the nodes-stats graph with a direct item0->Add() changed the
wrapping depth the graph's OScopeCtrl gets its first layout pass
through. Fixed by keeping the original wrapping (a wxBoxSizer around
the graph's wxStaticBoxSizer, same as before) and only removing the
second column, rather than flattening both. Re-verified clean: Kad tab
switches, populates (Nodes stats, Disconnect Kad, Bootstrap from node
row) and no crash, confirmed against Windows Event Log for Application
Error entries.
…d IP

Addresses got3nks's final PR amule-org#683 round:

- SetBitmapMargins() means different things per port: wxOSX stores it
  as the margin around the bitmap (a real gap fix there), but wxMSW
  applies it between bitmap and label only, on top of a font-derived
  default (GetCharWidth()/GetCharHeight()) that already matches native
  Windows button metrics -- overriding it moved the button away from
  platform convention rather than toward it. Now wxOSX-only; wxMSW
  keeps its untouched native default, wxGTK keeps the leading-space
  trick (still the only no-op port for this call).
- ScaledConnButImg's cache is now keyed by the FromDIP-resolved
  physical pixel size, not just the state index, so a window dragged
  to a differently-scaled monitor (per-monitor DPI v2) gets a
  freshly-rescaled bitmap instead of a stale one left over from
  wherever it was first computed.
- The Kad tab's single IP field is now Trim()med before wxSplit, so a
  copy-paste carrying leading/trailing whitespace -- the whole point of
  collapsing four fields into one -- no longer fails as "Invalid ip to
  bootstrap".

Rebased onto current master (resolves the amule-org#689 conflict).
@LSalami
LSalami force-pushed the connect-button-polish branch from ec13cc5 to b9082ea Compare July 29, 2026 10:58
@LSalami

LSalami commented Jul 29, 2026

Copy link
Copy Markdown
Author

All three folded in, plus the rebase.

Rebased onto current master (both the #689 and #691 conflicts -- master moved again mid-review -- are resolved; no manual conflicts left in the source, only the usual po/ catalog churn from the regen).

SetBitmapMargins() is now wxOSX-only. Good catch on the per-port semantics -- wxMSW keeps its own native, font-derived default (GetCharWidth()/GetCharHeight()) completely untouched; only wxOSX gets the explicit (4, 0) override, since that's the port where it's actually a margin-around-the-bitmap fix rather than a mismatch with the native convention. wxGTK still gets the leading-space trick, unchanged.

Icon cache is now keyed by physical size, not just state. ScaledConnButImg's cache is a std::map<int, wxBitmap> per state, keyed by the FromDIP-resolved pixel size -- so a window dragged to a differently-scaled monitor gets a freshly-rescaled bitmap for that size instead of reusing whatever was cached from wherever it was first computed. No wxEVT_DPI_CHANGED handler needed; the size-keyed cache means there's nothing stale to invalidate.

Pasted IP is now trimmed. Trim(true).Trim(false) before the wxSplit, so a copy-paste carrying leading/trailing whitespace no longer trips "Invalid ip to bootstrap".

Rebuilt clean, clang-format v18 applied (the real CI image), po regenerated, force-pushed.

@got3nks
got3nks merged commit 09f1b05 into amule-org:master Jul 29, 2026
13 checks passed
@got3nks

got3nks commented Jul 29, 2026

Copy link
Copy Markdown

Merged as 09f1b0546 — thanks for the quick turnaround across four passes, and for digging into the wx internals on the margin question rather than just taking my word for it.

@got3nks

got3nks commented Jul 29, 2026

Copy link
Copy Markdown

Screenshot of the new UI for @ngosang 's review

immagine immagine

@ngosang

ngosang commented Jul 29, 2026

Copy link
Copy Markdown
Member

Thank you both. It looks muuuch better.

@LSalami
LSalami deleted the connect-button-polish branch August 5, 2026 14:12
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.

[GUI] Remove the global Connect/Disconnect button from the amulegui toolbar and move it into the Networks view

3 participants