Cytopia  0.3
A city building simulation game
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BuildMenu.cxx File Reference
#include "BuildMenu.hxx"
#include "imgui.h"
#include "imgui_impl_sdl.h"
#include "imgui_impl_sdlrenderer.h"
#include <UIManager.hxx>
#include <Settings.hxx>
#include <GameStates.hxx>
#include <MapLayers.hxx>
#include <mapEdit.hxx>
#include <tileData.hxx>
#include "../engine/ResourcesManager.hxx"
+ Include dependency graph for BuildMenu.cxx:

Go to the source code of this file.

Namespaces

 detail
 

Functions

float detail::getItemSpan (int deep)
 
template<class Holder >
void drawSubmenu (ImVec2 pos, float categoryOffset, const Holder &holder, BuildMenu *menu, int deep)
 

Function Documentation

◆ drawSubmenu()

template<class Holder >
void drawSubmenu ( ImVec2  pos,
float  categoryOffset,
const Holder &  holder,
BuildMenu menu,
int  deep 
)

Definition at line 59 of file BuildMenu.cxx.

60 {
61  if (holder.getButtons().empty())
62  return;
63 
64  const ImVec2 &frameSize = holder.getButtons().front()->getBtnSize();
65  const float frameFullWidth = frameSize.x + detail::getItemSpan(deep);
66  ImVec2 screenSize = ui::GetIO().DisplaySize;
67 
68  auto &uiManager = UIManager::instance();
69 
70  ImVec2 windowSize;
71  ImVec2 itemSpacing;
72  ImVec2 nextPos;
73  ImVec2 nextOffset{0, 0};
74  bool verticalMenu =
75  (uiManager.buildMenuLayout() == BUILDMENU_LAYOUT::LEFT || uiManager.buildMenuLayout() == BUILDMENU_LAYOUT::RIGHT);
76  itemSpacing = verticalMenu ? itemSpacing = ImVec2(0, detail::getItemSpan(deep)) : ImVec2(detail::getItemSpan(deep), 0);
77  windowSize = verticalMenu ? ImVec2(frameSize.x, frameFullWidth * (float)holder.getButtons().size())
78  : ImVec2(frameFullWidth * (float)holder.getButtons().size(), frameSize.y);
79 
80  switch (uiManager.buildMenuLayout())
81  {
83  nextOffset.y = -categoryOffset;
84  break;
86  nextOffset.y = +categoryOffset;
87  break;
89  nextOffset.x = categoryOffset;
90  break;
91  default:
92  nextOffset.x = -categoryOffset;
93  }
94 
95  const auto &layout = uiManager.getLayouts()["BuildMenuButtons"];
96 
97  ui::SetNextWindowPos(pos);
98  ui::SetNextWindowSize(windowSize);
99 
100  // Set frame style, font size, noborder, transparent
101  ui::PushFont(layout.font);
102  ui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
103  ui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{0, 0});
104  ui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{0, 0});
105  ui::PushStyleVar(ImGuiStyleVar_ItemSpacing, itemSpacing);
106 
107  // every subcaterory is different widget, it need unique id
108  bool open = true;
109  std::string wId = std::string("##BuildMenu_") + holder.getId() + std::to_string(deep);
110  // begin buttons
111  ui::Begin(wId.c_str(), &open,
112  ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoScrollbar |
113  ImGuiWindowFlags_NoScrollWithMouse);
114 
115  // setup screen size cliip rect that handle mouse event outside
116  ui::PushClipRect(ImVec2{0, 0}, screenSize, false);
117  BuildMenuButton::Ptr nextMenuLevel = nullptr;
118  int idx = 0;
119 
120  // draw buttons, each button need unique id
121  std::array<char, 128> id_str = {0};
122  for (auto btn : holder.getButtons())
123  {
124  snprintf(id_str.data(), 128, "%s_%d", holder.getId().c_str(), ++idx);
125 
126  ImVec2 imgPos{btn->m_destRect.x, btn->m_destRect.y};
127  ImVec2 imgSize{btn->m_destRect.z, btn->m_destRect.w};
128 
129  // draw bg | pressed state
130  ImGuiButtonFlags flags = btn->m_open ? ImGuiButtonFlags_ForcePressed : 0;
131  flags |= btn->m_background ? 0 : ImGuiButtonFlags_NoBackground;
132 
133  if (ui::ImageButtonCt(btn->m_tex, flags, frameSize, imgPos, imgSize, btn->m_uv0, btn->m_uv1, -1, ImVec4(0, 0, 0, 0)))
134  {
135  btn->m_open = !btn->m_open;
136  menu->setItemVisible(btn, btn->m_open); // close all other buttons and open only me
137  menu->onClick(btn);
138  }
139 
140  if (ui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && ui::GetHoveredTimer() > menu->getTooltipDelay())
141  {
142  ui::SetTooltip(btn->getId().c_str());
143  }
144 
145  // calc next subcategory position center
146  if (btn->m_open && !btn->getButtons().empty())
147  {
148  nextMenuLevel = btn;
149  const ImVec2 &nextFrameSize = btn->getButtons().front()->getBtnSize();
150  const float nextFrameFullWidth = (verticalMenu ? nextFrameSize.y : nextFrameSize.x) + detail::getItemSpan(deep + 1);
151  const float nextCategoryOffset = (nextFrameFullWidth * (float)btn->getButtons().size()) / 2;
152 
153  switch (uiManager.buildMenuLayout())
154  {
156  nextPos.x = ui::GetCursorScreenPos().x + ((float)(idx - 1) * frameFullWidth) - nextCategoryOffset + frameFullWidth / 2;
157  nextPos.y = pos.y - nextFrameFullWidth;
158  break;
160  nextPos.x = ui::GetCursorScreenPos().x + ((float)(idx - 1) * frameFullWidth) - nextCategoryOffset + frameFullWidth / 2;
161  nextPos.y = pos.y + frameFullWidth + detail::getItemSpan(1);
162  break;
164  nextPos.x = pos.x + frameFullWidth + detail::getItemSpan(1);
165  nextPos.y = ui::GetCursorScreenPos().y - nextCategoryOffset - frameFullWidth / 2;
166  break;
167  default:
168  nextPos.x = pos.x - nextFrameFullWidth;
169  nextPos.y = ui::GetCursorScreenPos().y - nextCategoryOffset - frameFullWidth / 2;
170  break;
171  }
172  }
173 
174  if (!verticalMenu)
175  {
176  ui::SameLine();
177  }
178  }
179 
180  ui::PopClipRect(); // back common clip rect
181 
182  ui::End(); // end buttons
183 
184  ui::PopStyleVar(4);
185  ui::PopFont();
186 
187  if (nextMenuLevel)
188  {
189  drawSubmenu(nextPos, frameSize.y + 10.f, *nextMenuLevel, menu, deep + 1);
190  }
191 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:
BUILDMENU_LAYOUT::BOTTOM
@ BOTTOM
BuildMenu::setItemVisible
void setItemVisible(BuildMenuButton::Ptr btn, bool visible)
Definition: BuildMenu.cxx:292
detail::getItemSpan
float getItemSpan(int deep)
Definition: BuildMenu.cxx:55
BuildMenu::onClick
void onClick(BuildMenuButton::Ptr btn)
Definition: BuildMenu.cxx:317
detail
Definition: BuildMenu.cxx:53
BUILDMENU_LAYOUT::TOP
@ TOP
drawSubmenu
void drawSubmenu(ImVec2 pos, float categoryOffset, const Holder &holder, BuildMenu *menu, int deep)
Definition: BuildMenu.cxx:59
BuildMenuButton::Ptr
std::shared_ptr< BuildMenuButton > Ptr
Definition: BuildMenu.hxx:11
BUILDMENU_LAYOUT::RIGHT
@ RIGHT
BUILDMENU_LAYOUT::LEFT
@ LEFT
Singleton< UIManager >::instance
static UIManager & instance(void)
Get an instance of the singleton.
Definition: Singleton.hxx:15
BuildMenu::getTooltipDelay
float getTooltipDelay() const
Definition: BuildMenu.hxx:102
string
std::string string
Definition: AudioConfig.hxx:14