tab-frame.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #if defined(Hiro_TabFrame)
  2. namespace hiro {
  3. static auto CALLBACK TabFrame_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT {
  4. if(auto tabFrame = (mTabFrame*)GetWindowLongPtr(hwnd, GWLP_USERDATA)) {
  5. if(auto self = tabFrame->self()) {
  6. return Shared_windowProc(self->defaultWindowProc, hwnd, msg, wparam, lparam);
  7. }
  8. }
  9. return DefWindowProc(hwnd, msg, wparam, lparam);
  10. }
  11. auto pTabFrame::construct() -> void {
  12. hwnd = CreateWindow(
  13. WC_TABCONTROL, L"", WS_CHILD | WS_TABSTOP,
  14. 0, 0, 0, 0, _parentHandle(), nullptr, GetModuleHandle(0), 0
  15. );
  16. pWidget::construct();
  17. SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)TabFrame_windowProc);
  18. for(auto& item : state().items) append(item);
  19. }
  20. auto pTabFrame::destruct() -> void {
  21. if(imageList) { ImageList_Destroy(imageList); imageList = nullptr; }
  22. DestroyWindow(hwnd);
  23. }
  24. auto pTabFrame::append(sTabFrameItem item) -> void {
  25. wchar_t text[] = L"";
  26. TCITEM tcItem;
  27. tcItem.mask = TCIF_TEXT;
  28. tcItem.pszText = text;
  29. TabCtrl_InsertItem(hwnd, item->offset(), &tcItem);
  30. if(auto self = item->self()) {
  31. self->setClosable(item->state.closable);
  32. self->setIcon(item->state.icon);
  33. self->setMovable(item->state.movable);
  34. self->setText(item->state.text);
  35. if(item->selected()) self->setSelected();
  36. }
  37. _buildImageList();
  38. _synchronizeSizable();
  39. }
  40. auto pTabFrame::remove(sTabFrameItem item) -> void {
  41. TabCtrl_DeleteItem(hwnd, item->offset());
  42. _buildImageList();
  43. }
  44. auto pTabFrame::setEnabled(bool enabled) -> void {
  45. pWidget::setEnabled(enabled);
  46. for(auto& item : state().items) {
  47. if(auto& sizable = item->state.sizable) {
  48. if(auto self = sizable->self()) self->setEnabled(sizable->enabled());
  49. }
  50. }
  51. }
  52. auto pTabFrame::setGeometry(Geometry geometry) -> void {
  53. pWidget::setGeometry(geometry);
  54. geometry.setX(geometry.x() + 1);
  55. geometry.setY(geometry.y() + 21);
  56. geometry.setWidth(geometry.width() - 4);
  57. geometry.setHeight(geometry.height() - 23);
  58. for(auto& item : state().items) {
  59. if(auto& sizable = item->state.sizable) {
  60. sizable->setGeometry(geometry);
  61. }
  62. }
  63. }
  64. auto pTabFrame::setNavigation(Navigation navigation) -> void {
  65. //unsupported
  66. }
  67. auto pTabFrame::setVisible(bool visible) -> void {
  68. pWidget::setVisible(visible);
  69. for(auto& item : state().items) {
  70. if(auto& sizable = item->state.sizable) {
  71. if(auto self = sizable->self()) self->setVisible(sizable->visible(true));
  72. }
  73. }
  74. }
  75. //
  76. auto pTabFrame::_buildImageList() -> void {
  77. unsigned size = pFont::size(hfont, " ").height();
  78. if(imageList) { ImageList_Destroy(imageList); imageList = nullptr; }
  79. imageList = ImageList_Create(size, size, ILC_COLOR32, 1, 0);
  80. for(auto& item : state().items) {
  81. ImageList_Append(imageList, item->state.icon, size);
  82. }
  83. TabCtrl_SetImageList(hwnd, imageList);
  84. for(auto offset : range(state().items.size())) {
  85. TCITEM tcItem;
  86. tcItem.mask = TCIF_IMAGE;
  87. tcItem.iImage = state().items[offset]->state.icon ? offset : -1;
  88. TabCtrl_SetItem(hwnd, offset, &tcItem);
  89. }
  90. }
  91. //hide all TabFrameItems, and then display the selected TabFrameItem
  92. auto pTabFrame::_synchronizeSizable() -> void {
  93. for(auto& item : state().items) {
  94. if(auto& sizable = item->state.sizable) sizable->setVisible(false);
  95. }
  96. //without this call, widgets from the previous tab will remain visible
  97. //alongside widgets from the newly selected tab for about one frame ...
  98. Application::processEvents();
  99. uint selected = TabCtrl_GetCurSel(hwnd);
  100. if(auto item = self().item(selected)) {
  101. if(auto& sizable = item->state.sizable) sizable->setVisible(true);
  102. }
  103. }
  104. auto pTabFrame::onChange() -> void {
  105. uint selected = TabCtrl_GetCurSel(hwnd);
  106. for(auto& item : state().items) item->state.selected = false;
  107. if(auto item = self().item(selected)) item->state.selected = true;
  108. _synchronizeSizable();
  109. self().doChange();
  110. }
  111. }
  112. #endif