latest SDK
This commit is contained in:
178
libPPUI/CEditWithButtons.cpp
Normal file
178
libPPUI/CEditWithButtons.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
#include "stdafx.h"
|
||||
#include "CEditWithButtons.h"
|
||||
|
||||
|
||||
void CEditWithButtons::AddMoreButton(std::function<void()> f) {
|
||||
AddButton(L"more", f, nullptr, L"\x2026");
|
||||
}
|
||||
void CEditWithButtons::AddClearButton(const wchar_t * clearVal, bool bHandleEsc) {
|
||||
std::wstring clearValCopy(clearVal);
|
||||
auto handler = [this, clearValCopy] {
|
||||
this->SetWindowText(clearValCopy.c_str());
|
||||
};
|
||||
auto condition = [clearValCopy](const wchar_t * txt) -> bool {
|
||||
return clearValCopy != txt;
|
||||
};
|
||||
// Present "clear" to accessibility APIs but actually draw a multiplication x sign
|
||||
AddButton(L"clear", handler, condition, L"\x00D7");
|
||||
|
||||
if (bHandleEsc) {
|
||||
this->onEscKey = handler;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CEditWithButtons::AddButton(const wchar_t * str, handler_t handler, condition_t condition, const wchar_t * drawAlternateText) {
|
||||
Button_t btn;
|
||||
btn.handler = handler;
|
||||
btn.title = str;
|
||||
btn.condition = condition;
|
||||
btn.visible = EvalCondition(btn, nullptr);
|
||||
|
||||
if (drawAlternateText != nullptr) {
|
||||
btn.titleDraw = drawAlternateText;
|
||||
}
|
||||
|
||||
m_buttons.push_back(std::move(btn));
|
||||
RefreshButtons();
|
||||
}
|
||||
|
||||
CRect CEditWithButtons::RectOfButton(const wchar_t * text) {
|
||||
for (auto i = m_buttons.begin(); i != m_buttons.end(); ++i) {
|
||||
if (i->title == text && i->wnd != NULL) {
|
||||
CRect rc;
|
||||
if (i->wnd.GetWindowRect(rc)) return rc;
|
||||
}
|
||||
}
|
||||
return CRect();
|
||||
}
|
||||
|
||||
void CEditWithButtons::TabCycleButtons(HWND wnd) {
|
||||
for (auto i = m_buttons.begin(); i != m_buttons.end(); ++i) {
|
||||
if (i->wnd == wnd) {
|
||||
if (IsShiftPressed()) {
|
||||
// back
|
||||
for (;; ) {
|
||||
if (i == m_buttons.begin()) {
|
||||
TabFocusThis(m_hWnd); break;
|
||||
} else {
|
||||
--i;
|
||||
if (i->visible) {
|
||||
TabFocusThis(i->wnd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// forward
|
||||
for (;; ) {
|
||||
++i;
|
||||
if (i == m_buttons.end()) {
|
||||
TabFocusThis(m_hWnd);
|
||||
TabFocusPrevNext(false);
|
||||
break;
|
||||
} else {
|
||||
if (i->visible) {
|
||||
TabFocusThis(i->wnd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CEditWithButtons::ButtonWantTab(HWND wnd) {
|
||||
if (IsShiftPressed()) return true;
|
||||
if (m_buttons.size() == 0) return false; // should not be possible
|
||||
auto last = m_buttons.rbegin();
|
||||
if (wnd == last->wnd) return false; // not for last button
|
||||
return true;
|
||||
}
|
||||
bool CEditWithButtons::EvalCondition(Button_t & btn, const wchar_t * newText) {
|
||||
if (!btn.condition) return true;
|
||||
if (newText != nullptr) return btn.condition(newText);
|
||||
TCHAR text[256] = {};
|
||||
GetWindowText(text, 256);
|
||||
text[255] = 0;
|
||||
return btn.condition(text);
|
||||
}
|
||||
void CEditWithButtons::RefreshConditions(const wchar_t * newText) {
|
||||
bool changed = false;
|
||||
for (auto i = m_buttons.begin(); i != m_buttons.end(); ++i) {
|
||||
bool status = EvalCondition(*i, newText);
|
||||
if (status != i->visible) {
|
||||
i->visible = status; changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
|
||||
void CEditWithButtons::Layout(CSize size, CFontHandle fontSetMe) {
|
||||
if (m_buttons.size() == 0) return;
|
||||
|
||||
int walk = size.cx;
|
||||
|
||||
HDWP dwp = BeginDeferWindowPos((int)m_buttons.size());
|
||||
for (auto iter = m_buttons.rbegin(); iter != m_buttons.rend(); ++iter) {
|
||||
if (!iter->visible) {
|
||||
if (::GetFocus() == iter->wnd) {
|
||||
this->SetFocus();
|
||||
}
|
||||
::DeferWindowPos(dwp, iter->wnd, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOCOPYBITS);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (iter->wnd == NULL) {
|
||||
auto b = std::make_shared< CButtonLite >();
|
||||
iter->buttonImpl = b;
|
||||
b->Create(*this, NULL, iter->title.c_str());
|
||||
if (iter->titleDraw.length() > 0) b->DrawAlternateText(iter->titleDraw.c_str());
|
||||
CFontHandle font = fontSetMe;
|
||||
if (font == NULL) font = GetFont();
|
||||
b->SetFont(font);
|
||||
b->ClickHandler = iter->handler;
|
||||
b->CtlColorHandler = [=](CDCHandle dc) -> HBRUSH {
|
||||
return this->OnColorBtn(dc, NULL);
|
||||
};
|
||||
b->TabCycleHandler = [=](HWND wnd) {
|
||||
TabCycleButtons(wnd);
|
||||
};
|
||||
b->WantTabCheck = [=](HWND wnd) -> bool {
|
||||
return ButtonWantTab(wnd);
|
||||
};
|
||||
if (!IsWindowEnabled()) b->EnableWindow(FALSE);
|
||||
iter->wnd = *b;
|
||||
} else if (fontSetMe) {
|
||||
iter->wnd.SetFont(fontSetMe);
|
||||
}
|
||||
|
||||
unsigned delta = MeasureButton(*iter);
|
||||
int left = walk - delta;
|
||||
|
||||
if (iter->wnd != NULL) {
|
||||
CRect rc;
|
||||
rc.top = 0;
|
||||
rc.bottom = size.cy;
|
||||
rc.left = left;
|
||||
rc.right = walk;
|
||||
::DeferWindowPos(dwp, iter->wnd, NULL, rc.left, rc.top, rc.Width(), rc.Height(), SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOCOPYBITS);
|
||||
}
|
||||
|
||||
walk = left;
|
||||
}
|
||||
EndDeferWindowPos(dwp);
|
||||
this->SetMargins(0, size.cx - walk, EC_RIGHTMARGIN);
|
||||
}
|
||||
|
||||
unsigned CEditWithButtons::MeasureButton(Button_t const & button) {
|
||||
if (m_fixedWidth != 0) return m_fixedWidth;
|
||||
|
||||
return button.buttonImpl->Measure();
|
||||
}
|
||||
Reference in New Issue
Block a user