1 /* 2 Copyright © 2020, Inochi2D Project 3 Distributed under the 2-Clause BSD License, see LICENSE file. 4 5 Authors: Luna Nielsen 6 */ 7 module creator.panels; 8 import creator.core; 9 import creator.core.settings; 10 import creator.widgets; 11 import bindbc.imgui; 12 import std.string; 13 import i18n; 14 15 public import creator.panels.logger; 16 17 /** 18 A Widget 19 */ 20 abstract class Panel { 21 private: 22 string name_; 23 string displayName_; 24 bool defaultVisibility; 25 const(char)* windowID; 26 const(char)* displayNamePtr; 27 28 bool drewContents; 29 bool wasVisible; 30 31 protected: 32 ImVec2 panelSpace; 33 abstract void onUpdate(); 34 ImGuiWindowFlags flags; 35 36 void onBeginUpdate() { 37 38 // Try to begin panel 39 flags |= ImGuiWindowFlags.NoCollapse; 40 drewContents = incBegin(windowID, &visible, flags); 41 42 // Handle panel visibility settings save for closing tabs 43 // and skipping content draw 44 if (wasVisible != visible) incSettingsSet(name~".visible", visible); 45 if (!drewContents) return; 46 47 // Setup debug state and such. 48 debug incDebugImGuiState("Panel::onBeginUpdate", 1); 49 igGetContentRegionAvail(&panelSpace); 50 } 51 52 void onEndUpdate() { 53 debug if (drewContents) incDebugImGuiState("Panel::onEndUpdate", -1); 54 incEnd(); 55 56 wasVisible = visible; 57 } 58 59 void onInit() { } 60 61 public: 62 63 /** 64 Whether the panel is visible 65 */ 66 bool visible; 67 68 /** 69 Whether the panel is always visible 70 */ 71 bool alwaysVisible = false; 72 73 /** 74 Constructs a panel 75 */ 76 this(string name, string displayName, bool defaultVisibility) { 77 this.name_ = name; 78 this.displayName_ = displayName; 79 this.visible = defaultVisibility; 80 this.defaultVisibility = defaultVisibility; 81 } 82 83 /** 84 Initializes the Panel 85 */ 86 final void init_() { 87 onInit(); 88 89 // Workaround for the fact that panels are initialized in shared static this 90 this.displayName_ = _(this.displayName_); 91 if (incSettingsCanGet(this.name_~".visible")) { 92 visible = incSettingsGet!bool(this.name_~".visible"); 93 wasVisible = visible; 94 } 95 96 windowID = "%s###%s".format(displayName_, name_).toStringz; 97 displayNamePtr = displayName_.toStringz; 98 } 99 100 final string name() { 101 return name_; 102 } 103 104 final string displayName() { 105 return displayName_; 106 } 107 108 final const(char)* displayNameC() { 109 return displayNamePtr; 110 } 111 112 /** 113 Draws the panel 114 */ 115 final void update() { 116 this.onBeginUpdate(); 117 if (drewContents) this.onUpdate(); 118 this.onEndUpdate(); 119 } 120 121 final bool getDefaultVisibility() { 122 return defaultVisibility; 123 } 124 } 125 126 /** 127 Auto generate panel adder 128 */ 129 template incPanel(T) { 130 static this() { 131 incAddPanel(new T); 132 } 133 } 134 135 /** 136 Adds panel to panel list 137 */ 138 void incAddPanel(Panel panel) { 139 incPanels ~= panel; 140 } 141 142 /** 143 Draws panels 144 */ 145 void incUpdatePanels() { 146 foreach(panel; incPanels) { 147 if (!panel.visible && !panel.alwaysVisible) continue; 148 149 panel.update(); 150 } 151 } 152 153 /** 154 Draws panels 155 */ 156 void incInitPanels() { 157 foreach(panel; incPanels) { 158 panel.init_(); 159 } 160 } 161 162 /** 163 Panel list 164 */ 165 Panel[] incPanels;