315 lines
12 KiB
C++
315 lines
12 KiB
C++
//
|
|
// Copyright (c) 2008-2021 the Urho3D project.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
// THE SOFTWARE.
|
|
//
|
|
|
|
#include <Urho3D/Core/CoreEvents.h>
|
|
#include <Urho3D/Engine/Engine.h>
|
|
#include <Urho3D/Graphics/Graphics.h>
|
|
#include <Urho3D/Graphics/GraphicsEvents.h>
|
|
#include <Urho3D/Graphics/Material.h>
|
|
#include <Urho3D/Graphics/Model.h>
|
|
#include <Urho3D/Graphics/Octree.h>
|
|
#include <Urho3D/Graphics/StaticModel.h>
|
|
#include <Urho3D/Graphics/Texture2D.h>
|
|
#include <Urho3D/Graphics/Zone.h>
|
|
#include <Urho3D/Input/Input.h>
|
|
#include <Urho3D/Resource/ResourceCache.h>
|
|
#include <Urho3D/UI/Button.h>
|
|
#include <Urho3D/UI/CheckBox.h>
|
|
#include <Urho3D/UI/DropDownList.h>
|
|
#include <Urho3D/UI/LineEdit.h>
|
|
#include <Urho3D/UI/Text.h>
|
|
#include <Urho3D/UI/ToolTip.h>
|
|
#include <Urho3D/UI/UI.h>
|
|
#include <Urho3D/UI/UIEvents.h>
|
|
#include <Urho3D/UI/Window.h>
|
|
|
|
#include "WindowSettingsDemo.h"
|
|
|
|
#include <Urho3D/DebugNew.h>
|
|
|
|
URHO3D_DEFINE_APPLICATION_MAIN(WindowSettingsDemo)
|
|
|
|
WindowSettingsDemo::WindowSettingsDemo(Context* context)
|
|
: Sample(context)
|
|
, uiRoot_(GetSubsystem<UI>()->GetRoot())
|
|
{
|
|
}
|
|
|
|
void WindowSettingsDemo::Start()
|
|
{
|
|
// Execute base class startup
|
|
Sample::Start();
|
|
|
|
// Enable OS cursor
|
|
GetSubsystem<Input>()->SetMouseVisible(true);
|
|
|
|
// Load XML file containing default UI style sheet
|
|
auto* cache = GetSubsystem<ResourceCache>();
|
|
auto* style = cache->GetResource<XMLFile>("UI/DefaultStyle.xml");
|
|
|
|
// Set the loaded style as default style
|
|
uiRoot_->SetDefaultStyle(style);
|
|
|
|
// Create window with settings.
|
|
InitSettings();
|
|
SynchronizeSettings();
|
|
SubscribeToEvent(E_SCREENMODE,
|
|
[this](StringHash /*eventType*/, const VariantMap& /*eventData*/)
|
|
{
|
|
SynchronizeSettings();
|
|
});
|
|
|
|
// Set the mouse mode to use in the sample
|
|
Sample::InitMouseMode(MM_FREE);
|
|
|
|
// Create scene
|
|
CreateScene();
|
|
|
|
// Setup viewport
|
|
auto* renderer = GetSubsystem<Renderer>();
|
|
SharedPtr<Viewport> viewport(new Viewport(context_, scene_, cameraNode_->GetComponent<Camera>()));
|
|
renderer->SetViewport(0, viewport);
|
|
}
|
|
|
|
void WindowSettingsDemo::CreateScene()
|
|
{
|
|
auto* cache = GetSubsystem<ResourceCache>();
|
|
|
|
scene_ = new Scene(context_);
|
|
scene_->CreateComponent<Octree>();
|
|
|
|
auto* zone = scene_->CreateComponent<Zone>();
|
|
zone->SetAmbientColor(Color::WHITE);
|
|
|
|
// Create 3D object
|
|
Node* objectNode = scene_->CreateChild("Object");
|
|
objectNode->SetRotation(Quaternion(45.0f, 45.0f, 45.0f));
|
|
auto* objectModel = objectNode->CreateComponent<StaticModel>();
|
|
objectModel->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
|
|
objectModel->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml"));
|
|
|
|
// Create camera
|
|
cameraNode_ = scene_->CreateChild("Camera");
|
|
cameraNode_->CreateComponent<Camera>();
|
|
cameraNode_->SetPosition(Vector3(0.0f, 0.0f, -4.0f));
|
|
|
|
// Rotate object
|
|
SubscribeToEvent(scene_, E_SCENEUPDATE,
|
|
[objectNode](StringHash /*eventType*/, VariantMap& eventData)
|
|
{
|
|
const float timeStep = eventData[SceneUpdate::P_TIMESTEP].GetFloat();
|
|
objectNode->Rotate(Quaternion(0.0f, 20.0f * timeStep, 0.0f), TS_WORLD);
|
|
});
|
|
}
|
|
|
|
void WindowSettingsDemo::InitSettings()
|
|
{
|
|
auto* graphics = GetSubsystem<Graphics>();
|
|
|
|
// Create the Window and add it to the UI's root node
|
|
window_ = uiRoot_->CreateChild<Window>("Window");
|
|
|
|
// Set Window size and layout settings
|
|
window_->SetPosition(128, 128);
|
|
window_->SetMinWidth(300);
|
|
window_->SetLayout(LM_VERTICAL, 6, IntRect(6, 6, 6, 6));
|
|
window_->SetMovable(true);
|
|
window_->SetStyleAuto();
|
|
|
|
// Create the Window title Text
|
|
auto* windowTitle = window_->CreateChild<Text>("WindowTitle");
|
|
windowTitle->SetText("Window Settings");
|
|
windowTitle->SetStyleAuto();
|
|
|
|
// Create monitor selector
|
|
monitorControl_ = window_->CreateChild<DropDownList>("Monitor");
|
|
monitorControl_->SetMinHeight(24);
|
|
monitorControl_->SetStyleAuto();
|
|
for (int i = 0; i < graphics->GetMonitorCount(); ++i)
|
|
{
|
|
auto text = MakeShared<Text>(context_);
|
|
text->SetText(ToString("Monitor %d", i));
|
|
text->SetMinWidth(CeilToInt(text->GetRowWidth(0) + 10));
|
|
monitorControl_->AddItem(text);
|
|
text->SetStyleAuto();
|
|
}
|
|
|
|
// Create resolution selector
|
|
resolutionControl_ = window_->CreateChild<DropDownList>("Resolution");
|
|
resolutionControl_->SetMinHeight(24);
|
|
resolutionControl_->SetStyleAuto();
|
|
|
|
auto resolutionPlaceholder = MakeShared<Text>(context_);
|
|
resolutionPlaceholder->SetText("[Cannot fill list of resolutions]");
|
|
resolutionPlaceholder->SetMinWidth(CeilToInt(resolutionPlaceholder->GetRowWidth(0) + 10));
|
|
resolutionControl_->AddItem(resolutionPlaceholder);
|
|
resolutionPlaceholder->SetStyleAuto();
|
|
|
|
// Create fullscreen controller
|
|
auto* fullscreenFrame = window_->CreateChild<UIElement>("Fullscreen Frame");
|
|
fullscreenFrame->SetMinHeight(24);
|
|
fullscreenFrame->SetLayout(LM_HORIZONTAL, 6);
|
|
|
|
fullscreenControl_ = fullscreenFrame->CreateChild<CheckBox>("Fullscreen Control");
|
|
fullscreenControl_->SetStyleAuto();
|
|
|
|
auto* fullscreenText = fullscreenFrame->CreateChild<Text>("Fullscreen Label");
|
|
fullscreenText->SetText("Fullscreen");
|
|
fullscreenText->SetMinWidth(CeilToInt(fullscreenText->GetRowWidth(0) + 10));
|
|
fullscreenText->SetStyleAuto();
|
|
|
|
// Create borderless controller
|
|
auto* borderlessFrame = window_->CreateChild<UIElement>("Borderless Frame");
|
|
borderlessFrame->SetMinHeight(24);
|
|
borderlessFrame->SetLayout(LM_HORIZONTAL, 6);
|
|
|
|
borderlessControl_ = borderlessFrame->CreateChild<CheckBox>("Borderless Control");
|
|
borderlessControl_->SetStyleAuto();
|
|
|
|
auto* borderlessText = borderlessFrame->CreateChild<Text>("Borderless Label");
|
|
borderlessText->SetText("Borderless");
|
|
borderlessText->SetMinWidth(CeilToInt(borderlessText->GetRowWidth(0) + 10));
|
|
borderlessText->SetStyleAuto();
|
|
|
|
// Create resizable controller
|
|
auto* resizableFrame = window_->CreateChild<UIElement>("Resizable Frame");
|
|
resizableFrame->SetMinHeight(24);
|
|
resizableFrame->SetLayout(LM_HORIZONTAL, 6);
|
|
|
|
resizableControl_ = resizableFrame->CreateChild<CheckBox>("Resizable Control");
|
|
resizableControl_->SetStyleAuto();
|
|
|
|
auto* resizableText = resizableFrame->CreateChild<Text>("Resizable Label");
|
|
resizableText->SetText("Resizable");
|
|
resizableText->SetMinWidth(CeilToInt(resizableText->GetRowWidth(0) + 10));
|
|
resizableText->SetStyleAuto();
|
|
|
|
// Create resizable controller
|
|
auto* vsyncFrame = window_->CreateChild<UIElement>("V-Sync Frame");
|
|
vsyncFrame->SetMinHeight(24);
|
|
vsyncFrame->SetLayout(LM_HORIZONTAL, 6);
|
|
|
|
vsyncControl_ = vsyncFrame->CreateChild<CheckBox>("V-Sync Control");
|
|
vsyncControl_->SetStyleAuto();
|
|
|
|
auto* vsyncText = vsyncFrame->CreateChild<Text>("V-Sync Label");
|
|
vsyncText->SetText("V-Sync");
|
|
vsyncText->SetMinWidth(CeilToInt(vsyncText->GetRowWidth(0) + 10));
|
|
vsyncText->SetStyleAuto();
|
|
|
|
// Create multi-sample controller from 1 (= 2^0) to 16 (= 2^4)
|
|
multiSampleControl_ = window_->CreateChild<DropDownList>("Multi-Sample Control");
|
|
multiSampleControl_->SetMinHeight(24);
|
|
multiSampleControl_->SetStyleAuto();
|
|
for (int i = 0; i <= 4; ++i)
|
|
{
|
|
auto text = MakeShared<Text>(context_);
|
|
text->SetText(i == 0 ? "No MSAA" : ToString("MSAA x%d", 1 << i));
|
|
text->SetMinWidth(CeilToInt(text->GetRowWidth(0) + 10));
|
|
multiSampleControl_->AddItem(text);
|
|
text->SetStyleAuto();
|
|
}
|
|
|
|
// Create "Apply" button
|
|
auto* applyButton = window_->CreateChild<Button>("Apply");
|
|
applyButton->SetLayout(LM_HORIZONTAL, 6, IntRect(6, 6, 6, 6));
|
|
applyButton->SetStyleAuto();
|
|
|
|
auto* applyButtonText = applyButton->CreateChild<Text>("Apply Text");
|
|
applyButtonText->SetAlignment(HA_CENTER, VA_CENTER);
|
|
applyButtonText->SetText("Apply");
|
|
applyButtonText->SetStyleAuto();
|
|
|
|
applyButton->SetFixedWidth(CeilToInt(applyButtonText->GetRowWidth(0) + 20));
|
|
applyButton->SetFixedHeight(30);
|
|
|
|
// Apply settings when "Apply" button is clicked
|
|
SubscribeToEvent(applyButton, E_RELEASED,
|
|
[this, graphics](StringHash /*eventType*/, const VariantMap& /*eventData*/)
|
|
{
|
|
const unsigned monitor = monitorControl_->GetSelection();
|
|
if (monitor == M_MAX_UNSIGNED)
|
|
return;
|
|
|
|
const auto& resolutions = graphics->GetResolutions(monitor);
|
|
const unsigned selectedResolution = resolutionControl_->GetSelection();
|
|
if (selectedResolution >= resolutions.Size())
|
|
return;
|
|
|
|
const bool fullscreen = fullscreenControl_->IsChecked();
|
|
const bool borderless = borderlessControl_->IsChecked();
|
|
const bool resizable = resizableControl_->IsChecked();
|
|
const bool vsync = vsyncControl_->IsChecked();
|
|
|
|
const unsigned multiSampleSelection = multiSampleControl_->GetSelection();
|
|
const int multiSample = multiSampleSelection == M_MAX_UNSIGNED ? 1 : static_cast<int>(1 << multiSampleSelection);
|
|
|
|
// TODO: Expose these options too?
|
|
const bool highDPI = graphics->GetHighDPI();
|
|
const bool tripleBuffer = graphics->GetTripleBuffer();
|
|
|
|
const int width = resolutions[selectedResolution].x_;
|
|
const int height = resolutions[selectedResolution].y_;
|
|
const int refreshRate = resolutions[selectedResolution].z_;
|
|
graphics->SetMode(width, height, fullscreen, borderless, resizable, highDPI, vsync, tripleBuffer, multiSample, monitor, refreshRate);
|
|
});
|
|
}
|
|
|
|
void WindowSettingsDemo::SynchronizeSettings()
|
|
{
|
|
auto* graphics = GetSubsystem<Graphics>();
|
|
|
|
// Synchronize monitor
|
|
const unsigned currentMonitor = graphics->GetMonitor();
|
|
monitorControl_->SetSelection(currentMonitor);
|
|
|
|
// Synchronize resolution list
|
|
resolutionControl_->RemoveAllItems();
|
|
const auto& resolutions = graphics->GetResolutions(currentMonitor);
|
|
for (const IntVector3& resolution : resolutions)
|
|
{
|
|
auto resolutionEntry = MakeShared<Text>(context_);
|
|
resolutionEntry->SetText(ToString("%dx%d, %d Hz", resolution.x_, resolution.y_, resolution.z_));
|
|
resolutionEntry->SetMinWidth(CeilToInt(resolutionEntry->GetRowWidth(0) + 10));
|
|
resolutionControl_->AddItem(resolutionEntry);
|
|
resolutionEntry->SetStyleAuto();
|
|
}
|
|
|
|
// Synchronize selected resolution
|
|
const unsigned currentResolution = graphics->FindBestResolutionIndex(currentMonitor,
|
|
graphics->GetWidth(), graphics->GetHeight(), graphics->GetRefreshRate());
|
|
resolutionControl_->SetSelection(currentResolution);
|
|
|
|
// Synchronize fullscreen and borderless flags
|
|
fullscreenControl_->SetChecked(graphics->GetFullscreen());
|
|
borderlessControl_->SetChecked(graphics->GetBorderless());
|
|
resizableControl_->SetChecked(graphics->GetResizable());
|
|
vsyncControl_->SetChecked(graphics->GetVSync());
|
|
|
|
// Synchronize MSAA
|
|
for (unsigned i = 0; i <= 4; ++i)
|
|
{
|
|
if (graphics->GetMultiSample() == static_cast<int>(1 << i))
|
|
multiSampleControl_->SetSelection(i);
|
|
}
|
|
}
|