Scene Lab
An open source project by FPL.
 All Classes Namespaces Files Functions Pages
editor_gui.h
Go to the documentation of this file.
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SCENE_LAB_EDITOR_GUI_H_
16 #define SCENE_LAB_EDITOR_GUI_H_
17 
18 #include <string.h>
19 #include <memory>
20 #include <set>
21 #include <string>
22 #include <unordered_map>
23 #include "flatui/flatui.h"
24 #include "fplbase/asset_manager.h"
25 #include "fplbase/renderer.h"
26 #include "scene_lab/entity_system_adapter.h"
28 #include "scene_lab_config_generated.h"
29 
30 namespace scene_lab {
31 
32 class SceneLab;
33 
34 /// @file
35 /// EditorGui is a FlatUI-based GUI overlay for Scene Lab to the edit
36 /// window and on-screen menu buttons. Scene Lab can work without the
37 /// GUI but will have very reduced functionality.
38 class EditorGui {
39  public:
40  /// Initialize the user interface. Ensure that you pass the Flatbuffers schema
41  /// you are using (in binary schema format) so FlatbufferEditor knows how to
42  /// present the data. EditorGui will load its own font (specified in the
43  /// config) into an existing FontManager.
44  EditorGui(const SceneLabConfig* config, SceneLab* scene_lab,
45  fplbase::AssetManager* asset_manager,
46  fplbase::InputSystem* input_system, fplbase::Renderer* renderer,
47  flatui::FontManager* font_manager);
48 
49  /// Turn on the GUI. This should be called when Scene Lab is activated.
50  void Activate();
51 
52  /// Turn off the GUI. This should be called when Scene Lab is deactivated.
53  void Deactivate() {}
54 
55  /// Render the GUI, then update based on button presses. You must either call
56  /// this, or call StartRender(), then DrawGui() in a FlatUI gui::Run context,
57  /// then FinishRenderRender(). (only DrawGui() should be inside a FlatUI
58  /// gui::Run context.)
59  void Render();
60 
61  /// Prepare to draw the GUI. You don't need to call this if you are using
62  /// Render(). See DrawGui() for more information.
63 
64  void StartRender();
65  /// Either call Render() above, or call the following sequence if you are
66  /// using FlatUI elsewhere:
67  /// * StartRender();
68  /// * gui::Run(() { ... other Gui... DrawGui(...) };
69  /// * FinishRender();
70  void DrawGui(const mathfu::vec2& virtual_resolution);
71 
72  /// Finish drawing the GUI, and update input. You don't need to call this if
73  /// you are using Render(). See DrawGui() for more information.
74  void FinishRender();
75 
76  /// Is the GUI capturing mouse and/or keyboard input? Returns true if you
77  /// should ignore mouse and keyboard input. Or use mouse_in_window() and
78  /// keyboard_in_use() for more fine-grained control.
79  bool InputCaptured() const { return mouse_in_window() || keyboard_in_use(); }
80 
81  /// Is the mouse pointer over a GUI element? If true, you should ignore mouse
82  /// clicks as the user is clicking on GUI elements instead.
83  bool mouse_in_window() const { return mouse_in_window_; }
84 
85  /// If we've taken ownership of the keyboard (generally when a editable field
86  /// is being edited), this will return true, telling you to ignore keyboard
87  /// input.
88  bool keyboard_in_use() const { return keyboard_in_use_; }
89 
90  /// Should camera movement in Scene Lab be parallel to the ground, so your
91  /// camera's height doesn't change unless you want it to?
92  bool lock_camera_height() const { return lock_camera_height_; }
93 
94  /// Choose which entity we are currently editing.
95  void SetEditEntity(const GenericEntityId& entity);
96  /// Get the entity we are currently editing.
97  GenericEntityId edit_entity() const { return edit_entity_; }
98 
99  /// Clear all cached or modified data that we have for the edit entity. Call
100  /// this if you change any entity data externally, so we can reload data
101  /// directly from the entity.
102  void ClearEntityData() { component_guis_.clear(); }
103  /// Write the entity fields that were changed to the entity_data_ flatbuffer,
104  /// then import the changed flatbuffers back to the edit_entity_.
105  void CommitEntityData();
106 
107  /// Should we let the editor exit? Not if there are pending changes.
108  bool CanExit();
109 
110  /// Should we let the editor deselect this as the current entity?
111  /// Probably not if we've made any changes.
112  bool CanDeselectEntity() const { return !EntityModified(); }
113 
114  /// Has the entity's flatbuffer been modified?
115  bool EntityModified() const {
116  for (auto iter = component_guis_.begin(); iter != component_guis_.end();
117  ++iter) {
118  FlatbufferEditor* editor = iter->second.get();
119  if (editor->flatbuffer_modified()) return true;
120  }
121  return false;
122  }
123 
124  /// "Entity Updated" callback for Scene Lab; if the entity is updated
125  /// externally, we reload its data by calling ClearEntityData().
126  void EntityUpdated(const GenericEntityId& entity);
127 
128  /// Does the user want you to show the current entity's physics?
129  bool show_physics() const { return show_physics_; }
130 
131  /// Returns which mouse mode index we have selected.
132  unsigned int mouse_mode_index() const { return mouse_mode_index_; }
133  /// Set which mouse mode index the user wants to use.
134  void set_mouse_mode_index(int m) { mouse_mode_index_ = m; }
135 
136  const std::string& menu_title_string() { return menu_title_string_; }
137  void set_menu_title_string(const std::string& s) { menu_title_string_ = s; }
138 
139  /// Set whether to expand the given component's data.
140  void SetShowComponentDataView(const GenericComponentId& component, bool b) {
141  components_to_show_[component] = b;
142  }
143 
144  MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
145 
146  private:
147  /// Onscreen buttons IDs.
148  enum GuiButton {
149  kNone = 0,
150  kWindowMaximize,
151  kWindowHide,
152  kWindowRestore,
153  kToggleDataTypes,
154  kToggleExpandAll,
155  kTogglePhysics,
156  kToggleLockCameraHeight,
157  kEntityCommit,
158  kEntityRevert
159  };
160 
161  /// Onscreen tabs for the edit window.
162  enum EditView {
163  kNoEditView = -1,
164  kEditEntity = 0,
165  kEntityList,
166  kEditPrototype,
167  kPrototypeList,
168  kSettings,
169  kEditViewCount
170  };
171  enum WindowState { kNormal, kMaximized };
172 
173  static const int kToolbarHeight = 30;
174  static const int kIndent = 3;
175  static const int kFontSize = 18;
176 
177  /// Commit only the requested component flatbuffer to the entity.
178  void CommitComponentData(const GenericComponentId& component);
179 
180  /// Send an EntityUpdated event to the current entity.
181  void SendUpdateEvent();
182 
183  /// Gui helper function to capture mouse clicks and prevent Scene Lab
184  /// from consuming them.
185  void CaptureMouseClicks();
186 
187  /// Draw an interface for editing an entity.
188  void DrawEditEntityUI();
189  /// Draw an interface for choosing an entity.
190  void DrawEntityListUI();
191  /// Draw an interface for changing editor settings.
192  void DrawSettingsUI();
193  /// Draw an interface for choosing a prototype from a list.
194  void DrawPrototypeListUI();
195  /// Draw a list of all of the component data that this entity has.
196  void DrawEntityComponent(const GenericComponentId& component);
197  /// Draw a list of the entity's parent and children, if any.
198  void DrawEntityFamily();
199 
200  /// Draw tab bars for the different edit views.
201  void DrawTabs();
202 
203  /// Draw common stuff at the beginning of an edit view.
204  void BeginDrawEditView();
205  /// Draw common stuff at the end of an edit view.
206  void FinishDrawEditView();
207 
208  /// Create a text button; call this inside a gui::Run.
209  flatui::Event TextButton(const char* text, const char* id, float size);
210 
211  /// Show a button that, if you click on it, selects an entity.
212  void EntityButton(const GenericEntityId& entity, float size);
213 
214  /// Get the virtual resolution (for FlatUI) of the whole screen.
215  void GetVirtualResolution(mathfu::vec2* resolution_output);
216 
217  /// Get SceneLab's entity system adapter. Convenience function.
218  EntitySystemAdapter* entity_system_adapter();
219 
220  const SceneLabConfig* config_;
221  SceneLab* scene_lab_;
222  fplbase::AssetManager* asset_manager_;
223  fplbase::InputSystem* input_system_;
224  fplbase::Renderer* renderer_;
225  flatui::FontManager* font_manager_;
226 
227  // Which entity we are editing right now.
228  GenericEntityId edit_entity_;
229  // We're changing which entity to select; this will take effect at the
230  // end of rendering.
231  GenericEntityId changed_edit_entity_;
232  std::unordered_map<GenericComponentId, std::unique_ptr<FlatbufferEditor>>
233  component_guis_;
234  GenericComponentId auto_commit_component_;
235  GenericComponentId auto_revert_component_;
236  GenericComponentId auto_recreate_component_;
237 
238  std::unordered_map<GenericComponentId, bool>
239  components_to_show_; // Components to display on screen.
240  std::vector<GenericComponentId> component_list_;
241  std::vector<std::string> prototype_list_; // Currently available protoypes.
242 
243  std::string entity_list_filter_;
244  std::string prototype_list_filter_;
245  std::string menu_title_string_;
246 
247  mathfu::vec4 bg_edit_ui_color_;
248  mathfu::vec4 bg_toolbar_color_;
249  mathfu::vec4 bg_button_color_;
250  mathfu::vec4 bg_hover_color_;
251  mathfu::vec4 bg_click_color_;
252 
253  mathfu::vec4 text_button_color_;
254  mathfu::vec4 text_normal_color_;
255  mathfu::vec4 text_disabled_color_;
256  mathfu::vec4 text_editable_color_;
257  mathfu::vec4 text_modified_color_;
258  mathfu::vec4 text_error_color_;
259 
260  mathfu::vec2 scroll_offset_[kEditViewCount];
261  mathfu::vec2 virtual_resolution_;
262  GuiButton button_pressed_;
263  WindowState edit_window_state_;
264  EditView edit_view_;
265  float edit_width_;
266  int mouse_mode_index_;
267  bool show_physics_; // Are we showing the selected entity's physics?
268  bool show_types_; // Are we showing the type of each field?
269  bool expand_all_; // Expand edit view to encompass the whole screen?
270  bool mouse_in_window_; // Is the mouse currently over a UI element?
271  bool keyboard_in_use_; // Is the user currently typing into an edit field?
272  bool prompting_for_exit_; // Are we currently prompting the user to exit?
273  bool updated_via_gui_; // Was the entity just updated via the GUI?
274  bool lock_camera_height_; // Should camera movement be parallel to ground?
275 };
276 
277 } // namespace scene_lab
278 
279 #endif // SCENE_LAB_EDITOR_GUI_H_
Definition: editor_gui.h:38
bool keyboard_in_use() const
If we've taken ownership of the keyboard (generally when a editable field is being edited)...
Definition: editor_gui.h:88
EditorGui(const SceneLabConfig *config, SceneLab *scene_lab, fplbase::AssetManager *asset_manager, fplbase::InputSystem *input_system, fplbase::Renderer *renderer, flatui::FontManager *font_manager)
Initialize the user interface.
void SetEditEntity(const GenericEntityId &entity)
Choose which entity we are currently editing.
bool CanDeselectEntity() const
Should we let the editor deselect this as the current entity? Probably not if we've made any changes...
Definition: editor_gui.h:112
Definition: scene_lab.h:40
void CommitEntityData()
Write the entity fields that were changed to the entity_data_ flatbuffer, then import the changed fla...
void Render()
Render the GUI, then update based on button presses.
unsigned int mouse_mode_index() const
Returns which mouse mode index we have selected.
Definition: editor_gui.h:132
void DrawGui(const mathfu::vec2 &virtual_resolution)
Either call Render() above, or call the following sequence if you are using FlatUI elsewhere: ...
void FinishRender()
Finish drawing the GUI, and update input.
bool CanExit()
Should we let the editor exit? Not if there are pending changes.
bool lock_camera_height() const
Should camera movement in Scene Lab be parallel to the ground, so your camera's height doesn't change...
Definition: editor_gui.h:92
GenericEntityId edit_entity() const
Get the entity we are currently editing.
Definition: editor_gui.h:97
An on-screen representation of a Flatbuffer, which can be edited by the user.
bool flatbuffer_modified() const
Has the Flatbuffer data been modified? If so, you probably want to reload whatever is using it...
Definition: flatbuffer_editor.h:100
void Activate()
Turn on the GUI. This should be called when Scene Lab is activated.
void ClearEntityData()
Clear all cached or modified data that we have for the edit entity.
Definition: editor_gui.h:102
bool mouse_in_window() const
Is the mouse pointer over a GUI element? If true, you should ignore mouse clicks as the user is click...
Definition: editor_gui.h:83
bool show_physics() const
Does the user want you to show the current entity's physics?
Definition: editor_gui.h:129
bool InputCaptured() const
Is the GUI capturing mouse and/or keyboard input? Returns true if you should ignore mouse and keyboar...
Definition: editor_gui.h:79
void set_mouse_mode_index(int m)
Set which mouse mode index the user wants to use.
Definition: editor_gui.h:134
void StartRender()
Prepare to draw the GUI.
bool EntityModified() const
Has the entity's flatbuffer been modified?
Definition: editor_gui.h:115
void EntityUpdated(const GenericEntityId &entity)
"Entity Updated" callback for Scene Lab; if the entity is updated externally, we reload its data by c...
void SetShowComponentDataView(const GenericComponentId &component, bool b)
Set whether to expand the given component's data.
Definition: editor_gui.h:140
void Deactivate()
Turn off the GUI. This should be called when Scene Lab is deactivated.
Definition: editor_gui.h:53
Definition: flatbuffer_editor.h:43