mirror of
https://github.com/sebastiandine/Card-Collection-Manager-3.git
synced 2026-09-01 23:01:31 +00:00
filter fix (#26)
This commit is contained in:
@@ -62,6 +62,7 @@
|
||||
- Center popup dialogs on the app window (`CentreOnParent()`) so confirmations/info boxes open relative to the current app window.
|
||||
- Include `wxSpinCtrl` in themed input controls (Amount field) or it will keep a mismatched native background.
|
||||
- Do not call `applyNativeClassTheme(..., "DarkMode_Explorer", "Explorer")` for `wxTextCtrl`; on some Windows builds this causes black typed text in dark mode. Keep text inputs palette-driven (`SetThemeEnabled(false)` in dark/high-contrast as needed).
|
||||
- The collection **filter** boxes use `wxTE_RICH2` so typed text can take palette colours on MSW. Do **not** call `SetHint()` on those controls: RichEdit has no cue banner, and wx's fallback writes the hint into `GetValue()`. Use `installTextCtrlPlaceholder` (paints the cue only while empty).
|
||||
- Text inputs are hardened in `Theme.cpp` via `applyPaletteToTextCtrl` / `hardenTextCtrlNativeTheme`: opt the EDIT HWND out of immersive dark mode, clear its visual style, and subclass the **parent** to answer `WM_CTLCOLOREDIT` (that message goes to the parent, not the frame — an earlier frame-level handler never ran for the toolbar filter).
|
||||
- Keep toolbar button behavior stable under dark/high-contrast: avoid changes that break click/tooltip affordances while experimenting with hover contrast fixes.
|
||||
- For dark/high-contrast button readability, do not trust native hover/pressed rendering on Windows; custom state painting in `Theme.cpp` is allowed when native visuals ignore configured colors.
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/statbmp.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/utils.h>
|
||||
@@ -125,7 +126,9 @@ public:
|
||||
auto ids = selectedIds();
|
||||
std::optional<std::vector<std::uint32_t>> keepIds;
|
||||
if (!ids.empty()) keepIds = std::move(ids);
|
||||
suppressListFocus_ = true;
|
||||
rebuildRows(keepIds);
|
||||
suppressListFocus_ = false;
|
||||
}
|
||||
|
||||
void applyTheme(const ThemePalette& palette) {
|
||||
@@ -189,7 +192,8 @@ public:
|
||||
wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED,
|
||||
wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
|
||||
list_->EnsureVisible(row);
|
||||
list_->SetFocus();
|
||||
if (dynamic_cast<wxTextCtrl*>(wxWindow::FindFocus()) == nullptr)
|
||||
list_->SetFocus();
|
||||
}
|
||||
|
||||
// Move the selection by `delta` rows (+1 / -1). Used when Up/Down are
|
||||
@@ -750,7 +754,13 @@ private:
|
||||
if (inRebuild_) return;
|
||||
// Row click / native arrow keys: keep HWND focus on the list. Filter
|
||||
// nudge sets suppressListFocus_ so the caret stays in the text box.
|
||||
if (!suppressListFocus_ && list_ != nullptr) list_->SetFocus();
|
||||
// Also skip the focus grab when any wxTextCtrl already has focus
|
||||
// (covers the deferred CallAfter select that fires after setFilter
|
||||
// has reset suppressListFocus_).
|
||||
if (!suppressListFocus_ && list_ != nullptr) {
|
||||
if (dynamic_cast<wxTextCtrl*>(wxWindow::FindFocus()) == nullptr)
|
||||
list_->SetFocus();
|
||||
}
|
||||
notifySelectionChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@ Theme inferThemeFromWindow(const wxWindow* window);
|
||||
void applyThemeToWindowTree(wxWindow* root, const ThemePalette& palette, Theme theme);
|
||||
// Force palette colors onto a text input (incl. MSW dark-mode typed-text fix).
|
||||
void applyPaletteToTextCtrl(wxTextCtrl* text, const ThemePalette& palette, Theme theme);
|
||||
// Empty-state cue that is never part of GetValue(). Required for wxTE_RICH2 on
|
||||
// MSW: SetHint() has no cue-banner there and wx writes the string as real text.
|
||||
void installTextCtrlPlaceholder(wxTextCtrl* text, const wxString& hint);
|
||||
void themeModalDialog(wxDialog* dlg, Theme theme);
|
||||
int showThemedMessageDialog(wxWindow* parent, const wxString& message, const wxString& caption, long style);
|
||||
int showThemedConfirmDialog(wxWindow* parent, const wxString& message, const wxString& caption);
|
||||
|
||||
@@ -107,8 +107,8 @@ void DigiBattle99GameView::buildSingleCardsToolbar(wxWindow* parent, wxBoxSizer*
|
||||
toolbar->Add(toolbarButtons_[1], 0, wxALIGN_CENTER_VERTICAL | wxALL, 4);
|
||||
toolbar->Add(toolbarButtons_[2], 0, wxALIGN_CENTER_VERTICAL | wxALL, 4);
|
||||
toolbar->AddStretchSpacer(1);
|
||||
filterInput_ = new wxTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, wxSize(260, -1));
|
||||
filterInput_->SetHint(kDigiFilterHint);
|
||||
filterInput_ = new wxTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, wxSize(260, -1), wxTE_RICH2);
|
||||
installTextCtrlPlaceholder(filterInput_, kDigiFilterHint);
|
||||
toolbar->Add(filterInput_, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxTOP | wxBOTTOM, 4);
|
||||
pageSizer->Add(toolbar, 0, wxEXPAND);
|
||||
|
||||
@@ -509,7 +509,6 @@ void DigiBattle99GameView::setFilter(std::string_view filter) {
|
||||
if (filterInput_->GetValue() != wanted) {
|
||||
filterInput_->ChangeValue(wanted);
|
||||
if (filter.empty()) {
|
||||
filterInput_->SetHint(kDigiFilterHint);
|
||||
filterInput_->Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,8 +155,8 @@ void MainFrame::buildLayout() {
|
||||
}
|
||||
toolbar->AddStretchSpacer(1);
|
||||
filterInput_ = new wxTextCtrl(toolbarPanel_, wxID_ANY, "", wxDefaultPosition,
|
||||
wxSize(260, -1));
|
||||
filterInput_->SetHint(kFilterInputHint);
|
||||
wxSize(260, -1), wxTE_RICH2);
|
||||
installTextCtrlPlaceholder(filterInput_, kFilterInputHint);
|
||||
toolbar->Add(filterInput_, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxTOP | wxBOTTOM, 4);
|
||||
toolbarPanel_->SetSizer(toolbar);
|
||||
root->Add(toolbarPanel_, 0, wxEXPAND);
|
||||
@@ -295,7 +295,6 @@ void MainFrame::switchGame(Game g) {
|
||||
if (auto* view = activeView()) {
|
||||
if (filterInput_ != nullptr) {
|
||||
filterInput_->ChangeValue(wxString{});
|
||||
filterInput_->SetHint(kFilterInputHint);
|
||||
filterInput_->Refresh();
|
||||
}
|
||||
view->setFilter("");
|
||||
|
||||
@@ -115,8 +115,8 @@ void PokemonGameView::buildSingleCardsToolbar(wxWindow* parent, wxBoxSizer* page
|
||||
toolbar->Add(toolbarButtons_[1], 0, wxALIGN_CENTER_VERTICAL | wxALL, 4);
|
||||
toolbar->Add(toolbarButtons_[2], 0, wxALIGN_CENTER_VERTICAL | wxALL, 4);
|
||||
toolbar->AddStretchSpacer(1);
|
||||
filterInput_ = new wxTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, wxSize(260, -1));
|
||||
filterInput_->SetHint(kPokeFilterHint);
|
||||
filterInput_ = new wxTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, wxSize(260, -1), wxTE_RICH2);
|
||||
installTextCtrlPlaceholder(filterInput_, kPokeFilterHint);
|
||||
toolbar->Add(filterInput_, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxTOP | wxBOTTOM, 4);
|
||||
pageSizer->Add(toolbar, 0, wxEXPAND);
|
||||
|
||||
@@ -592,7 +592,6 @@ void PokemonGameView::setFilter(std::string_view filter) {
|
||||
if (filterInput_->GetValue() != wanted) {
|
||||
filterInput_->ChangeValue(wanted);
|
||||
if (filter.empty()) {
|
||||
filterInput_->SetHint(kPokeFilterHint);
|
||||
filterInput_->Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
+165
-16
@@ -22,6 +22,8 @@
|
||||
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <cstring>
|
||||
#include <cwchar>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
@@ -229,7 +231,7 @@ std::unordered_set<wxTextCtrl*> gPaletteTextCtrlDestroyBound;
|
||||
|
||||
LRESULT CALLBACK editColorParentSubclass(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
|
||||
UINT_PTR /*subclassId*/, DWORD_PTR /*refData*/) {
|
||||
if (msg == WM_CTLCOLOREDIT) {
|
||||
if (msg == WM_CTLCOLOREDIT || msg == WM_CTLCOLORSTATIC) {
|
||||
const HWND editHwnd = reinterpret_cast<HWND>(lParam);
|
||||
const auto it = gPaletteTextCtrls.find(editHwnd);
|
||||
if (it != gPaletteTextCtrls.end() && it->second != nullptr) {
|
||||
@@ -251,10 +253,22 @@ LRESULT CALLBACK editColorParentSubclass(HWND hwnd, UINT msg, WPARAM wParam, LPA
|
||||
return ::DefSubclassProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
void ensureEditColorParentSubclass(wxTextCtrl* text) {
|
||||
if (text == nullptr) return;
|
||||
const HWND editHwnd = reinterpret_cast<HWND>(text->GetHandle());
|
||||
if (editHwnd == nullptr) return;
|
||||
HWND resolveNativeEditHwnd(wxTextCtrl* text) {
|
||||
if (text == nullptr) return nullptr;
|
||||
const HWND wxHwnd = reinterpret_cast<HWND>(text->GetHandle());
|
||||
if (wxHwnd == nullptr) return nullptr;
|
||||
static const wchar_t* kClasses[] = {
|
||||
L"Edit", L"RICHEDIT50W", L"RichEdit50W", L"RICHEDIT20W", L"RichEdit20W",
|
||||
};
|
||||
for (const wchar_t* cls : kClasses) {
|
||||
HWND child = ::FindWindowExW(wxHwnd, nullptr, cls, nullptr);
|
||||
if (child != nullptr) return child;
|
||||
}
|
||||
return wxHwnd;
|
||||
}
|
||||
|
||||
void ensureEditColorParentSubclass(wxTextCtrl* text, HWND editHwnd) {
|
||||
if (text == nullptr || editHwnd == nullptr) return;
|
||||
gPaletteTextCtrls[editHwnd] = text;
|
||||
if (gPaletteTextCtrlDestroyBound.insert(text).second) {
|
||||
text->Bind(wxEVT_DESTROY, [text, editHwnd](wxWindowDestroyEvent& event) {
|
||||
@@ -271,25 +285,127 @@ void ensureEditColorParentSubclass(wxTextCtrl* text) {
|
||||
}
|
||||
}
|
||||
|
||||
constexpr UINT_PTR kPlaceholderSubclassId = 0x43434d50; // 'CCMP'
|
||||
struct PlaceholderState {
|
||||
wxTextCtrl* text{nullptr};
|
||||
std::wstring hint;
|
||||
};
|
||||
std::unordered_map<HWND, PlaceholderState> gPlaceholders;
|
||||
std::unordered_set<HWND> gPlaceholderSubclassed;
|
||||
|
||||
wxColour mixColours(const wxColour& a, const wxColour& b, int aParts, int total) {
|
||||
const int bParts = total - aParts;
|
||||
auto mix = [&](unsigned char ca, unsigned char cb) -> unsigned char {
|
||||
return static_cast<unsigned char>((static_cast<int>(ca) * aParts +
|
||||
static_cast<int>(cb) * bParts) /
|
||||
total);
|
||||
};
|
||||
return wxColour(mix(a.Red(), b.Red()), mix(a.Green(), b.Green()), mix(a.Blue(), b.Blue()));
|
||||
}
|
||||
|
||||
void paintEmptyPlaceholder(HWND hwnd, HDC suppliedDc) {
|
||||
const auto it = gPlaceholders.find(hwnd);
|
||||
if (it == gPlaceholders.end() || it->second.hint.empty()) return;
|
||||
if (::GetWindowTextLengthW(hwnd) > 0) return;
|
||||
// Native cue banners hide as soon as the caret is in the box, even if empty.
|
||||
const HWND focus = ::GetFocus();
|
||||
if (focus == hwnd) return;
|
||||
if (it->second.text != nullptr && it->second.text->HasFocus()) return;
|
||||
|
||||
HDC hdc = suppliedDc;
|
||||
if (hdc == nullptr) hdc = ::GetDC(hwnd);
|
||||
if (hdc == nullptr) return;
|
||||
|
||||
RECT rc{};
|
||||
::GetClientRect(hwnd, &rc);
|
||||
rc.left += 4;
|
||||
|
||||
wxColour fg(160, 160, 160);
|
||||
wxColour bg(45, 45, 45);
|
||||
if (it->second.text != nullptr) {
|
||||
const wxColour textFg = it->second.text->GetForegroundColour();
|
||||
const wxColour textBg = it->second.text->GetBackgroundColour();
|
||||
if (textFg.IsOk()) fg = textFg;
|
||||
if (textBg.IsOk()) bg = textBg;
|
||||
}
|
||||
const wxColour muted = mixColours(fg, bg, 2, 5);
|
||||
|
||||
const HFONT source = reinterpret_cast<HFONT>(::SendMessageW(hwnd, WM_GETFONT, 0, 0));
|
||||
HFONT hintFont = nullptr;
|
||||
if (source != nullptr) {
|
||||
LOGFONTW lf{};
|
||||
if (::GetObjectW(source, sizeof(lf), &lf) != 0) {
|
||||
// Cue text should read lighter than typed input. RichEdit's WM_GETFONT
|
||||
// is often a heavy face; Segoe UI Light keeps the hint thin on MSW.
|
||||
wcsncpy(lf.lfFaceName, L"Segoe UI Light", LF_FACESIZE - 1);
|
||||
lf.lfFaceName[LF_FACESIZE - 1] = 0;
|
||||
lf.lfWeight = FW_LIGHT;
|
||||
lf.lfItalic = FALSE;
|
||||
lf.lfQuality = CLEARTYPE_QUALITY;
|
||||
if (lf.lfHeight < -1) lf.lfHeight += 1;
|
||||
hintFont = ::CreateFontIndirectW(&lf);
|
||||
}
|
||||
}
|
||||
const HFONT useFont = hintFont != nullptr ? hintFont : source;
|
||||
const HGDIOBJ oldFont = (useFont != nullptr) ? ::SelectObject(hdc, useFont) : nullptr;
|
||||
::SetBkMode(hdc, TRANSPARENT);
|
||||
::SetTextColor(hdc, RGB(muted.Red(), muted.Green(), muted.Blue()));
|
||||
::DrawTextW(hdc, it->second.hint.c_str(), -1, &rc,
|
||||
DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS);
|
||||
if (oldFont != nullptr) ::SelectObject(hdc, oldFont);
|
||||
if (hintFont != nullptr) ::DeleteObject(hintFont);
|
||||
if (suppliedDc == nullptr) ::ReleaseDC(hwnd, hdc);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK placeholderEditSubclass(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
|
||||
UINT_PTR /*subclassId*/, DWORD_PTR /*refData*/) {
|
||||
if (msg == WM_PAINT || msg == WM_PRINTCLIENT) {
|
||||
const LRESULT result = ::DefSubclassProc(hwnd, msg, wParam, lParam);
|
||||
paintEmptyPlaceholder(hwnd, msg == WM_PRINTCLIENT ? reinterpret_cast<HDC>(wParam) : nullptr);
|
||||
return result;
|
||||
}
|
||||
if (msg == WM_SETFOCUS || msg == WM_KILLFOCUS) {
|
||||
const LRESULT result = ::DefSubclassProc(hwnd, msg, wParam, lParam);
|
||||
::InvalidateRect(hwnd, nullptr, TRUE);
|
||||
return result;
|
||||
}
|
||||
if (msg == WM_NCDESTROY) {
|
||||
gPlaceholders.erase(hwnd);
|
||||
gPlaceholderSubclassed.erase(hwnd);
|
||||
::RemoveWindowSubclass(hwnd, placeholderEditSubclass, kPlaceholderSubclassId);
|
||||
}
|
||||
return ::DefSubclassProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
void hardenTextCtrlNativeTheme(wxTextCtrl* text, Theme theme) {
|
||||
if (text == nullptr) return;
|
||||
const bool darkLike = isDarkLikeTheme(theme);
|
||||
text->SetThemeEnabled(!darkLike);
|
||||
|
||||
const HWND hwnd = reinterpret_cast<HWND>(text->GetHandle());
|
||||
if (hwnd == nullptr) return;
|
||||
const HWND wxHwnd = reinterpret_cast<HWND>(text->GetHandle());
|
||||
if (wxHwnd == nullptr) return;
|
||||
|
||||
// Opt this EDIT out of immersive dark mode so typed text uses our palette.
|
||||
HWND editHwnd = resolveNativeEditHwnd(text);
|
||||
|
||||
// Enable native dark mode on the EDIT so its themed renderer paints
|
||||
// light-on-dark. The app-wide preferred mode is already ForceDark
|
||||
// (set in applyFrameTitlebarTheme); individual windows opt in here.
|
||||
// DarkMode_Explorer explicitly selects the dark text variant in the
|
||||
// visual-style theme — plain "Explorer" gave dark background but the
|
||||
// text colour stayed dark on some Windows 10/11 builds.
|
||||
if (auto allowDarkModeForWindow = resolveAllowDarkModeForWindow()) {
|
||||
allowDarkModeForWindow(hwnd, FALSE);
|
||||
allowDarkModeForWindow(editHwnd, darkLike ? TRUE : FALSE);
|
||||
if (editHwnd != wxHwnd)
|
||||
allowDarkModeForWindow(wxHwnd, darkLike ? TRUE : FALSE);
|
||||
}
|
||||
if (darkLike) {
|
||||
if (auto setWindowTheme = resolveSetWindowTheme()) {
|
||||
// Empty theme class disables visual-style painting of the EDIT contents.
|
||||
setWindowTheme(hwnd, L"", L"");
|
||||
}
|
||||
if (auto setWindowTheme = resolveSetWindowTheme()) {
|
||||
const wchar_t* cls = darkLike ? L"DarkMode_Explorer" : L"Explorer";
|
||||
setWindowTheme(editHwnd, cls, nullptr);
|
||||
if (editHwnd != wxHwnd)
|
||||
setWindowTheme(wxHwnd, cls, nullptr);
|
||||
}
|
||||
ensureEditColorParentSubclass(text);
|
||||
::SendMessageW(editHwnd, WM_THEMECHANGED, 0, 0);
|
||||
ensureEditColorParentSubclass(text, editHwnd);
|
||||
::InvalidateRect(editHwnd, nullptr, TRUE);
|
||||
}
|
||||
|
||||
COLORREF toColorRef(const wxColour& c) {
|
||||
@@ -728,9 +844,42 @@ void applyPaletteToTextCtrl(wxTextCtrl* text, const ThemePalette& palette, Theme
|
||||
text->SetForegroundColour(palette.inputText);
|
||||
text->SetOwnBackgroundColour(palette.inputBg);
|
||||
text->SetOwnForegroundColour(palette.inputText);
|
||||
// For RichEdit-backed controls (wxTE_RICH2) the character format must be
|
||||
// set explicitly — SetForegroundColour alone does not propagate to the
|
||||
// native EM_SETCHARFORMAT on all wx builds.
|
||||
wxTextAttr attr;
|
||||
attr.SetTextColour(palette.inputText);
|
||||
text->SetDefaultStyle(attr);
|
||||
if (text->GetLastPosition() > 0)
|
||||
text->SetStyle(0, text->GetLastPosition(), attr);
|
||||
text->Refresh();
|
||||
}
|
||||
|
||||
void installTextCtrlPlaceholder(wxTextCtrl* text, const wxString& hint) {
|
||||
if (text == nullptr) return;
|
||||
#ifdef __WXMSW__
|
||||
// RichEdit (wxTE_RICH2) ignores EM_SETCUEBANNER; wx's SetHint fallback
|
||||
// writes the cue into GetValue(). Paint the hint ourselves when empty.
|
||||
const HWND editHwnd = resolveNativeEditHwnd(text);
|
||||
if (editHwnd == nullptr) {
|
||||
text->CallAfter([text, hint]() { installTextCtrlPlaceholder(text, hint); });
|
||||
return;
|
||||
}
|
||||
gPlaceholders[editHwnd] = PlaceholderState{text, hint.ToStdWstring()};
|
||||
if (gPlaceholderSubclassed.insert(editHwnd).second) {
|
||||
if (::SetWindowSubclass(editHwnd, placeholderEditSubclass, kPlaceholderSubclassId, 0) ==
|
||||
FALSE) {
|
||||
gPlaceholderSubclassed.erase(editHwnd);
|
||||
gPlaceholders.erase(editHwnd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
::InvalidateRect(editHwnd, nullptr, TRUE);
|
||||
#else
|
||||
text->SetHint(hint);
|
||||
#endif
|
||||
}
|
||||
|
||||
void themeModalDialog(wxDialog* dlg, Theme theme) {
|
||||
if (dlg == nullptr) return;
|
||||
const ThemePalette palette = paletteForTheme(theme);
|
||||
|
||||
@@ -159,8 +159,8 @@ void YuGiOhBandaiGameView::buildSingleCardsToolbar(wxWindow* parent, wxBoxSizer*
|
||||
toolbar->Add(toolbarButtons_[1], 0, wxALIGN_CENTER_VERTICAL | wxALL, 4);
|
||||
toolbar->Add(toolbarButtons_[2], 0, wxALIGN_CENTER_VERTICAL | wxALL, 4);
|
||||
toolbar->AddStretchSpacer(1);
|
||||
filterInput_ = new wxTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, wxSize(260, -1));
|
||||
filterInput_->SetHint(kBandaiFilterHint);
|
||||
filterInput_ = new wxTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, wxSize(260, -1), wxTE_RICH2);
|
||||
installTextCtrlPlaceholder(filterInput_, kBandaiFilterHint);
|
||||
toolbar->Add(filterInput_, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxTOP | wxBOTTOM, 4);
|
||||
pageSizer->Add(toolbar, 0, wxEXPAND);
|
||||
|
||||
@@ -537,7 +537,6 @@ void YuGiOhBandaiGameView::setFilter(std::string_view filter) {
|
||||
if (filterInput_->GetValue() != wanted) {
|
||||
filterInput_->ChangeValue(wanted);
|
||||
if (filter.empty()) {
|
||||
filterInput_->SetHint(kBandaiFilterHint);
|
||||
filterInput_->Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,8 +113,8 @@ void YuGiOhGameView::buildSingleCardsToolbar(wxWindow* parent, wxBoxSizer* pageS
|
||||
toolbar->Add(toolbarButtons_[1], 0, wxALIGN_CENTER_VERTICAL | wxALL, 4);
|
||||
toolbar->Add(toolbarButtons_[2], 0, wxALIGN_CENTER_VERTICAL | wxALL, 4);
|
||||
toolbar->AddStretchSpacer(1);
|
||||
filterInput_ = new wxTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, wxSize(260, -1));
|
||||
filterInput_->SetHint(kYgoFilterHint);
|
||||
filterInput_ = new wxTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, wxSize(260, -1), wxTE_RICH2);
|
||||
installTextCtrlPlaceholder(filterInput_, kYgoFilterHint);
|
||||
toolbar->Add(filterInput_, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxTOP | wxBOTTOM, 4);
|
||||
pageSizer->Add(toolbar, 0, wxEXPAND);
|
||||
|
||||
@@ -515,7 +515,6 @@ void YuGiOhGameView::setFilter(std::string_view filter) {
|
||||
if (filterInput_->GetValue() != wanted) {
|
||||
filterInput_->ChangeValue(wanted);
|
||||
if (filter.empty()) {
|
||||
filterInput_->SetHint(kYgoFilterHint);
|
||||
filterInput_->Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user