Script settings tab

C++20
uramer 3 years ago
parent 03f1b1a082
commit fba82eb1a7

@ -1,18 +1,20 @@
#include "settingswindow.hpp"
#include <regex>
#include <iomanip>
#include <numeric>
#include <array>
#include <MyGUI_ScrollBar.h>
#include <MyGUI_Window.h>
#include <MyGUI_ComboBox.h>
#include <MyGUI_ScrollView.h>
#include <MyGUI_Gui.h>
#include <MyGUI_TabControl.h>
#include <MyGUI_TabItem.h>
#include <SDL_video.h>
#include <iomanip>
#include <numeric>
#include <array>
#include <components/debug/debuglog.hpp>
#include <components/misc/stringops.hpp>
#include <components/misc/constants.hpp>
@ -21,6 +23,7 @@
#include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include <components/lua_ui/scriptsettings.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -33,7 +36,6 @@
namespace
{
std::string textureMipmappingToStr(const std::string& val)
{
if (val == "linear") return "Trilinear";
@ -236,6 +238,10 @@ namespace MWGui
getWidget(mLightingMethodButton, "LightingMethodButton");
getWidget(mLightsResetButton, "LightsResetButton");
getWidget(mMaxLights, "MaxLights");
getWidget(mScriptFilter, "ScriptFilter");
getWidget(mScriptList, "ScriptList");
getWidget(mScriptView, "ScriptView");
getWidget(mScriptDisabled, "ScriptDisabled");
#ifndef WIN32
// hide gamma controls since it currently does not work under Linux
@ -321,9 +327,12 @@ namespace MWGui
mKeyboardSwitch->setStateSelected(true);
mControllerSwitch->setStateSelected(false);
mScriptFilter->eventEditTextChange += MyGUI::newDelegate(this, &SettingsWindow::onScriptFilterChange);
mScriptList->eventListMouseItemActivate += MyGUI::newDelegate(this, &SettingsWindow::onScriptListSelection);
}
void SettingsWindow::onTabChanged(MyGUI::TabControl* /*_sender*/, size_t /*index*/)
void SettingsWindow::onTabChanged(MyGUI::TabControl* /*_sender*/, size_t index)
{
resetScrollbars();
}
@ -699,6 +708,67 @@ namespace MWGui
mControlsBox->setVisibleVScroll(true);
}
void SettingsWindow::resizeScriptSettings()
{
static int minListWidth = 150;
static float relativeListWidth = 0.2f;
MyGUI::IntSize parentSize = mScriptFilter->getParent()->getClientCoord().size();
int listWidth = std::max(minListWidth, static_cast<int>(parentSize.width * relativeListWidth));
int filterHeight = mScriptFilter->getSize().height;
int listBorder = (mScriptList->getSize().height - mScriptList->getClientCoord().height) / 2;
int listHeight = parentSize.height - listBorder - mScriptList->getPosition().top;
mScriptFilter->setSize({ listWidth, filterHeight });
mScriptList->setSize({ listWidth, listHeight });
mScriptView->setPosition({ listWidth, 0 });
mScriptView->setSize({ parentSize.width - listWidth, parentSize.height });
mScriptDisabled->setPosition({0, 0});
mScriptDisabled->setSize(parentSize);
}
void SettingsWindow::renderScriptSettings()
{
while (mScriptView->getChildCount() > 0)
mScriptView->getChildAt(0)->detachFromWidget();
mScriptList->removeAllItems();
std::string filter(".*");
filter += mScriptFilter->getCaption();
filter += ".*";
auto flags = std::regex_constants::icase;
std::regex filterRegex(filter, flags);
auto scriptSettings = LuaUi::scriptSettings();
for (size_t i = 0; i < scriptSettings.size(); ++i)
{
LuaUi::ScriptSettings script = scriptSettings[i];
if (std::regex_match(script.mName, filterRegex) || std::regex_match(script.mSearchHints, filterRegex))
mScriptList->addItem(script.mName, i);
}
// Hide script settings tab when the game world isn't loaded and scripts couldn't add their settings
bool disabled = scriptSettings.empty();
mScriptDisabled->setVisible(disabled);
mScriptFilter->setVisible(!disabled);
mScriptList->setVisible(!disabled);
mScriptView->setVisible(!disabled);
}
void SettingsWindow::onScriptFilterChange(MyGUI::Widget*)
{
renderScriptSettings();
}
void SettingsWindow::onScriptListSelection(MyGUI::Widget*, size_t index)
{
while (mScriptView->getChildCount() > 0)
mScriptView->getChildAt(0)->detachFromWidget();
if (index >= mScriptList->getItemCount())
return;
size_t scriptIndex = *mScriptList->getItemDataAt<size_t>(index);
LuaUi::ScriptSettings script = LuaUi::scriptSettings()[scriptIndex];
LuaUi::attachToWidget(script, mScriptView);
}
void SettingsWindow::onRebindAction(MyGUI::Widget* _sender)
{
int actionId = *_sender->getUserData<int>();
@ -744,12 +814,15 @@ namespace MWGui
updateControlsBox();
updateLightSettings();
resetScrollbars();
renderScriptSettings();
resizeScriptSettings();
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mOkButton);
}
void SettingsWindow::onWindowResize(MyGUI::Window *_sender)
{
layoutControlsBox();
resizeScriptSettings();
}
void SettingsWindow::computeMinimumWindowSize()

@ -44,6 +44,11 @@ namespace MWGui
MyGUI::Button* mControllerSwitch;
bool mKeyboardMode; //if true, setting up the keyboard. Otherwise, it's controller
MyGUI::EditBox* mScriptFilter;
MyGUI::ListBox* mScriptList;
MyGUI::Widget* mScriptView;
MyGUI::EditBox* mScriptDisabled;
void onTabChanged(MyGUI::TabControl* _sender, size_t index);
void onOkButtonClicked(MyGUI::Widget* _sender);
void onTextureFilteringChanged(MyGUI::ComboBox* _sender, size_t pos);
@ -71,12 +76,17 @@ namespace MWGui
void onWindowResize(MyGUI::Window* _sender);
void onScriptFilterChange(MyGUI::Widget*);
void onScriptListSelection(MyGUI::Widget*, size_t index);
void apply();
void configureWidgets(MyGUI::Widget* widget, bool init);
void updateSliderLabel(MyGUI::ScrollBar* scroller, const std::string& value);
void layoutControlsBox();
void resizeScriptSettings();
void renderScriptSettings();
void computeMinimumWindowSize();

@ -2,6 +2,7 @@
#include <components/lua_ui/element.hpp>
#include <components/lua_ui/layers.hpp>
#include <components/lua_ui/content.hpp>
#include <components/lua_ui/scriptsettings.hpp>
#include "context.hpp"
#include "actions.hpp"
@ -43,7 +44,7 @@ namespace MWLua
break;
}
}
catch (std::exception& e)
catch (std::exception&)
{
// prevent any actions on a potentially corrupted widget
mElement->mRoot = nullptr;
@ -238,6 +239,20 @@ namespace MWLua
typeTable.set(it.second, it.first);
api["TYPE"] = LuaUtil::makeReadOnly(typeTable);
api["registerSettings"] = [](sol::table options)
{
LuaUi::ScriptSettings script;
script.mName = options.get_or("name", std::string());
if (script.mName.empty())
throw std::logic_error("No name provided for script settings");
script.mSearchHints = options.get_or("searchHints", std::string());
auto element = options.get_or<std::shared_ptr<LuaUi::Element>>("element", nullptr);
if (!element)
throw std::logic_error("No UI element provided for script settings");
script.mElement = element.get();
LuaUi::registerSettings(script);
};
return LuaUtil::makeReadOnly(api);
}
}

@ -165,7 +165,7 @@ add_component_dir (queries
)
add_component_dir (lua_ui
properties widget element util layers content
properties widget element util layers content scriptsettings
text textedit window image
)

@ -0,0 +1,37 @@
#include "scriptsettings.hpp"
#include <map>
#include "element.hpp"
namespace LuaUi
{
namespace
{
std::vector<ScriptSettings> allSettings;
}
const std::vector<ScriptSettings>& scriptSettings()
{
return allSettings;
}
void registerSettings(const ScriptSettings& script)
{
allSettings.push_back(script);
}
void clearSettings()
{
allSettings.clear();
}
void attachToWidget(const ScriptSettings& script, MyGUI::Widget* widget)
{
WidgetExtension* root = script.mElement->mRoot;
if (!root)
return;
root->widget()->attachToWidget(widget);
root->updateCoord();
}
}

@ -0,0 +1,25 @@
#ifndef OPENMW_LUAUI_SCRIPTSETTINGS
#define OPENMW_LUAUI_SCRIPTSETTINGS
#include <vector>
#include <string>
#include <string_view>
#include <MyGUI_Widget.h>
namespace LuaUi
{
class Element;
struct ScriptSettings
{
std::string mName;
std::string mSearchHints;
Element* mElement; // TODO: figure out if this can lead to use after free
};
const std::vector<ScriptSettings>& scriptSettings();
void registerSettings(const ScriptSettings& script);
void clearSettings();
void attachToWidget(const ScriptSettings& script, MyGUI::Widget* widget);
}
#endif // !OPENMW_LUAUI_SCRIPTSETTINGS

@ -9,6 +9,7 @@
#include "image.hpp"
#include "element.hpp"
#include "scriptsettings.hpp"
namespace LuaUi
{
@ -37,6 +38,7 @@ namespace LuaUi
void clearUserInterface()
{
clearSettings();
while (!Element::sAllElements.empty())
Element::sAllElements.begin()->second->destroy();
}

@ -656,6 +656,19 @@
-->
</Widget>
</Widget>
<Widget type="TabItem" skin="" position="4 32 360 308">
<Property key="Caption" value=" Scripts "/>
<Widget name="ScriptFilter" type="EditBox" skin="MW_TextEdit" position="0 0 150 40" />
<Widget name="ScriptList" type="ListBox" skin="MW_List" position="0 40 150 268" />
<Widget name="ScriptView" type="Widget" skin="" position="0 0 360 308" />
<Widget name="ScriptDisabled" type="EditBox" skin="SandText" position="0 0 360 308" align="Center" visible="false">
<Property key="Caption" value="Scripts settings are only available when a game is loaded."/>
<Property key="TextAlign" value="Center" />
<Property key="MultiLine" value="true" />
<Property key="WordWrap" value="true" />
<Property key="Static" value="true"/>
</Widget>
</Widget>
</Widget>
<Widget type="AutoSizedButton" skin="MW_Button" position="320 420 56 24" align="Right Bottom" name="OkButton">
<Property key="ExpandDirection" value="Left"/>

Loading…
Cancel
Save