File: tab-frame.cpp

package info (click to toggle)
ares 126-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 32,600 kB
  • sloc: cpp: 356,508; ansic: 20,394; makefile: 16; sh: 2
file content (129 lines) | stat: -rw-r--r-- 3,890 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#if defined(Hiro_TabFrame)

namespace hiro {

static auto CALLBACK TabFrame_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT {
  if(auto tabFrame = (mTabFrame*)GetWindowLongPtr(hwnd, GWLP_USERDATA)) {
    if(auto self = tabFrame->self()) {
      return Shared_windowProc(self->defaultWindowProc, hwnd, msg, wparam, lparam);
    }
  }
  return DefWindowProc(hwnd, msg, wparam, lparam);
}

auto pTabFrame::construct() -> void {
  hwnd = CreateWindow(
    WC_TABCONTROL, L"", WS_CHILD | WS_TABSTOP,
    0, 0, 0, 0, _parentHandle(), nullptr, GetModuleHandle(0), 0
  );
  pWidget::construct();
  SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)TabFrame_windowProc);
  for(auto& item : state().items) append(item);
}

auto pTabFrame::destruct() -> void {
  if(imageList) { ImageList_Destroy(imageList); imageList = nullptr; }
  DestroyWindow(hwnd);
}

auto pTabFrame::append(sTabFrameItem item) -> void {
  wchar_t text[] = L"";
  TCITEM tcItem;
  tcItem.mask = TCIF_TEXT;
  tcItem.pszText = text;
  TabCtrl_InsertItem(hwnd, item->offset(), &tcItem);
  if(auto self = item->self()) {
    self->setClosable(item->state.closable);
    self->setIcon(item->state.icon);
    self->setMovable(item->state.movable);
    self->setText(item->state.text);
    if(item->selected()) self->setSelected();
  }
  _buildImageList();
  _synchronizeSizable();
}

auto pTabFrame::remove(sTabFrameItem item) -> void {
  TabCtrl_DeleteItem(hwnd, item->offset());
  _buildImageList();
}

auto pTabFrame::setEnabled(bool enabled) -> void {
  pWidget::setEnabled(enabled);
  for(auto& item : state().items) {
    if(auto& sizable = item->state.sizable) {
      if(auto self = sizable->self()) self->setEnabled(sizable->enabled());
    }
  }
}

auto pTabFrame::setGeometry(Geometry geometry) -> void {
  pWidget::setGeometry(geometry);
  geometry.setX(geometry.x() + 1);
  geometry.setY(geometry.y() + 21);
  geometry.setWidth(geometry.width() - 4);
  geometry.setHeight(geometry.height() - 23);
  for(auto& item : state().items) {
    if(auto& sizable = item->state.sizable) {
      sizable->setGeometry(geometry);
    }
  }
}

auto pTabFrame::setNavigation(Navigation navigation) -> void {
  //unsupported
}

auto pTabFrame::setVisible(bool visible) -> void {
  pWidget::setVisible(visible);
  for(auto& item : state().items) {
    if(auto& sizable = item->state.sizable) {
      if(auto self = sizable->self()) self->setVisible(sizable->visible(true));
    }
  }
}

//

auto pTabFrame::_buildImageList() -> void {
  u32 size = pFont::size(hfont, " ").height();

  if(imageList) { ImageList_Destroy(imageList); imageList = nullptr; }
  imageList = ImageList_Create(size, size, ILC_COLOR32, 1, 0);
  for(auto& item : state().items) {
    ImageList_Append(imageList, item->state.icon, size);
  }
  TabCtrl_SetImageList(hwnd, imageList);
  for(auto offset : range(state().items.size())) {
    TCITEM tcItem;
    tcItem.mask = TCIF_IMAGE;
    tcItem.iImage = state().items[offset]->state.icon ? offset : -1;
    TabCtrl_SetItem(hwnd, offset, &tcItem);
  }
}

//hide all TabFrameItems, and then display the selected TabFrameItem
auto pTabFrame::_synchronizeSizable() -> void {
  for(auto& item : state().items) {
    if(auto& sizable = item->state.sizable) sizable->setVisible(false);
  }
  //without this call, widgets from the previous tab will remain visible
  //alongside widgets from the newly selected tab for about one frame ...
  Application::processEvents();
  u32 selected = TabCtrl_GetCurSel(hwnd);
  if(auto item = self().item(selected)) {
    if(auto& sizable = item->state.sizable) sizable->setVisible(true);
  }
}

auto pTabFrame::onChange() -> void {
  u32 selected = TabCtrl_GetCurSel(hwnd);
  for(auto& item : state().items) item->state.selected = false;
  if(auto item = self().item(selected)) item->state.selected = true;
  _synchronizeSizable();
  self().doChange();
}

}

#endif