NAP
imguiservice.h
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4 
5 #pragma once
6 
7 // Local Includes
8 #include "imgui/imgui.h"
9 #include "imguiicon.h"
10 
11 // External includes
12 #include <nap/service.h>
13 #include <renderwindow.h>
14 #include <inputevent.h>
15 #include <nap/resourceptr.h>
16 #include <descriptorsetallocator.h>
17 #include <nap/signalslot.h>
18 #include <color.h>
19 
20 // ImGUI forward declares
21 struct ImGuiContext;
22 
23 namespace nap
24 {
25  // Forward Declares
26  class RenderService;
27  class Display;
28  class GuiWindow;
29  class IMGuiService;
30 
40  namespace icon
41  {
42  inline constexpr const char* save = "save.png";
43  inline constexpr const char* saveAs = "save_as.png";
44  inline constexpr const char* cancel = "cancel.png";
45  inline constexpr const char* ok = "ok.png";
46  inline constexpr const char* del = "delete.png";
47  inline constexpr const char* file = "file.png";
48  inline constexpr const char* help = "help.png";
49  inline constexpr const char* settings = "settings.png";
50  inline constexpr const char* reload = "reload.png";
51  inline constexpr const char* folder = "folder.png";
52  inline constexpr const char* load = "load.png";
53  inline constexpr const char* info = "info.png";
54  inline constexpr const char* warning = "warning.png";
55  inline constexpr const char* error = "error.png";
56  inline constexpr const char* copy = "copy.png";
57  inline constexpr const char* paste = "paste.png";
58  inline constexpr const char* insert = "insert.png";
59  inline constexpr const char* edit = "edit.png";
60  inline constexpr const char* remove = "remove.png";
61  inline constexpr const char* add = "add.png";
62  inline constexpr const char* change = "change.png";
63  inline constexpr const char* subtract = "subtract.png";
64  }
65 
66 
67  // GUI
68  namespace gui
69  {
70  inline constexpr float dpi = 96.0f;
71  inline constexpr int pointerInvalidID = -3;
72  inline constexpr int pointerMouseID = -2;
73  inline constexpr int pointerTouchID = -1;
74 
78  enum class EColorScheme
79  {
80  Light = 0,
81  Dark = 1,
82  HyperDark = 2,
83  Classic = 3,
84  Custom = 4
85  };
86 
90  struct NAPAPI ColorPalette
91  {
92  ColorPalette() = default;
93  RGBColor8 mBackgroundColor = { 0x2D, 0x2D, 0x2D };
94  RGBColor8 mDarkColor = { 0x00, 0x00, 0x00 };
95  RGBColor8 mMenuColor = { 0x8D, 0x8B, 0x84 };
96  RGBColor8 mFront1Color = { 0x8D, 0x8B, 0x84 };
97  RGBColor8 mFront2Color = { 0xAE, 0xAC, 0xA4 };
98  RGBColor8 mFront3Color = { 0xCD, 0xCD, 0xC3 };
99  RGBColor8 mFront4Color = { 0xFF, 0xFF, 0xFF };
100  RGBColor8 mHighlightColor1 = { 0x29, 0x58, 0xff };
101  RGBColor8 mHighlightColor2 = { 0xD6, 0xFF, 0xA3 };
102  RGBColor8 mHighlightColor3 = { 0xFF, 0xEA, 0x30 };
103  RGBColor8 mHighlightColor4 = { 0xFF, 0x50, 0x50 };
104  bool mInvertIcon = false;
105  };
106 
110  struct NAPAPI Style
111  {
112  Style() = default;
113  bool mAntiAliasedLines = true;
114  bool mAntiAliasedFill = true;
115  glm::vec2 mWindowPadding = { 10.0, 10.0f };
116  float mWindowRounding = 0.0f;
117  glm::vec2 mFramePadding = { 5.0f, 5.0f };
118  float mFrameRounding = 0.0f;
119  glm::vec2 mItemSpacing = { 12.0f, 6.0f };
120  glm::vec2 mItemInnerSpacing = { 8.0f, 6.0f };
121  float mIndentSpacing = 25.0f;
122  float mScrollbarSize = 13.0f;
123  float mScrollbarRounding = 0.0f;
124  float mGrabMinSize = 5.0f;
125  float mGrabRounding = 0.0f;
126  float mWindowBorderSize = 0.0f;
127  float mPopupRounding = 0.0f;
128  float mChildRounding = 0.0f;
129  glm::vec2 mWindowTitleAlign = { 0.5f, 0.5f };
130  float mPopupBorderSize = 0.0f;
131  float mTabRounding = 0.0f;
132  glm::vec2 mTouchExtraPadding = { 0.0f, 0.0f };
133  };
134  }
135 
136 
141  {
142  RTTI_ENABLE(ServiceConfiguration)
143  public:
145  float mFontSize = 17.0f;
146  float mScale = 1.0f;
147  std::string mFontFile = "";
148  glm::ivec2 mFontOversampling = { 5, 3 };
149  float mFontSpacing = 0.25f;
152  virtual rtti::TypeInfo getServiceType() const override { return RTTI_OF(IMGuiService); }
153  };
154 
155 
165  class NAPAPI IMGuiService : public Service
166  {
167  RTTI_ENABLE(Service)
168  friend class GuiWindow;
169  public:
173  IMGuiService(ServiceConfiguration* configuration);
174 
199  void draw();
200 
219  void selectWindow(nap::ResourcePtr<RenderWindow> window);
220 
226  ImGuiContext* getContext(nap::ResourcePtr<RenderWindow> window);
227 
233  ImGuiContext* findContext(int windowID);
234 
241  float getScale() const;
242 
250  float getScale(const ImGuiContext* context) const;
251 
256  const gui::ColorPalette& getPalette() const;
257 
262  ImGuiContext* processInputEvent(const InputEvent& event);
263 
267  bool isCapturingKeyboard(ImGuiContext* context);
268 
272  bool isCapturingMouse(ImGuiContext* context);
273 
287  ImTextureID getTextureHandle(const nap::Texture2D& texture) const;
288 
302  nap::Icon& getIcon(std::string&& name);
303 
326  bool loadIcon(const std::string& name, const nap::Module& module, utility::ErrorState& error);
327 
328  protected:
335  virtual bool init(utility::ErrorState& error) override;
336 
341  virtual void getDependentServices(std::vector<rtti::TypeInfo>& dependencies) override;
342 
347  virtual void update(double deltaTime) override;
348 
352  virtual void postUpdate(double deltaTime) override;
353 
357  virtual void preShutdown() override;
358 
362  virtual void shutdown() override;
363 
367  virtual void registerObjectCreators(rtti::Factory& factory) override;
368 
369  private:
370 
375  struct NAPAPI GUIContext
376  {
377  GUIContext(ImGuiContext* context, ImGuiStyle* style);
378  ~GUIContext();
379 
380  using ESource = PointerEvent::ESource;
381  static constexpr int keyCount = 512;
382  using KeyArray = std::array<bool, keyCount>;
383 
384  std::array<bool,3> mMousePressed = { false };
385  std::array<bool,3> mMouseRelease = { false };
386  std::array<bool,3> mModPressed = { false };
387  std::array<bool,3> mModRelease = { false };
388  std::array<int, 3> mPointerID = { gui::pointerInvalidID };
389  KeyArray mKeyPressed = { false };
390  std::vector<int> mKeyRelease;
391  glm::ivec2 mMousePosition = { 0, 0 };
392  float mMouseWheel = 0.0f;
393  float mScale = 1.0f;
394  const Display* mDisplay = nullptr;
395  ImGuiContext* mContext = nullptr;
396  ImGuiContext* mPreviousContext = nullptr;
397  ImGuiStyle* mStyle = nullptr;
398 
399  // Activates current context
400  void activate();
401 
402  // Deactivates current context, restores previous
403  void deactivate();
404  };
405 
409  void onWindowAdded(RenderWindow& window);
410  nap::Slot<RenderWindow&> mWindowAddedSlot = { this, &IMGuiService::onWindowAdded };
411 
415  void onWindowRemoved(RenderWindow& window);
416  nap::Slot<RenderWindow&> mWindowRemovedSlot = { this, &IMGuiService::onWindowRemoved };
417 
421  void onWindowEvent(const WindowEvent& windowEvent);
422  nap::Slot<const WindowEvent&> mWindowEventSlot = { this, &IMGuiService::onWindowEvent };
423 
427  void createVulkanResources(nap::RenderWindow& window);
428 
432  void newFrame(RenderWindow& window, GUIContext& context, double deltaTime);
433 
437  void pushScale(GUIContext& context, const Display& display);
438 
442  void handleKeyEvent(const KeyEvent& keyEvent, GUIContext& context);
443 
447  void handlePointerEvent(const PointerEvent& pointerEvent, GUIContext& context);
448 
452  void handleTouchEvent(const TouchEvent& touchEvent, GUIContext& context);
453 
454  // Everything related to ImGUI
455  RenderService* mRenderService = nullptr;
456  mutable std::unordered_map<const Texture2D*, VkDescriptorSet> mDescriptors;
457  std::unique_ptr<DescriptorSetAllocator> mAllocator;
458  std::unordered_map<RenderWindow*, std::unique_ptr<GUIContext>> mContexts;
459  std::unique_ptr<ImFontAtlas> mFontAtlas = nullptr;
460  std::unique_ptr<ImGuiStyle> mStyle = nullptr;
461  float mGuiScale = 1.0f;
462  float mDPIScale = 1.0f;
463 
464  // Selected colour palette and style
465  IMGuiServiceConfiguration* mConfiguration = nullptr;
466  const gui::ColorPalette* mColorPalette = nullptr;
467 
468  // Icons
469  std::unordered_map<std::string, std::unique_ptr<Icon>> mIcons;
470  };
471 }
nap::gui::EColorScheme::Light
@ Light
Lighter color scheme.
nap::RenderWindow
Definition: renderwindow.h:43
nap::icon::paste
constexpr const char * paste
Definition: imguiservice.h:57
nap::IMGuiServiceConfiguration::getServiceType
virtual rtti::TypeInfo getServiceType() const override
Definition: imguiservice.h:152
nap::RGBColor< uint8 >
nap::icon::add
constexpr const char * add
Definition: imguiservice.h:61
nap::icon::saveAs
constexpr const char * saveAs
Definition: imguiservice.h:43
nap::icon::file
constexpr const char * file
Definition: imguiservice.h:47
nap::gui::pointerMouseID
constexpr int pointerMouseID
Pointer from mouse ID.
Definition: imguiservice.h:72
nap::icon::error
constexpr const char * error
Definition: imguiservice.h:55
nap::Slot
Slot.
Definition: signalslot.h:21
nap::gui::EColorScheme::Dark
@ Dark
Darker color scheme (default)
nap::icon::remove
constexpr const char * remove
Definition: imguiservice.h:60
nap::icon::help
constexpr const char * help
Definition: imguiservice.h:48
nap::icon::subtract
constexpr const char * subtract
Definition: imguiservice.h:63
nap::icon::save
constexpr const char * save
Definition: imguiservice.h:42
nap::gui::pointerTouchID
constexpr int pointerTouchID
Pointer from touch ID.
Definition: imguiservice.h:73
nap::rtti::ObjectPtr
Definition: objectptr.h:154
nap::icon::load
constexpr const char * load
Definition: imguiservice.h:52
nap::icon::insert
constexpr const char * insert
Definition: imguiservice.h:58
nap::icon::edit
constexpr const char * edit
Definition: imguiservice.h:59
nap::gui::EColorScheme
EColorScheme
Definition: imguiservice.h:78
nap::icon::settings
constexpr const char * settings
Definition: imguiservice.h:49
nap::IMGuiServiceConfiguration
Definition: imguiservice.h:140
nap::gui::pointerInvalidID
constexpr int pointerInvalidID
Invalid pointer ID.
Definition: imguiservice.h:71
nap::Display
Definition: renderservice.h:146
nap::icon::warning
constexpr const char * warning
Definition: imguiservice.h:54
nap::ServiceConfiguration
Definition: service.h:28
nap::icon::cancel
constexpr const char * cancel
Definition: imguiservice.h:44
nap::Icon
Definition: imguiicon.h:24
nap::icon::change
constexpr const char * change
Definition: imguiservice.h:62
nap::gui::ColorPalette
Definition: imguiservice.h:90
nap::icon::ok
constexpr const char * ok
Definition: imguiservice.h:45
nap::Texture2D
Definition: texture.h:128
nap::Service
Definition: templateservice.h:8
nap::icon::info
constexpr const char * info
Definition: imguiservice.h:53
nap::gui::EColorScheme::Classic
@ Classic
Classic color scheme.
nap::icon::folder
constexpr const char * folder
Definition: imguiservice.h:51
nap::icon::del
constexpr const char * del
Definition: imguiservice.h:46
nap::IMGuiService
Definition: imguiservice.h:165
nap::rtti::Factory
Definition: factory.h:78
nap::gui::Style
Definition: imguiservice.h:110
nap
Definition: templateapp.h:17
nap::gui::dpi
constexpr float dpi
Default (reference) dpi for gui elements.
Definition: imguiservice.h:70
nap::PointerEvent::ESource
ESource
Definition: inputevent.h:129
nap::icon::reload
constexpr const char * reload
Definition: imguiservice.h:50
nap::icon::copy
constexpr const char * copy
Definition: imguiservice.h:56
nap::rtti::TypeInfo
rttr::type TypeInfo
Definition: typeinfo.h:140
nap::IMGuiServiceConfiguration::mCustomColors
gui::ColorPalette mCustomColors
Property: 'Colors' Color overrides if scheme is set to custom.
Definition: imguiservice.h:150
nap::IMGuiServiceConfiguration::mStyle
gui::Style mStyle
Property: 'Style' Configurable style elements.
Definition: imguiservice.h:151
nap::Module
Definition: modulemanager.h:28
nap::InputEvent
Definition: inputevent.h:27
nap::gui::EColorScheme::Custom
@ Custom
Custom color scheme.
nap::gui::EColorScheme::HyperDark
@ HyperDark
High contrast dark color scheme.