bsnes/phoenix/windows/widget/tab-frame.cpp

144 lines
4.3 KiB
C++

namespace phoenix {
static LRESULT CALLBACK TabFrame_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
Object* object = (Object*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(object == nullptr) return DefWindowProc(hwnd, msg, wparam, lparam);
TabFrame& tabFrame = (TabFrame&)*object;
return Shared_windowProc(tabFrame.p.windowProc, hwnd, msg, wparam, lparam);
}
void pTabFrame::append(string text, const image& image) {
unsigned selection = TabCtrl_GetItemCount(hwnd);
wchar_t wtext[] = L"";
TCITEM item;
item.mask = TCIF_TEXT;
item.pszText = wtext;
TabCtrl_InsertItem(hwnd, selection, &item);
setText(selection, text);
if(!image.empty()) setImage(selection, image);
}
void pTabFrame::remove(unsigned selection) {
TabCtrl_DeleteItem(hwnd, selection);
buildImageList();
}
void pTabFrame::setEnabled(bool enabled) {
pWidget::setEnabled(enabled);
for(auto& layout : tabFrame.state.layout) {
if(layout) layout->setEnabled(layout->enabled());
}
}
void pTabFrame::setGeometry(Geometry geometry) {
pWidget::setGeometry(geometry);
geometry.x += 1, geometry.width -= 4;
geometry.y += 21, geometry.height -= 23;
for(auto& layout : tabFrame.state.layout) {
if(layout) layout->setGeometry(geometry);
}
}
void pTabFrame::setImage(unsigned selection, const image& image) {
buildImageList();
}
void pTabFrame::setSelection(unsigned selection) {
TabCtrl_SetCurSel(hwnd, selection);
synchronizeLayout();
}
void pTabFrame::setText(unsigned selection, string text) {
utf16_t wtext(text);
TCITEM item;
item.mask = TCIF_TEXT;
item.pszText = (wchar_t*)wtext;
TabCtrl_SetItem(hwnd, selection, &item);
}
void pTabFrame::setVisible(bool visible) {
pWidget::setVisible(visible);
for(auto& layout : tabFrame.state.layout) {
if(layout) layout->setVisible(layout->visible());
}
}
void pTabFrame::constructor() {
hwnd = CreateWindow(WC_TABCONTROL, L"",
WS_CHILD | WS_TABSTOP,
0, 0, 0, 0, parentHwnd, (HMENU)id, GetModuleHandle(0), 0);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)&tabFrame);
windowProc = (WindowProc)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)TabFrame_windowProc);
setDefaultFont();
for(auto& text : tabFrame.state.text) append(text, {});
buildImageList();
setSelection(tabFrame.state.selection);
synchronize();
}
void pTabFrame::destructor() {
if(imageList) { ImageList_Destroy(imageList); imageList = nullptr; }
DestroyWindow(hwnd);
}
void pTabFrame::orphan() {
destructor();
constructor();
}
void pTabFrame::buildImageList() {
if(imageList) ImageList_Destroy(imageList);
unsigned size = pFont::size(hfont, " ").height;
imageList = ImageList_Create(size, size, ILC_COLOR32, 1, 0);
for(auto& image : tabFrame.state.image) {
ImageList_Append(imageList, image, size);
}
TabCtrl_SetImageList(hwnd, imageList);
for(unsigned n = 0; n < tabFrame.state.image.size(); n++) {
TCITEM item;
item.mask = TCIF_IMAGE;
item.iImage = (tabFrame.state.image(n).empty() ? -1 : n);
TabCtrl_SetItem(hwnd, n, &item);
}
}
void pTabFrame::synchronizeLayout() {
unsigned selection = 0;
for(auto& layout : tabFrame.state.layout) {
if(layout) layout->setVisible(selection == tabFrame.state.selection);
selection++;
}
}
void pTabFrame::onChange() {
tabFrame.state.selection = TabCtrl_GetCurSel(hwnd);
synchronizeLayout();
if(tabFrame.onChange) tabFrame.onChange();
}
//called only if TCS_OWNERDRAWFIXED style is used
//this style disables XP/Vista theming of the TabFrame
void pTabFrame::onDrawItem(LPARAM lparam) {
LPDRAWITEMSTRUCT item = (LPDRAWITEMSTRUCT)lparam;
FillRect(item->hDC, &item->rcItem, GetSysColorBrush(COLOR_3DFACE));
SetBkMode(item->hDC, TRANSPARENT);
SetTextColor(item->hDC, GetSysColor(COLOR_BTNTEXT));
unsigned selection = item->itemID;
if(selection < tabFrame.state.text.size()) {
string text = tabFrame.state.text[selection];
Size size = pFont::size(hfont, text);
unsigned width = item->rcItem.right - item->rcItem.left + 1;
if(!tabFrame.state.image[selection].empty()) {
width += size.height + 2;
ImageList_Draw(imageList, selection, item->hDC, item->rcItem.left + (width - size.width) / 2 - (size.height + 3), item->rcItem.top + 2, ILD_NORMAL);
}
TextOut(item->hDC, item->rcItem.left + (width - size.width) / 2, item->rcItem.top + 2, utf16_t(text), text.size());
}
}
}