Skip to content

Commit

Permalink
#6131: Convert LightInspector to a dockable control
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Oct 21, 2022
1 parent b1254d7 commit a6e78c9
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 119 deletions.
1 change: 1 addition & 0 deletions include/ui/iusercontrol.h
Expand Up @@ -47,6 +47,7 @@ struct UserControl
constexpr static const char* TextureBrowser = "TextureBrowser";
constexpr static const char* SurfaceInspector = "SurfaceInspector";
constexpr static const char* PatchInspector = "PatchInspector";
constexpr static const char* LightInspector = "LightInspector";
constexpr static const char* LayerControlPanel = "LayerControlPanel";
constexpr static const char* TextureTool = "TextureTool";
};
Expand Down
5 changes: 4 additions & 1 deletion radiant/ui/UserInterfaceModule.cpp
Expand Up @@ -75,6 +75,7 @@

#include "console/ConsoleControl.h"
#include "layers/LayerControl.h"
#include "lightinspector/LightInspectorControl.h"
#include "patch/PatchInspectorControl.h"
#include "surfaceinspector/SurfaceInspectorControl.h"
#include "textool/TextureToolControl.h"
Expand Down Expand Up @@ -255,6 +256,7 @@ void UserInterfaceModule::initialiseModule(const IApplicationContext& ctx)
registerControl(std::make_shared<LayerControl>());
registerControl(std::make_shared<TextureToolControl>());
registerControl(std::make_shared<PatchInspectorControl>());
registerControl(std::make_shared<LightInspectorControl>());

GlobalMainFrame().signal_MainFrameConstructed().connect([&]()
{
Expand All @@ -263,6 +265,7 @@ void UserInterfaceModule::initialiseModule(const IApplicationContext& ctx)
GlobalMainFrame().addControl(UserControl::LayerControlPanel, { IMainFrame::Location::FloatingWindow, false });
GlobalMainFrame().addControl(UserControl::TextureTool, { IMainFrame::Location::FloatingWindow, false });
GlobalMainFrame().addControl(UserControl::PatchInspector, { IMainFrame::Location::FloatingWindow, false });
GlobalMainFrame().addControl(UserControl::LightInspector, { IMainFrame::Location::FloatingWindow, false });
});
}

Expand Down Expand Up @@ -423,7 +426,7 @@ void UserInterfaceModule::registerUICommands()
GlobalCommandSystem().addCommand("clear", [](const auto&) { radiant::ClearConsoleMessage::Send(); });

GlobalCommandSystem().addCommand("ToggleConsole", Console::toggle);
GlobalCommandSystem().addCommand("ToggleLightInspector", LightInspector::toggleInspector);
GlobalCommandSystem().addStatement("ToggleLightInspector", fmt::format("ToggleControl {0}", UserControl::LightInspector), false);
GlobalCommandSystem().addStatement("SurfaceInspector", fmt::format("ToggleControl {0}", UserControl::SurfaceInspector), false);
GlobalCommandSystem().addStatement("ToggleLayerControlDialog", fmt::format("ToggleControl {0}", UserControl::LayerControlPanel), false);
GlobalCommandSystem().addStatement("PatchInspector", fmt::format("ToggleControl {0}", UserControl::PatchInspector), false);
Expand Down
112 changes: 24 additions & 88 deletions radiant/ui/lightinspector/LightInspector.cpp
@@ -1,51 +1,42 @@
#include "LightInspector.h"

#include "i18n.h"
#include "icameraview.h"
#include "ientity.h"
#include "ieclass.h"
#include "igame.h"
#include "ishaders.h"
#include "iradiant.h"
#include "ui/imainframe.h"
#include "iselection.h"
#include "iundo.h"

#include <wx/tglbtn.h>
#include <wx/clrpicker.h>
#include <wx/checkbox.h>
#include <wx/artprov.h>
#include <wx/stattext.h>
#include <wx/slider.h>
#include <wx/radiobut.h>


#include "ui/materials/MaterialChooser.h" // for static displayLightInfo() function
#include "util/ScopedBoolLock.h"
#include "gamelib.h"

namespace ui
{

/* CONSTANTS */

namespace
{
const char* LIGHTINSPECTOR_TITLE = N_("Light properties");
const std::string RKEY_WINDOW_STATE = "user/ui/lightInspector/window";
const char* COLOR_KEY = "_color";
constexpr const char* COLOR_KEY = "_color";
}

// Private constructor sets up dialog
LightInspector::LightInspector() :
wxutil::TransientWindow(_(LIGHTINSPECTOR_TITLE), GlobalMainFrame().getWxTopLevelWindow(), true),
LightInspector::LightInspector(wxWindow* parent) :
wxPanel(parent),
_isProjected(false),
_texSelector(nullptr),
_updateActive(false),
_supportsAiSee(game::current::getValue<bool>("/light/supportsAiSeeSpawnarg", false))
{
// Load XRC panel and access widgets
wxPanel* contents = loadNamedPanel(this, "LightInspectorMainPanel");
auto contents = loadNamedPanel(this, "LightInspectorMainPanel");
SetSizer(new wxBoxSizer(wxVERTICAL));
GetSizer()->Add(contents, 1, wxEXPAND);

_brightnessSlider = findNamedObject<wxSlider>(this, "BrightnessSlider");

setupLightShapeOptions();
Expand All @@ -57,31 +48,29 @@ LightInspector::LightInspector() :
makeLabelBold(this, "LightInspectorOptionsLabel");

SetMinSize(contents->GetEffectiveMinSize());
InitialiseWindowPosition(600, 360, RKEY_WINDOW_STATE);
}

LightInspectorPtr& LightInspector::InstancePtr()
{
static LightInspectorPtr _instancePtr;
return _instancePtr;
}
_selectionChanged.disconnect();
_undoHandler.disconnect();
_redoHandler.disconnect();

void LightInspector::onMainFrameShuttingDown()
{
if (IsShownOnScreen())
{
Hide();
}
// Register self as observer to receive events
_undoHandler = GlobalMapModule().signal_postUndo().connect(
sigc::mem_fun(this, &LightInspector::update));
_redoHandler = GlobalMapModule().signal_postRedo().connect(
sigc::mem_fun(this, &LightInspector::update));

// Register self to the SelSystem to get notified upon selection changes.
_selectionChanged = GlobalSelectionSystem().signal_selectionChanged().connect(
[this](const ISelectable&) { update(); });

// Destroy the window
SendDestroyEvent();
InstancePtr().reset();
// Update the widgets right now
update();
}

void LightInspector::shaderSelectionChanged()
{
// Get the selected shader
MaterialPtr ishader = _texSelector->getSelectedShader();
auto ishader = _texSelector->getSelectedShader();

// greebo: Do not write to the entities if this call resulted from an update()
if (_updateActive) return;
Expand Down Expand Up @@ -235,68 +224,15 @@ void LightInspector::update()
}
}

// Pre-hide callback
void LightInspector::_preHide()
LightInspector::~LightInspector()
{
TransientWindow::_preHide();

// Remove as observer, an invisible inspector doesn't need to receive events
_selectionChanged.disconnect();

_undoHandler.disconnect();
_redoHandler.disconnect();
}

// Pre-show callback
void LightInspector::_preShow()
{
TransientWindow::_preShow();

_selectionChanged.disconnect();
_undoHandler.disconnect();
_redoHandler.disconnect();

// Register self as observer to receive events
_undoHandler = GlobalMapModule().signal_postUndo().connect(
sigc::mem_fun(this, &LightInspector::update));
_redoHandler = GlobalMapModule().signal_postRedo().connect(
sigc::mem_fun(this, &LightInspector::update));

// Register self to the SelSystem to get notified upon selection changes.
_selectionChanged = GlobalSelectionSystem().signal_selectionChanged().connect(
[this](const ISelectable&) { update(); });

// Update the widgets before showing
update();
}

// Static method to toggle the dialog
void LightInspector::toggleInspector(const cmd::ArgumentList& args)
{
// Toggle the instance
Instance().ToggleVisibility();
}

LightInspector& LightInspector::Instance()
{
LightInspectorPtr& instancePtr = InstancePtr();

if (instancePtr == NULL)
{
// Not yet instantiated, do it now
instancePtr.reset(new LightInspector);

// Pre-destruction cleanup
GlobalMainFrame().signal_MainFrameShuttingDown().connect(
sigc::mem_fun(*instancePtr, &LightInspector::onMainFrameShuttingDown)
);
}

return *instancePtr;
}

// CALLBACKS

void LightInspector::updateLightShapeWidgets()
{
// Set radio button values. wxWidgets only allows setting a radio button,
Expand Down Expand Up @@ -380,7 +316,7 @@ namespace
}

// Convert linear light value to/from displayed slider value
const float SLIDER_POWER = 1.25;
constexpr float SLIDER_POWER = 1.25;
float fromSlider(float value)
{
return std::pow(value / 100.f, SLIDER_POWER);
Expand Down
36 changes: 6 additions & 30 deletions radiant/ui/lightinspector/LightInspector.h
@@ -1,15 +1,14 @@
#pragma once

#include "icommandsystem.h"
#include "iradiant.h"
#include "ui/materials/MaterialSelector.h"
#include "wxutil/window/TransientWindow.h"
#include "wxutil/XmlResourceBasedWidget.h"

#include <map>
#include <string>
#include <sigc++/connection.h>
#include <sigc++/trackable.h>
#include <wx/panel.h>

/* FORWARD DECLS */
class Entity;
Expand All @@ -20,14 +19,11 @@ class wxSlider;
namespace ui
{

class LightInspector;
typedef std::shared_ptr<LightInspector> LightInspectorPtr;

/**
* \brief Dialog to allow adjustment of properties on lights
*/
class LightInspector :
public wxutil::TransientWindow,
public wxPanel,
public sigc::trackable,
private wxutil::XmlResourceBasedWidget
{
Expand Down Expand Up @@ -59,17 +55,11 @@ class LightInspector :
sigc::connection _undoHandler;
sigc::connection _redoHandler;

private:
// This is where the static shared_ptr of the singleton instance is held.
static LightInspectorPtr& InstancePtr();

// Constructor creates GTK widgets
LightInspector();

// TransientWindow callbacks
virtual void _preShow();
virtual void _preHide();
public:
LightInspector(wxWindow* parent);
~LightInspector() override;

private:
// Widget construction functions
void setupLightShapeOptions();
void bindSpawnargToCheckbox(std::string spawnarg, std::string checkbox);
Expand Down Expand Up @@ -108,20 +98,6 @@ class LightInspector :
// greebo: Gets called when the light texture selection has changed
void shaderSelectionChanged();

// Safely disconnects this dialog from all the systems
// and saves the window size/position to the registry
void onMainFrameShuttingDown();

public:

/** Toggle the visibility of the dialog instance, constructing it if necessary.
*/
static void toggleInspector(const cmd::ArgumentList& args);

/** greebo: This is the actual home of the static instance
*/
static LightInspector& Instance();

// Update the sensitivity of the widgets
void update();
};
Expand Down
35 changes: 35 additions & 0 deletions radiant/ui/lightinspector/LightInspectorControl.h
@@ -0,0 +1,35 @@
#pragma once

#include "i18n.h"
#include "ui/iusercontrol.h"
#include "LightInspector.h"

namespace ui
{

class LightInspectorControl :
public IUserControl
{
public:
std::string getControlName() override
{
return UserControl::LightInspector;
}

std::string getDisplayName() override
{
return _("Light Inspector");
}

std::string getIcon() override
{
return "bulb_lit.png";
}

wxWindow* createWidget(wxWindow* parent) override
{
return new LightInspector(parent);
}
};

}
1 change: 1 addition & 0 deletions tools/msvc/DarkRadiant.vcxproj
Expand Up @@ -465,6 +465,7 @@
<ClInclude Include="..\..\radiant\ui\layers\CreateLayerDialog.h" />
<ClInclude Include="..\..\radiant\ui\layers\LayerControl.h" />
<ClInclude Include="..\..\radiant\ui\layers\LayerControlPanel.h" />
<ClInclude Include="..\..\radiant\ui\lightinspector\LightInspectorControl.h" />
<ClInclude Include="..\..\radiant\ui\LongRunningOperationHandler.h" />
<ClInclude Include="..\..\radiant\ui\mainframe\AuiLayout.h" />
<ClInclude Include="..\..\radiant\ui\mainframe\PropertyNotebook.h" />
Expand Down
3 changes: 3 additions & 0 deletions tools/msvc/DarkRadiant.vcxproj.filters
Expand Up @@ -1419,6 +1419,9 @@
<ClInclude Include="..\..\radiant\ui\patch\PatchInspectorControl.h">
<Filter>src\ui\patch</Filter>
</ClInclude>
<ClInclude Include="..\..\radiant\ui\lightinspector\LightInspectorControl.h">
<Filter>src\ui\lightinspector</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\radiant\darkradiant.rc" />
Expand Down

0 comments on commit a6e78c9

Please sign in to comment.