mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 07:53:51 +00:00
Merge branch 'alchemyfilter' into 'master'
Filters for ingredients & effects in alchemy window See merge request OpenMW/openmw!106
This commit is contained in:
commit
6de1c0d0d3
9 changed files with 218 additions and 6 deletions
|
@ -74,6 +74,7 @@ Programmers
|
||||||
Fil Krynicki (filkry)
|
Fil Krynicki (filkry)
|
||||||
Finbar Crago (finbar-crago)
|
Finbar Crago (finbar-crago)
|
||||||
Florian Weber (Florianjw)
|
Florian Weber (Florianjw)
|
||||||
|
Frédéric Chardon (fr3dz10)
|
||||||
Gaëtan Dezeiraud (Brouilles)
|
Gaëtan Dezeiraud (Brouilles)
|
||||||
Gašper Sedej
|
Gašper Sedej
|
||||||
Gijsbert ter Horst (Ghostbird)
|
Gijsbert ter Horst (Ghostbird)
|
||||||
|
|
|
@ -264,6 +264,7 @@
|
||||||
Feature #5219: Impelement TestCells console command
|
Feature #5219: Impelement TestCells console command
|
||||||
Feature #5224: Handle NiKeyframeController for NiTriShape
|
Feature #5224: Handle NiKeyframeController for NiTriShape
|
||||||
Feature #5304: Morrowind-style bump-mapping
|
Feature #5304: Morrowind-style bump-mapping
|
||||||
|
Feature #5314: Ingredient filter in the alchemy window
|
||||||
Task #4686: Upgrade media decoder to a more current FFmpeg API
|
Task #4686: Upgrade media decoder to a more current FFmpeg API
|
||||||
Task #4695: Optimize Distant Terrain memory consumption
|
Task #4695: Optimize Distant Terrain memory consumption
|
||||||
Task #4789: Optimize cell transitions
|
Task #4789: Optimize cell transitions
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <MyGUI_Gui.h>
|
#include <MyGUI_Gui.h>
|
||||||
#include <MyGUI_Button.h>
|
#include <MyGUI_Button.h>
|
||||||
#include <MyGUI_EditBox.h>
|
#include <MyGUI_EditBox.h>
|
||||||
|
#include <MyGUI_ComboBox.h>
|
||||||
#include <MyGUI_ControllerManager.h>
|
#include <MyGUI_ControllerManager.h>
|
||||||
#include <MyGUI_ControllerRepeatClick.h>
|
#include <MyGUI_ControllerRepeatClick.h>
|
||||||
|
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
|
#include <MyGUI_Macros.h>
|
||||||
#include <components/esm/records.hpp>
|
#include <components/esm/records.hpp>
|
||||||
|
|
||||||
#include "inventoryitemmodel.hpp"
|
#include "inventoryitemmodel.hpp"
|
||||||
|
@ -29,6 +31,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
AlchemyWindow::AlchemyWindow()
|
AlchemyWindow::AlchemyWindow()
|
||||||
: WindowBase("openmw_alchemy_window.layout")
|
: WindowBase("openmw_alchemy_window.layout")
|
||||||
|
, mModel(nullptr)
|
||||||
, mSortModel(nullptr)
|
, mSortModel(nullptr)
|
||||||
, mAlchemy(new MWMechanics::Alchemy())
|
, mAlchemy(new MWMechanics::Alchemy())
|
||||||
, mApparatus (4)
|
, mApparatus (4)
|
||||||
|
@ -50,6 +53,8 @@ namespace MWGui
|
||||||
getWidget(mDecreaseButton, "DecreaseButton");
|
getWidget(mDecreaseButton, "DecreaseButton");
|
||||||
getWidget(mNameEdit, "NameEdit");
|
getWidget(mNameEdit, "NameEdit");
|
||||||
getWidget(mItemView, "ItemView");
|
getWidget(mItemView, "ItemView");
|
||||||
|
getWidget(mFilterValue, "FilterValue");
|
||||||
|
getWidget(mFilterType, "FilterType");
|
||||||
|
|
||||||
mBrewCountEdit->eventValueChanged += MyGUI::newDelegate(this, &AlchemyWindow::onCountValueChanged);
|
mBrewCountEdit->eventValueChanged += MyGUI::newDelegate(this, &AlchemyWindow::onCountValueChanged);
|
||||||
mBrewCountEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &AlchemyWindow::onAccept);
|
mBrewCountEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &AlchemyWindow::onAccept);
|
||||||
|
@ -72,6 +77,9 @@ namespace MWGui
|
||||||
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked);
|
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked);
|
||||||
|
|
||||||
mNameEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &AlchemyWindow::onAccept);
|
mNameEdit->eventEditSelectAccept += MyGUI::newDelegate(this, &AlchemyWindow::onAccept);
|
||||||
|
mFilterValue->eventComboChangePosition += MyGUI::newDelegate(this, &AlchemyWindow::onFilterChanged);
|
||||||
|
mFilterValue->eventEditTextChange += MyGUI::newDelegate(this, &AlchemyWindow::onFilterEdited);
|
||||||
|
mFilterType->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::switchFilterType);
|
||||||
|
|
||||||
center();
|
center();
|
||||||
}
|
}
|
||||||
|
@ -136,16 +144,110 @@ namespace MWGui
|
||||||
removeIngredient(mIngredients[i]);
|
removeIngredient(mIngredients[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateFilters();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AlchemyWindow::initFilter()
|
||||||
|
{
|
||||||
|
auto const& wm = MWBase::Environment::get().getWindowManager();
|
||||||
|
auto const ingredient = wm->getGameSettingString("sIngredients", "Ingredients");
|
||||||
|
auto const effect = wm->getGameSettingString("sMagicEffects", "Magic Effects");
|
||||||
|
|
||||||
|
if (mFilterType->getCaption() == ingredient)
|
||||||
|
mCurrentFilter = FilterType::ByName;
|
||||||
|
else
|
||||||
|
mCurrentFilter = FilterType::ByEffect;
|
||||||
|
updateFilters();
|
||||||
|
mFilterValue->clearIndexSelected();
|
||||||
|
updateFilters();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlchemyWindow::switchFilterType(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
auto const& wm = MWBase::Environment::get().getWindowManager();
|
||||||
|
auto const ingredient = wm->getGameSettingString("sIngredients", "Ingredients");
|
||||||
|
auto const effect = wm->getGameSettingString("sMagicEffects", "Magic Effects");
|
||||||
|
auto *button = _sender->castType<MyGUI::Button>();
|
||||||
|
|
||||||
|
if (button->getCaption() == ingredient)
|
||||||
|
{
|
||||||
|
button->setCaption(effect);
|
||||||
|
mCurrentFilter = FilterType::ByEffect;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button->setCaption(ingredient);
|
||||||
|
mCurrentFilter = FilterType::ByName;
|
||||||
|
}
|
||||||
|
mSortModel->setNameFilter({});
|
||||||
|
mSortModel->setEffectFilter({});
|
||||||
|
mFilterValue->clearIndexSelected();
|
||||||
|
updateFilters();
|
||||||
|
mItemView->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlchemyWindow::updateFilters()
|
||||||
|
{
|
||||||
|
std::set<std::string> itemNames, itemEffects;
|
||||||
|
for (size_t i = 0; i < mModel->getItemCount(); ++i)
|
||||||
|
{
|
||||||
|
auto const& base = mModel->getItem(i).mBase;
|
||||||
|
if (base.getTypeName() != typeid(ESM::Ingredient).name())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
itemNames.insert(base.getClass().getName(base));
|
||||||
|
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||||
|
auto const alchemySkill = player.getClass().getSkill(player, ESM::Skill::Alchemy);
|
||||||
|
|
||||||
|
auto const effects = MWMechanics::Alchemy::effectsDescription(base, alchemySkill);
|
||||||
|
itemEffects.insert(effects.begin(), effects.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
mFilterValue->removeAllItems();
|
||||||
|
auto const addItems = [&](auto const& container)
|
||||||
|
{
|
||||||
|
for (auto const& item : container)
|
||||||
|
mFilterValue->addItem(item);
|
||||||
|
};
|
||||||
|
switch (mCurrentFilter)
|
||||||
|
{
|
||||||
|
case FilterType::ByName: addItems(itemNames); break;
|
||||||
|
case FilterType::ByEffect: addItems(itemEffects); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlchemyWindow::applyFilter(const std::string& filter)
|
||||||
|
{
|
||||||
|
switch (mCurrentFilter)
|
||||||
|
{
|
||||||
|
case FilterType::ByName: mSortModel->setNameFilter(filter); break;
|
||||||
|
case FilterType::ByEffect: mSortModel->setEffectFilter(filter); break;
|
||||||
|
}
|
||||||
|
mItemView->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlchemyWindow::onFilterChanged(MyGUI::ComboBox* _sender, size_t _index)
|
||||||
|
{
|
||||||
|
// ignore spurious event fired when one edit the content after selection.
|
||||||
|
// onFilterEdited will handle it.
|
||||||
|
if (_index != MyGUI::ITEM_NONE)
|
||||||
|
applyFilter(_sender->getItemNameAt(_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlchemyWindow::onFilterEdited(MyGUI::EditBox* _sender)
|
||||||
|
{
|
||||||
|
applyFilter(_sender->getCaption());
|
||||||
|
}
|
||||||
|
|
||||||
void AlchemyWindow::onOpen()
|
void AlchemyWindow::onOpen()
|
||||||
{
|
{
|
||||||
mAlchemy->clear();
|
mAlchemy->clear();
|
||||||
mAlchemy->setAlchemist (MWMechanics::getPlayer());
|
mAlchemy->setAlchemist (MWMechanics::getPlayer());
|
||||||
|
|
||||||
InventoryItemModel* model = new InventoryItemModel(MWMechanics::getPlayer());
|
mModel = new InventoryItemModel(MWMechanics::getPlayer());
|
||||||
mSortModel = new SortFilterItemModel(model);
|
mSortModel = new SortFilterItemModel(mModel);
|
||||||
mSortModel->setFilter(SortFilterItemModel::Filter_OnlyIngredients);
|
mSortModel->setFilter(SortFilterItemModel::Filter_OnlyIngredients);
|
||||||
mItemView->setModel (mSortModel);
|
mItemView->setModel (mSortModel);
|
||||||
mItemView->resetScrollBars();
|
mItemView->resetScrollBars();
|
||||||
|
@ -167,6 +269,7 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
initFilter();
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mNameEdit);
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mNameEdit);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <MyGUI_ControllerItem.h>
|
#include <MyGUI_ControllerItem.h>
|
||||||
|
#include <MyGUI_ComboBox.h>
|
||||||
|
|
||||||
|
#include <components/widgets/box.hpp>
|
||||||
#include <components/widgets/numericeditbox.hpp>
|
#include <components/widgets/numericeditbox.hpp>
|
||||||
|
|
||||||
#include "windowbase.hpp"
|
#include "windowbase.hpp"
|
||||||
|
@ -19,6 +21,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
class ItemView;
|
class ItemView;
|
||||||
class ItemWidget;
|
class ItemWidget;
|
||||||
|
class InventoryItemModel;
|
||||||
class SortFilterItemModel;
|
class SortFilterItemModel;
|
||||||
|
|
||||||
class AlchemyWindow : public WindowBase
|
class AlchemyWindow : public WindowBase
|
||||||
|
@ -36,8 +39,11 @@ namespace MWGui
|
||||||
static const float sCountChangeInterval; // in seconds
|
static const float sCountChangeInterval; // in seconds
|
||||||
|
|
||||||
std::string mSuggestedPotionName;
|
std::string mSuggestedPotionName;
|
||||||
|
enum class FilterType { ByName, ByEffect };
|
||||||
|
FilterType mCurrentFilter;
|
||||||
|
|
||||||
ItemView* mItemView;
|
ItemView* mItemView;
|
||||||
|
InventoryItemModel* mModel;
|
||||||
SortFilterItemModel* mSortModel;
|
SortFilterItemModel* mSortModel;
|
||||||
|
|
||||||
MyGUI::Button* mCreateButton;
|
MyGUI::Button* mCreateButton;
|
||||||
|
@ -47,6 +53,8 @@ namespace MWGui
|
||||||
|
|
||||||
MyGUI::Button* mIncreaseButton;
|
MyGUI::Button* mIncreaseButton;
|
||||||
MyGUI::Button* mDecreaseButton;
|
MyGUI::Button* mDecreaseButton;
|
||||||
|
Gui::AutoSizedButton* mFilterType;
|
||||||
|
MyGUI::ComboBox* mFilterValue;
|
||||||
MyGUI::EditBox* mNameEdit;
|
MyGUI::EditBox* mNameEdit;
|
||||||
Gui::NumericEditBox* mBrewCountEdit;
|
Gui::NumericEditBox* mBrewCountEdit;
|
||||||
|
|
||||||
|
@ -60,6 +68,13 @@ namespace MWGui
|
||||||
void onCountValueChanged(int value);
|
void onCountValueChanged(int value);
|
||||||
void onRepeatClick(MyGUI::Widget* widget, MyGUI::ControllerItem* controller);
|
void onRepeatClick(MyGUI::Widget* widget, MyGUI::ControllerItem* controller);
|
||||||
|
|
||||||
|
void applyFilter(const std::string& filter);
|
||||||
|
void initFilter();
|
||||||
|
void onFilterChanged(MyGUI::ComboBox* _sender, size_t _index);
|
||||||
|
void onFilterEdited(MyGUI::EditBox* _sender);
|
||||||
|
void switchFilterType(MyGUI::Widget* _sender);
|
||||||
|
void updateFilters();
|
||||||
|
|
||||||
void addRepeatController(MyGUI::Widget* widget);
|
void addRepeatController(MyGUI::Widget* widget);
|
||||||
|
|
||||||
void onIncreaseButtonTriggered();
|
void onIncreaseButtonTriggered();
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include "../mwworld/nullaction.hpp"
|
#include "../mwworld/nullaction.hpp"
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
|
#include "../mwmechanics/alchemy.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
bool compareType(const std::string& type1, const std::string& type2)
|
bool compareType(const std::string& type1, const std::string& type2)
|
||||||
|
@ -151,6 +153,8 @@ namespace MWGui
|
||||||
: mCategory(Category_All)
|
: mCategory(Category_All)
|
||||||
, mFilter(0)
|
, mFilter(0)
|
||||||
, mSortByType(true)
|
, mSortByType(true)
|
||||||
|
, mNameFilter("")
|
||||||
|
, mEffectFilter("")
|
||||||
{
|
{
|
||||||
mSourceModel = sourceModel;
|
mSourceModel = sourceModel;
|
||||||
}
|
}
|
||||||
|
@ -199,8 +203,39 @@ namespace MWGui
|
||||||
if (!(category & mCategory))
|
if (!(category & mCategory))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ((mFilter & Filter_OnlyIngredients) && base.getTypeName() != typeid(ESM::Ingredient).name())
|
if (mFilter & Filter_OnlyIngredients)
|
||||||
return false;
|
{
|
||||||
|
if (base.getTypeName() != typeid(ESM::Ingredient).name())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!mNameFilter.empty() && !mEffectFilter.empty())
|
||||||
|
throw std::logic_error("name and magic effect filter are mutually exclusive");
|
||||||
|
|
||||||
|
if (!mNameFilter.empty())
|
||||||
|
{
|
||||||
|
const auto itemName = Misc::StringUtils::lowerCase(base.getClass().getName(base));
|
||||||
|
return itemName.find(mNameFilter) != std::string::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mEffectFilter.empty())
|
||||||
|
{
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||||
|
const auto alchemySkill = player.getClass().getSkill(player, ESM::Skill::Alchemy);
|
||||||
|
|
||||||
|
const auto effects = MWMechanics::Alchemy::effectsDescription(base, alchemySkill);
|
||||||
|
|
||||||
|
for (const auto& effect : effects)
|
||||||
|
{
|
||||||
|
const auto ciEffect = Misc::StringUtils::lowerCase(effect);
|
||||||
|
|
||||||
|
if (ciEffect.find(mEffectFilter) != std::string::npos)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if ((mFilter & Filter_OnlyEnchanted) && !(item.mFlags & ItemStack::Flag_Enchanted))
|
if ((mFilter & Filter_OnlyEnchanted) && !(item.mFlags & ItemStack::Flag_Enchanted))
|
||||||
return false;
|
return false;
|
||||||
if ((mFilter & Filter_OnlyChargedSoulstones) && (base.getTypeName() != typeid(ESM::Miscellaneous).name()
|
if ((mFilter & Filter_OnlyChargedSoulstones) && (base.getTypeName() != typeid(ESM::Miscellaneous).name()
|
||||||
|
@ -286,6 +321,11 @@ namespace MWGui
|
||||||
mNameFilter = Misc::StringUtils::lowerCase(filter);
|
mNameFilter = Misc::StringUtils::lowerCase(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SortFilterItemModel::setEffectFilter (const std::string& filter)
|
||||||
|
{
|
||||||
|
mEffectFilter = Misc::StringUtils::lowerCase(filter);
|
||||||
|
}
|
||||||
|
|
||||||
void SortFilterItemModel::update()
|
void SortFilterItemModel::update()
|
||||||
{
|
{
|
||||||
mSourceModel->update();
|
mSourceModel->update();
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace MWGui
|
||||||
void setCategory (int category);
|
void setCategory (int category);
|
||||||
void setFilter (int filter);
|
void setFilter (int filter);
|
||||||
void setNameFilter (const std::string& filter);
|
void setNameFilter (const std::string& filter);
|
||||||
|
void setEffectFilter (const std::string& filter);
|
||||||
|
|
||||||
/// Use ItemStack::Type for sorting?
|
/// Use ItemStack::Type for sorting?
|
||||||
void setSortByType(bool sort) { mSortByType = sort; }
|
void setSortByType(bool sort) { mSortByType = sort; }
|
||||||
|
@ -60,6 +61,7 @@ namespace MWGui
|
||||||
bool mSortByType;
|
bool mSortByType;
|
||||||
|
|
||||||
std::string mNameFilter; // filter by item name
|
std::string mNameFilter; // filter by item name
|
||||||
|
std::string mEffectFilter; // filter by magic effect
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -554,3 +554,37 @@ std::string MWMechanics::Alchemy::suggestPotionName()
|
||||||
return MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
return MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
|
||||||
ESM::MagicEffect::effectIdToString(effectId))->mValue.getString();
|
ESM::MagicEffect::effectIdToString(effectId))->mValue.getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> MWMechanics::Alchemy::effectsDescription (const MWWorld::ConstPtr &ptr, const int alchemySkill)
|
||||||
|
{
|
||||||
|
std::vector<std::string> effects;
|
||||||
|
|
||||||
|
const auto& item = ptr.get<ESM::Ingredient>()->mBase;
|
||||||
|
const auto& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
const static auto fWortChanceValue = gmst.find("fWortChanceValue")->mValue.getFloat();
|
||||||
|
const auto& data = item->mData;
|
||||||
|
|
||||||
|
for (auto i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
const auto effectID = data.mEffectID[i];
|
||||||
|
const auto skillID = data.mSkills[i];
|
||||||
|
const auto attributeID = data.mAttributes[i];
|
||||||
|
|
||||||
|
if (alchemySkill < fWortChanceValue * (i + 1))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (effectID != -1)
|
||||||
|
{
|
||||||
|
std::string effect = gmst.find(ESM::MagicEffect::effectIdToString(effectID))->mValue.getString();
|
||||||
|
|
||||||
|
if (skillID != -1)
|
||||||
|
effect += " " + gmst.find(ESM::Skill::sSkillNameIds[skillID])->mValue.getString();
|
||||||
|
else if (attributeID != -1)
|
||||||
|
effect += " " + gmst.find(ESM::Attribute::sGmstAttributeIds[attributeID])->mValue.getString();
|
||||||
|
|
||||||
|
effects.push_back(effect);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return effects;
|
||||||
|
}
|
||||||
|
|
|
@ -131,6 +131,8 @@ namespace MWMechanics
|
||||||
///< Try to create potions from the ingredients, place them in the inventory of the alchemist and
|
///< Try to create potions from the ingredients, place them in the inventory of the alchemist and
|
||||||
/// adjust the skills of the alchemist accordingly.
|
/// adjust the skills of the alchemist accordingly.
|
||||||
/// \param name must not be an empty string, or Result_NoName is returned
|
/// \param name must not be an empty string, or Result_NoName is returned
|
||||||
|
|
||||||
|
static std::vector<std::string> effectsDescription (const MWWorld::ConstPtr &ptr, const int alchemySKill);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,8 +57,7 @@
|
||||||
|
|
||||||
<!-- Available Ingredients -->
|
<!-- Available Ingredients -->
|
||||||
|
|
||||||
<Widget type="ItemView" skin="MW_ItemView" position="10 206 552 158" name="ItemView" align="Left Top Stretch"/>
|
<Widget type="ItemView" skin="MW_ItemView" position="10 206 552 132" name="ItemView" align="Left Top Stretch"/>
|
||||||
|
|
||||||
|
|
||||||
<!-- Created Effects -->
|
<!-- Created Effects -->
|
||||||
|
|
||||||
|
@ -71,6 +70,21 @@
|
||||||
<Widget type="Widget" skin="" position="4 4 316 122" name="CreatedEffects" align="HStretch"/>
|
<Widget type="Widget" skin="" position="4 4 316 122" name="CreatedEffects" align="HStretch"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
<!-- Filters -->
|
||||||
|
|
||||||
|
<Widget type="HBox" skin="MW_Box" position="10 333 552 39" align="Bottom HStretch">
|
||||||
|
<Property key="Padding" value="5"/>
|
||||||
|
<Property key="Spacing" value="10"/>
|
||||||
|
|
||||||
|
<Widget type="AutoSizedButton" skin="MW_Button" position="10 2 1 1" name="FilterType">
|
||||||
|
<Property key="Caption" value="#{sIngredients}"/> <!-- default value, can be either sIngredients of sMagicEffects -->
|
||||||
|
</Widget>
|
||||||
|
<Widget type="ComboBox" skin="MW_ComboBox" position="0 2 0 24" name="FilterValue">
|
||||||
|
<UserString key="HStretch" value="true"/>
|
||||||
|
<Property key="ModeDrop" value="false"/>
|
||||||
|
</Widget>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
|
||||||
<!-- Buttons -->
|
<!-- Buttons -->
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue