WindowSettingsDemo.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #include <Urho3D/Core/CoreEvents.h>
  4. #include <Urho3D/Engine/Engine.h>
  5. #include <Urho3D/Graphics/Graphics.h>
  6. #include <Urho3D/Graphics/GraphicsEvents.h>
  7. #include <Urho3D/Graphics/Material.h>
  8. #include <Urho3D/Graphics/Model.h>
  9. #include <Urho3D/Graphics/Octree.h>
  10. #include <Urho3D/Graphics/StaticModel.h>
  11. #include <Urho3D/Graphics/Zone.h>
  12. #include <Urho3D/GraphicsAPI/Texture2D.h>
  13. #include <Urho3D/Input/Input.h>
  14. #include <Urho3D/Resource/ResourceCache.h>
  15. #include <Urho3D/UI/Button.h>
  16. #include <Urho3D/UI/CheckBox.h>
  17. #include <Urho3D/UI/DropDownList.h>
  18. #include <Urho3D/UI/LineEdit.h>
  19. #include <Urho3D/UI/Text.h>
  20. #include <Urho3D/UI/ToolTip.h>
  21. #include <Urho3D/UI/UI.h>
  22. #include <Urho3D/UI/UIEvents.h>
  23. #include <Urho3D/UI/Window.h>
  24. #include "WindowSettingsDemo.h"
  25. #include <Urho3D/DebugNew.h>
  26. URHO3D_DEFINE_APPLICATION_MAIN(WindowSettingsDemo)
  27. WindowSettingsDemo::WindowSettingsDemo(Context* context)
  28. : Sample(context)
  29. , uiRoot_(GetSubsystem<UI>()->GetRoot())
  30. {
  31. }
  32. void WindowSettingsDemo::Start()
  33. {
  34. // Execute base class startup
  35. Sample::Start();
  36. // Enable OS cursor
  37. GetSubsystem<Input>()->SetMouseVisible(true);
  38. // Load XML file containing default UI style sheet
  39. auto* cache = GetSubsystem<ResourceCache>();
  40. auto* style = cache->GetResource<XMLFile>("UI/DefaultStyle.xml");
  41. // Set the loaded style as default style
  42. uiRoot_->SetDefaultStyle(style);
  43. // Create window with settings.
  44. InitSettings();
  45. SynchronizeSettings();
  46. SubscribeToEvent(E_SCREENMODE,
  47. [this](StringHash /*eventType*/, const VariantMap& /*eventData*/)
  48. {
  49. SynchronizeSettings();
  50. });
  51. // Set the mouse mode to use in the sample
  52. Sample::InitMouseMode(MM_FREE);
  53. // Create scene
  54. CreateScene();
  55. // Setup viewport
  56. auto* renderer = GetSubsystem<Renderer>();
  57. SharedPtr<Viewport> viewport(new Viewport(context_, scene_, cameraNode_->GetComponent<Camera>()));
  58. renderer->SetViewport(0, viewport);
  59. }
  60. void WindowSettingsDemo::CreateScene()
  61. {
  62. auto* cache = GetSubsystem<ResourceCache>();
  63. scene_ = new Scene(context_);
  64. scene_->CreateComponent<Octree>();
  65. auto* zone = scene_->CreateComponent<Zone>();
  66. zone->SetAmbientColor(Color::WHITE);
  67. // Create 3D object
  68. Node* objectNode = scene_->CreateChild("Object");
  69. objectNode->SetRotation(Quaternion(45.0f, 45.0f, 45.0f));
  70. auto* objectModel = objectNode->CreateComponent<StaticModel>();
  71. objectModel->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
  72. objectModel->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml"));
  73. // Create camera
  74. cameraNode_ = scene_->CreateChild("Camera");
  75. cameraNode_->CreateComponent<Camera>();
  76. cameraNode_->SetPosition(Vector3(0.0f, 0.0f, -4.0f));
  77. // Rotate object
  78. SubscribeToEvent(scene_, E_SCENEUPDATE,
  79. [objectNode](StringHash /*eventType*/, VariantMap& eventData)
  80. {
  81. const float timeStep = eventData[SceneUpdate::P_TIMESTEP].GetFloat();
  82. objectNode->Rotate(Quaternion(0.0f, 20.0f * timeStep, 0.0f), TransformSpace::World);
  83. });
  84. }
  85. void WindowSettingsDemo::InitSettings()
  86. {
  87. auto* graphics = GetSubsystem<Graphics>();
  88. // Create the Window and add it to the UI's root node
  89. window_ = uiRoot_->CreateChild<Window>("Window");
  90. // Set Window size and layout settings
  91. window_->SetPosition(128, 128);
  92. window_->SetMinWidth(300);
  93. window_->SetLayout(LM_VERTICAL, 6, IntRect(6, 6, 6, 6));
  94. window_->SetMovable(true);
  95. window_->SetStyleAuto();
  96. // Create the Window title Text
  97. auto* windowTitle = window_->CreateChild<Text>("WindowTitle");
  98. windowTitle->SetText("Window Settings");
  99. windowTitle->SetStyleAuto();
  100. // Create monitor selector
  101. monitorControl_ = window_->CreateChild<DropDownList>("Monitor");
  102. monitorControl_->SetMinHeight(24);
  103. monitorControl_->SetStyleAuto();
  104. for (int i = 0; i < graphics->GetMonitorCount(); ++i)
  105. {
  106. auto text = MakeShared<Text>(context_);
  107. text->SetText(ToString("Monitor %d", i));
  108. text->SetMinWidth(CeilToInt(text->GetRowWidth(0) + 10));
  109. monitorControl_->AddItem(text);
  110. text->SetStyleAuto();
  111. }
  112. // Create resolution selector
  113. resolutionControl_ = window_->CreateChild<DropDownList>("Resolution");
  114. resolutionControl_->SetMinHeight(24);
  115. resolutionControl_->SetStyleAuto();
  116. auto resolutionPlaceholder = MakeShared<Text>(context_);
  117. resolutionPlaceholder->SetText("[Cannot fill list of resolutions]");
  118. resolutionPlaceholder->SetMinWidth(CeilToInt(resolutionPlaceholder->GetRowWidth(0) + 10));
  119. resolutionControl_->AddItem(resolutionPlaceholder);
  120. resolutionPlaceholder->SetStyleAuto();
  121. // Create fullscreen controller
  122. auto* fullscreenFrame = window_->CreateChild<UIElement>("Fullscreen Frame");
  123. fullscreenFrame->SetMinHeight(24);
  124. fullscreenFrame->SetLayout(LM_HORIZONTAL, 6);
  125. fullscreenControl_ = fullscreenFrame->CreateChild<CheckBox>("Fullscreen Control");
  126. fullscreenControl_->SetStyleAuto();
  127. auto* fullscreenText = fullscreenFrame->CreateChild<Text>("Fullscreen Label");
  128. fullscreenText->SetText("Fullscreen");
  129. fullscreenText->SetMinWidth(CeilToInt(fullscreenText->GetRowWidth(0) + 10));
  130. fullscreenText->SetStyleAuto();
  131. // Create borderless controller
  132. auto* borderlessFrame = window_->CreateChild<UIElement>("Borderless Frame");
  133. borderlessFrame->SetMinHeight(24);
  134. borderlessFrame->SetLayout(LM_HORIZONTAL, 6);
  135. borderlessControl_ = borderlessFrame->CreateChild<CheckBox>("Borderless Control");
  136. borderlessControl_->SetStyleAuto();
  137. auto* borderlessText = borderlessFrame->CreateChild<Text>("Borderless Label");
  138. borderlessText->SetText("Borderless");
  139. borderlessText->SetMinWidth(CeilToInt(borderlessText->GetRowWidth(0) + 10));
  140. borderlessText->SetStyleAuto();
  141. // Create resizable controller
  142. auto* resizableFrame = window_->CreateChild<UIElement>("Resizable Frame");
  143. resizableFrame->SetMinHeight(24);
  144. resizableFrame->SetLayout(LM_HORIZONTAL, 6);
  145. resizableControl_ = resizableFrame->CreateChild<CheckBox>("Resizable Control");
  146. resizableControl_->SetStyleAuto();
  147. auto* resizableText = resizableFrame->CreateChild<Text>("Resizable Label");
  148. resizableText->SetText("Resizable");
  149. resizableText->SetMinWidth(CeilToInt(resizableText->GetRowWidth(0) + 10));
  150. resizableText->SetStyleAuto();
  151. // Create resizable controller
  152. auto* vsyncFrame = window_->CreateChild<UIElement>("V-Sync Frame");
  153. vsyncFrame->SetMinHeight(24);
  154. vsyncFrame->SetLayout(LM_HORIZONTAL, 6);
  155. vsyncControl_ = vsyncFrame->CreateChild<CheckBox>("V-Sync Control");
  156. vsyncControl_->SetStyleAuto();
  157. auto* vsyncText = vsyncFrame->CreateChild<Text>("V-Sync Label");
  158. vsyncText->SetText("V-Sync");
  159. vsyncText->SetMinWidth(CeilToInt(vsyncText->GetRowWidth(0) + 10));
  160. vsyncText->SetStyleAuto();
  161. // Create multi-sample controller from 1 (= 2^0) to 16 (= 2^4)
  162. multiSampleControl_ = window_->CreateChild<DropDownList>("Multi-Sample Control");
  163. multiSampleControl_->SetMinHeight(24);
  164. multiSampleControl_->SetStyleAuto();
  165. for (int i = 0; i <= 4; ++i)
  166. {
  167. auto text = MakeShared<Text>(context_);
  168. text->SetText(i == 0 ? "No MSAA" : ToString("MSAA x%d", 1 << i));
  169. text->SetMinWidth(CeilToInt(text->GetRowWidth(0) + 10));
  170. multiSampleControl_->AddItem(text);
  171. text->SetStyleAuto();
  172. }
  173. // Create "Apply" button
  174. auto* applyButton = window_->CreateChild<Button>("Apply");
  175. applyButton->SetLayout(LM_HORIZONTAL, 6, IntRect(6, 6, 6, 6));
  176. applyButton->SetStyleAuto();
  177. auto* applyButtonText = applyButton->CreateChild<Text>("Apply Text");
  178. applyButtonText->SetAlignment(HA_CENTER, VA_CENTER);
  179. applyButtonText->SetText("Apply");
  180. applyButtonText->SetStyleAuto();
  181. applyButton->SetFixedWidth(CeilToInt(applyButtonText->GetRowWidth(0) + 20));
  182. applyButton->SetFixedHeight(30);
  183. // Apply settings when "Apply" button is clicked
  184. SubscribeToEvent(applyButton, E_RELEASED,
  185. [this, graphics](StringHash /*eventType*/, const VariantMap& /*eventData*/)
  186. {
  187. const unsigned monitor = monitorControl_->GetSelection();
  188. if (monitor == M_MAX_UNSIGNED)
  189. return;
  190. const auto& resolutions = graphics->GetResolutions(monitor);
  191. const i32 selectedResolution = resolutionControl_->GetSelection();
  192. if (selectedResolution >= resolutions.Size())
  193. return;
  194. const bool fullscreen = fullscreenControl_->IsChecked();
  195. const bool borderless = borderlessControl_->IsChecked();
  196. const bool resizable = resizableControl_->IsChecked();
  197. const bool vsync = vsyncControl_->IsChecked();
  198. const unsigned multiSampleSelection = multiSampleControl_->GetSelection();
  199. const int multiSample = multiSampleSelection == M_MAX_UNSIGNED ? 1 : static_cast<int>(1 << multiSampleSelection);
  200. // TODO: Expose these options too?
  201. const bool highDPI = graphics->GetHighDPI();
  202. const bool tripleBuffer = graphics->GetTripleBuffer();
  203. const int width = resolutions[selectedResolution].x_;
  204. const int height = resolutions[selectedResolution].y_;
  205. const int refreshRate = resolutions[selectedResolution].z_;
  206. graphics->SetMode(width, height, fullscreen, borderless, resizable, highDPI, vsync, tripleBuffer, multiSample, monitor, refreshRate);
  207. });
  208. }
  209. void WindowSettingsDemo::SynchronizeSettings()
  210. {
  211. auto* graphics = GetSubsystem<Graphics>();
  212. // Synchronize monitor
  213. const unsigned currentMonitor = graphics->GetMonitor();
  214. monitorControl_->SetSelection(currentMonitor);
  215. // Synchronize resolution list
  216. resolutionControl_->RemoveAllItems();
  217. const auto& resolutions = graphics->GetResolutions(currentMonitor);
  218. for (const IntVector3& resolution : resolutions)
  219. {
  220. auto resolutionEntry = MakeShared<Text>(context_);
  221. resolutionEntry->SetText(ToString("%dx%d, %d Hz", resolution.x_, resolution.y_, resolution.z_));
  222. resolutionEntry->SetMinWidth(CeilToInt(resolutionEntry->GetRowWidth(0) + 10));
  223. resolutionControl_->AddItem(resolutionEntry);
  224. resolutionEntry->SetStyleAuto();
  225. }
  226. // Synchronize selected resolution
  227. const i32 currentResolution = graphics->FindBestResolutionIndex(currentMonitor,
  228. graphics->GetWidth(), graphics->GetHeight(), graphics->GetRefreshRate());
  229. resolutionControl_->SetSelection(currentResolution);
  230. // Synchronize fullscreen and borderless flags
  231. fullscreenControl_->SetChecked(graphics->GetFullscreen());
  232. borderlessControl_->SetChecked(graphics->GetBorderless());
  233. resizableControl_->SetChecked(graphics->GetResizable());
  234. vsyncControl_->SetChecked(graphics->GetVSync());
  235. // Synchronize MSAA
  236. for (unsigned i = 0; i <= 4; ++i)
  237. {
  238. if (graphics->GetMultiSample() == static_cast<int>(1 << i))
  239. multiSampleControl_->SetSelection(i);
  240. }
  241. }