mirror of https://github.com/odrling/Aegisub
Clean up OptionValue
Make the vtables less absurdly huge (knocks 100KB off aegisub32.exe), eliminate some copies of the values when constructing the options, and use an enum class for the value type.
This commit is contained in:
parent
371f602100
commit
c59b9d59b8
|
@ -125,43 +125,43 @@ void Options::Flush() const {
|
||||||
|
|
||||||
for (auto const& ov : values) {
|
for (auto const& ov : values) {
|
||||||
switch (ov.second->GetType()) {
|
switch (ov.second->GetType()) {
|
||||||
case OptionValue::Type_String:
|
case OptionType::String:
|
||||||
put_option(obj_out, ov.first, ov.second->GetString());
|
put_option(obj_out, ov.first, ov.second->GetString());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OptionValue::Type_Int:
|
case OptionType::Int:
|
||||||
put_option(obj_out, ov.first, ov.second->GetInt());
|
put_option(obj_out, ov.first, ov.second->GetInt());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OptionValue::Type_Double:
|
case OptionType::Double:
|
||||||
put_option(obj_out, ov.first, ov.second->GetDouble());
|
put_option(obj_out, ov.first, ov.second->GetDouble());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OptionValue::Type_Color:
|
case OptionType::Color:
|
||||||
put_option(obj_out, ov.first, ov.second->GetColor().GetRgbFormatted());
|
put_option(obj_out, ov.first, ov.second->GetColor().GetRgbFormatted());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OptionValue::Type_Bool:
|
case OptionType::Bool:
|
||||||
put_option(obj_out, ov.first, ov.second->GetBool());
|
put_option(obj_out, ov.first, ov.second->GetBool());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OptionValue::Type_List_String:
|
case OptionType::ListString:
|
||||||
put_array(obj_out, ov.first, "string", ov.second->GetListString());
|
put_array(obj_out, ov.first, "string", ov.second->GetListString());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OptionValue::Type_List_Int:
|
case OptionType::ListInt:
|
||||||
put_array(obj_out, ov.first, "int", ov.second->GetListInt());
|
put_array(obj_out, ov.first, "int", ov.second->GetListInt());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OptionValue::Type_List_Double:
|
case OptionType::ListDouble:
|
||||||
put_array(obj_out, ov.first, "double", ov.second->GetListDouble());
|
put_array(obj_out, ov.first, "double", ov.second->GetListDouble());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OptionValue::Type_List_Color:
|
case OptionType::ListColor:
|
||||||
put_array(obj_out, ov.first, "color", ov.second->GetListColor());
|
put_array(obj_out, ov.first, "color", ov.second->GetListColor());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OptionValue::Type_List_Bool:
|
case OptionType::ListBool:
|
||||||
put_array(obj_out, ov.first, "bool", ov.second->GetListBool());
|
put_array(obj_out, ov.first, "bool", ov.second->GetListBool());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,9 +59,9 @@ void ConfigVisitor::Visit(const json::Object& object) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class OptionValueType, class ValueType>
|
template<class OptionValueType>
|
||||||
std::unique_ptr<OptionValue> ConfigVisitor::ReadArray(json::Array const& src, std::string const& array_type, void (OptionValueType::*)(const std::vector<ValueType>&)) {
|
std::unique_ptr<OptionValue> ConfigVisitor::ReadArray(json::Array const& src, std::string const& array_type) {
|
||||||
std::vector<ValueType> arr;
|
typename OptionValueType::value_type arr;
|
||||||
arr.reserve(src.size());
|
arr.reserve(src.size());
|
||||||
|
|
||||||
for (json::Object const& obj : src) {
|
for (json::Object const& obj : src) {
|
||||||
|
@ -74,10 +74,10 @@ std::unique_ptr<OptionValue> ConfigVisitor::ReadArray(json::Array const& src, st
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
arr.push_back(ValueType(obj.begin()->second));
|
arr.push_back((typename OptionValueType::value_type::value_type)(obj.begin()->second));
|
||||||
}
|
}
|
||||||
|
|
||||||
return util::make_unique<OptionValueType>(name, arr);
|
return util::make_unique<OptionValueType>(name, std::move(arr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigVisitor::Visit(const json::Array& array) {
|
void ConfigVisitor::Visit(const json::Array& array) {
|
||||||
|
@ -95,15 +95,15 @@ void ConfigVisitor::Visit(const json::Array& array) {
|
||||||
const std::string& array_type = front.begin()->first;
|
const std::string& array_type = front.begin()->first;
|
||||||
|
|
||||||
if (array_type == "string")
|
if (array_type == "string")
|
||||||
AddOptionValue(ReadArray(array, array_type, &OptionValueListString::SetListString));
|
AddOptionValue(ReadArray<OptionValueListString>(array, array_type));
|
||||||
else if (array_type == "int")
|
else if (array_type == "int")
|
||||||
AddOptionValue(ReadArray(array, array_type, &OptionValueListInt::SetListInt));
|
AddOptionValue(ReadArray<OptionValueListInt>(array, array_type));
|
||||||
else if (array_type == "double")
|
else if (array_type == "double")
|
||||||
AddOptionValue(ReadArray(array, array_type, &OptionValueListDouble::SetListDouble));
|
AddOptionValue(ReadArray<OptionValueListDouble>(array, array_type));
|
||||||
else if (array_type == "bool")
|
else if (array_type == "bool")
|
||||||
AddOptionValue(ReadArray(array, array_type, &OptionValueListBool::SetListBool));
|
AddOptionValue(ReadArray<OptionValueListBool>(array, array_type));
|
||||||
else if (array_type == "color")
|
else if (array_type == "color")
|
||||||
AddOptionValue(ReadArray(array, array_type, &OptionValueListColor::SetListColor));
|
AddOptionValue(ReadArray<OptionValueListColor>(array, array_type));
|
||||||
else
|
else
|
||||||
Error<OptionJsonValueArray>("Array type not handled");
|
Error<OptionJsonValueArray>("Array type not handled");
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,8 @@ class ConfigVisitor final : public json::ConstVisitor {
|
||||||
template<class ErrorType>
|
template<class ErrorType>
|
||||||
void Error(const char *message);
|
void Error(const char *message);
|
||||||
|
|
||||||
template<class OptionValueType, class ValueType>
|
template<class OptionValueType>
|
||||||
std::unique_ptr<OptionValue> ReadArray(json::Array const& src, std::string const& array_type, void (OptionValueType::*set_list)(const std::vector<ValueType>&));
|
std::unique_ptr<OptionValue> ReadArray(json::Array const& src, std::string const& array_type);
|
||||||
|
|
||||||
void AddOptionValue(std::unique_ptr<OptionValue>&& opt);
|
void AddOptionValue(std::unique_ptr<OptionValue>&& opt);
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -27,91 +27,119 @@ namespace agi {
|
||||||
DEFINE_BASE_EXCEPTION_NOINNER(OptionValueError, Exception)
|
DEFINE_BASE_EXCEPTION_NOINNER(OptionValueError, Exception)
|
||||||
DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorNotFound, OptionValueError, "options/not_found")
|
DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorNotFound, OptionValueError, "options/not_found")
|
||||||
DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorInvalidType, OptionValueError, "options/invalid_type")
|
DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorInvalidType, OptionValueError, "options/invalid_type")
|
||||||
DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorInvalidListType, OptionValueError, "options/array/invalid_type")
|
|
||||||
|
/// Option type
|
||||||
|
/// No bitsets here.
|
||||||
|
enum class OptionType {
|
||||||
|
String = 0, ///< String
|
||||||
|
Int = 1, ///< Integer
|
||||||
|
Double = 2, ///< Double
|
||||||
|
Color = 3, ///< Color
|
||||||
|
Bool = 4, ///< Bool
|
||||||
|
ListString = 100, ///< List of Strings
|
||||||
|
ListInt = 101, ///< List of Integers
|
||||||
|
ListDouble = 102, ///< List of Doubles
|
||||||
|
ListColor = 103, ///< List of Colors
|
||||||
|
ListBool = 104 ///< List of Bools
|
||||||
|
};
|
||||||
|
|
||||||
/// @class OptionValue
|
/// @class OptionValue
|
||||||
/// Holds an actual option.
|
/// Holds an actual option.
|
||||||
class OptionValue {
|
class OptionValue {
|
||||||
agi::signal::Signal<OptionValue const&> ValueChanged;
|
agi::signal::Signal<OptionValue const&> ValueChanged;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
|
std::string TypeToString(OptionType type) const {
|
||||||
|
switch (type) {
|
||||||
|
case OptionType::String: return "String";
|
||||||
|
case OptionType::Int: return "Integer";
|
||||||
|
case OptionType::Double: return "Double";
|
||||||
|
case OptionType::Color: return "Color";
|
||||||
|
case OptionType::Bool: return "Bool";
|
||||||
|
case OptionType::ListString: return "List of Strings";
|
||||||
|
case OptionType::ListInt: return "List of Integers";
|
||||||
|
case OptionType::ListDouble: return "List of Doubles";
|
||||||
|
case OptionType::ListColor: return "List of Colors";
|
||||||
|
case OptionType::ListBool: return "List of Bools";
|
||||||
|
}
|
||||||
|
throw agi::InternalError("Invalid option type", nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionValueErrorInvalidType TypeError(OptionType type) const {
|
||||||
|
return OptionValueErrorInvalidType("Invalid type for option " + name + ": expected " + TypeToString(type) + ", got " + TypeToString(GetType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T *As(OptionType type) {
|
||||||
|
if (GetType() == type)
|
||||||
|
return static_cast<T *>(this);
|
||||||
|
throw TypeError(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
const T *As(OptionType type) const {
|
||||||
|
if (GetType() == type)
|
||||||
|
return static_cast<const T *>(this);
|
||||||
|
throw TypeError(type);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void NotifyChanged() { ValueChanged(*this); }
|
void NotifyChanged() { ValueChanged(*this); }
|
||||||
|
|
||||||
OptionValueErrorInvalidType TypeError(std::string type, std::string op = " retrieve ") const {
|
|
||||||
return OptionValueErrorInvalidType("Attempt to" + op + type + " with non-" + type + " value " + GetName());
|
|
||||||
}
|
|
||||||
OptionValueErrorInvalidListType ListTypeError(std::string type, std::string op = " retrieve ") const {
|
|
||||||
return OptionValueErrorInvalidListType("Attempt to" + op + type + " with non-" + type + " list " + GetName());
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionValue(std::string name) : name(std::move(name)) { }
|
OptionValue(std::string name) : name(std::move(name)) { }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~OptionValue() {};
|
virtual ~OptionValue() {}
|
||||||
|
|
||||||
/// Option type
|
|
||||||
/// No bitsets here.
|
|
||||||
enum OptionType {
|
|
||||||
Type_String = 0, ///< String
|
|
||||||
Type_Int = 1, ///< Integer
|
|
||||||
Type_Double = 2, ///< Double
|
|
||||||
Type_Color = 3, ///< Color
|
|
||||||
Type_Bool = 4, ///< Bool
|
|
||||||
Type_List_String = 100, ///< List of Strings
|
|
||||||
Type_List_Int = 101, ///< List of Integers
|
|
||||||
Type_List_Double = 102, ///< List of Doubles
|
|
||||||
Type_List_Color = 103, ///< List of Colors
|
|
||||||
Type_List_Bool = 104 ///< List of Bools
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string GetName() const { return name; }
|
std::string GetName() const { return name; }
|
||||||
virtual OptionType GetType() const = 0;
|
virtual OptionType GetType() const = 0;
|
||||||
virtual bool IsDefault() const = 0;
|
virtual bool IsDefault() const = 0;
|
||||||
virtual void Reset() = 0;
|
virtual void Reset() = 0;
|
||||||
|
|
||||||
virtual std::string GetString() const { throw TypeError("string"); }
|
std::string const& GetString() const;
|
||||||
virtual int64_t GetInt() const { throw TypeError("int"); }
|
int64_t const& GetInt() const;
|
||||||
virtual double GetDouble() const { throw TypeError("double"); }
|
double const& GetDouble() const;
|
||||||
virtual Color GetColor() const { throw TypeError("color"); }
|
Color const& GetColor() const;
|
||||||
virtual bool GetBool() const { throw TypeError("bool"); }
|
bool const& GetBool() const;
|
||||||
|
|
||||||
virtual void SetString(const std::string) { throw TypeError("string", " set "); }
|
void SetString(const std::string);
|
||||||
virtual void SetInt(const int64_t) { throw TypeError("int", " set "); }
|
void SetInt(const int64_t);
|
||||||
virtual void SetDouble(const double) { throw TypeError("double", " set "); }
|
void SetDouble(const double);
|
||||||
virtual void SetColor(const Color) { throw TypeError("color", " set "); }
|
void SetColor(const Color);
|
||||||
virtual void SetBool(const bool) { throw TypeError("bool", " set "); }
|
void SetBool(const bool);
|
||||||
|
|
||||||
virtual std::vector<std::string> const& GetListString() const { throw ListTypeError("string"); }
|
std::vector<std::string> const& GetListString() const;
|
||||||
virtual std::vector<int64_t> const& GetListInt() const { throw ListTypeError("int"); }
|
std::vector<int64_t> const& GetListInt() const;
|
||||||
virtual std::vector<double> const& GetListDouble() const { throw ListTypeError("double"); }
|
std::vector<double> const& GetListDouble() const;
|
||||||
virtual std::vector<Color> const& GetListColor() const { throw ListTypeError("color"); }
|
std::vector<Color> const& GetListColor() const;
|
||||||
virtual std::vector<bool> const& GetListBool() const { throw ListTypeError("string"); }
|
std::vector<bool> const& GetListBool() const;
|
||||||
|
|
||||||
virtual void SetListString(const std::vector<std::string>&) { throw ListTypeError("string", " set "); }
|
void SetListString(std::vector<std::string>);
|
||||||
virtual void SetListInt(const std::vector<int64_t>&) { throw ListTypeError("int", " set "); }
|
void SetListInt(std::vector<int64_t>);
|
||||||
virtual void SetListDouble(const std::vector<double>&) { throw ListTypeError("double", " set "); }
|
void SetListDouble(std::vector<double>);
|
||||||
virtual void SetListColor(const std::vector<Color>&) { throw ListTypeError("color", " set "); }
|
void SetListColor(std::vector<Color>);
|
||||||
virtual void SetListBool(const std::vector<bool>&) { throw ListTypeError("string", " set "); }
|
void SetListBool(std::vector<bool>);
|
||||||
|
|
||||||
virtual void Set(const OptionValue *new_value)=0;
|
virtual void Set(const OptionValue *new_value)=0;
|
||||||
|
|
||||||
DEFINE_SIGNAL_ADDERS(ValueChanged, Subscribe)
|
DEFINE_SIGNAL_ADDERS(ValueChanged, Subscribe)
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CONFIG_OPTIONVALUE(type_name, type) \
|
#define CONFIG_OPTIONVALUE(type_name, type) \
|
||||||
class OptionValue##type_name final : public OptionValue { \
|
class OptionValue##type_name final : public OptionValue { \
|
||||||
type value; \
|
type value; \
|
||||||
type value_default; \
|
type value_default; \
|
||||||
public: \
|
public: \
|
||||||
OptionValue##type_name(std::string member_name, type member_value) \
|
typedef type value_type; \
|
||||||
: OptionValue(std::move(member_name)) \
|
OptionValue##type_name(std::string member_name, type member_value) \
|
||||||
, value(member_value), value_default(member_value) { } \
|
: OptionValue(std::move(member_name)) \
|
||||||
type Get##type_name() const { return value; } \
|
, value(member_value), value_default(member_value) { } \
|
||||||
void Set##type_name(const type new_val) { value = new_val; NotifyChanged(); } \
|
type const& GetValue() const { return value; } \
|
||||||
OptionType GetType() const { return OptionValue::Type_##type_name; } \
|
void SetValue(type new_val) { value = std::move(new_val); NotifyChanged(); } \
|
||||||
void Reset() { value = value_default; NotifyChanged(); } \
|
OptionType GetType() const { return OptionType::type_name; } \
|
||||||
bool IsDefault() const { return value == value_default; } \
|
void Reset() { value = value_default; NotifyChanged(); } \
|
||||||
void Set(const OptionValue *new_val) { Set##type_name(new_val->Get##type_name()); } \
|
bool IsDefault() const { return value == value_default; } \
|
||||||
|
void Set(const OptionValue *new_val) { SetValue(new_val->Get##type_name()); } \
|
||||||
};
|
};
|
||||||
|
|
||||||
CONFIG_OPTIONVALUE(String, std::string)
|
CONFIG_OPTIONVALUE(String, std::string)
|
||||||
|
@ -120,21 +148,22 @@ CONFIG_OPTIONVALUE(Double, double)
|
||||||
CONFIG_OPTIONVALUE(Color, Color)
|
CONFIG_OPTIONVALUE(Color, Color)
|
||||||
CONFIG_OPTIONVALUE(Bool, bool)
|
CONFIG_OPTIONVALUE(Bool, bool)
|
||||||
|
|
||||||
#define CONFIG_OPTIONVALUE_LIST(type_name, type) \
|
#define CONFIG_OPTIONVALUE_LIST(type_name, type) \
|
||||||
class OptionValueList##type_name final : public OptionValue { \
|
class OptionValueList##type_name final : public OptionValue { \
|
||||||
std::vector<type> array; \
|
std::vector<type> array; \
|
||||||
std::vector<type> array_default; \
|
std::vector<type> array_default; \
|
||||||
std::string name; \
|
std::string name; \
|
||||||
public: \
|
public: \
|
||||||
|
typedef std::vector<type> value_type; \
|
||||||
OptionValueList##type_name(std::string name, std::vector<type> const& value = std::vector<type>()) \
|
OptionValueList##type_name(std::string name, std::vector<type> const& value = std::vector<type>()) \
|
||||||
: OptionValue(std::move(name)) \
|
: OptionValue(std::move(name)) \
|
||||||
, array(value), array_default(value) { } \
|
, array(value), array_default(value) { } \
|
||||||
std::vector<type> const& GetList##type_name() const { return array; } \
|
std::vector<type> const& GetValue() const { return array; } \
|
||||||
void SetList##type_name(const std::vector<type>& val) { array = val; NotifyChanged(); } \
|
void SetValue(std::vector<type> val) { array = std::move(val); NotifyChanged(); } \
|
||||||
OptionType GetType() const { return OptionValue::Type_List_##type_name; } \
|
OptionType GetType() const { return OptionType::List##type_name; } \
|
||||||
void Reset() { array = array_default; NotifyChanged(); } \
|
void Reset() { array = array_default; NotifyChanged(); } \
|
||||||
bool IsDefault() const { return array == array_default; } \
|
bool IsDefault() const { return array == array_default; } \
|
||||||
void Set(const OptionValue *nv) { SetList##type_name(nv->GetList##type_name()); } \
|
void Set(const OptionValue *nv) { SetValue(nv->GetList##type_name()); } \
|
||||||
};
|
};
|
||||||
|
|
||||||
CONFIG_OPTIONVALUE_LIST(String, std::string)
|
CONFIG_OPTIONVALUE_LIST(String, std::string)
|
||||||
|
@ -143,4 +172,22 @@ CONFIG_OPTIONVALUE_LIST(Double, double)
|
||||||
CONFIG_OPTIONVALUE_LIST(Color, Color)
|
CONFIG_OPTIONVALUE_LIST(Color, Color)
|
||||||
CONFIG_OPTIONVALUE_LIST(Bool, bool)
|
CONFIG_OPTIONVALUE_LIST(Bool, bool)
|
||||||
|
|
||||||
|
#define CONFIG_OPTIONVALUE_ACCESSORS(ReturnType, Type) \
|
||||||
|
inline ReturnType const& OptionValue::Get##Type() const { return As<OptionValue##Type>(OptionType::Type)->GetValue(); } \
|
||||||
|
inline void OptionValue::Set##Type(ReturnType v) { As<OptionValue##Type>(OptionType::Type)->SetValue(std::move(v)); }
|
||||||
|
|
||||||
|
CONFIG_OPTIONVALUE_ACCESSORS(std::string, String)
|
||||||
|
CONFIG_OPTIONVALUE_ACCESSORS(int64_t, Int)
|
||||||
|
CONFIG_OPTIONVALUE_ACCESSORS(double, Double)
|
||||||
|
CONFIG_OPTIONVALUE_ACCESSORS(Color, Color)
|
||||||
|
CONFIG_OPTIONVALUE_ACCESSORS(bool, Bool)
|
||||||
|
CONFIG_OPTIONVALUE_ACCESSORS(std::vector<std::string>, ListString)
|
||||||
|
CONFIG_OPTIONVALUE_ACCESSORS(std::vector<int64_t>, ListInt)
|
||||||
|
CONFIG_OPTIONVALUE_ACCESSORS(std::vector<double>, ListDouble)
|
||||||
|
CONFIG_OPTIONVALUE_ACCESSORS(std::vector<Color>, ListColor)
|
||||||
|
CONFIG_OPTIONVALUE_ACCESSORS(std::vector<bool>, ListBool)
|
||||||
|
|
||||||
|
#undef CONFIG_OPTIONVALUE
|
||||||
|
#undef CONFIG_OPTIONVALUE_LIST
|
||||||
|
#undef CONFIG_OPTIONVALUE_ACCESSORS
|
||||||
} // namespace agi
|
} // namespace agi
|
||||||
|
|
|
@ -176,8 +176,7 @@ void BaseGrid::OnShowColMenu(wxCommandEvent &event) {
|
||||||
int item = event.GetId() - MENU_SHOW_COL;
|
int item = event.GetId() - MENU_SHOW_COL;
|
||||||
showCol[item] = !showCol[item];
|
showCol[item] = !showCol[item];
|
||||||
|
|
||||||
std::vector<bool> map(std::begin(showCol), std::end(showCol));
|
OPT_SET("Subtitle/Grid/Column")->SetListBool(std::vector<bool>(std::begin(showCol), std::end(showCol)));
|
||||||
OPT_SET("Subtitle/Grid/Column")->SetListBool(map);
|
|
||||||
|
|
||||||
SetColumnWidths();
|
SetColumnWidths();
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
|
|
|
@ -106,7 +106,7 @@ void DialogPasteOver::OnOK(wxCommandEvent &) {
|
||||||
std::vector<bool> options;
|
std::vector<bool> options;
|
||||||
for (size_t i = 0; i < ListBox->GetCount(); ++i)
|
for (size_t i = 0; i < ListBox->GetCount(); ++i)
|
||||||
options.push_back(ListBox->IsChecked(i));
|
options.push_back(ListBox->IsChecked(i));
|
||||||
OPT_SET("Tool/Paste Lines Over/Fields")->SetListBool(options);
|
OPT_SET("Tool/Paste Lines Over/Fields")->SetListBool(std::move(options));
|
||||||
|
|
||||||
EndModal(0);
|
EndModal(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ void init() {
|
||||||
migrations.emplace_back("duplicate -> split");
|
migrations.emplace_back("duplicate -> split");
|
||||||
}
|
}
|
||||||
|
|
||||||
OPT_SET("App/Hotkey Migrations")->SetListString(migrations);
|
OPT_SET("App/Hotkey Migrations")->SetListString(std::move(migrations));
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
|
|
|
@ -117,7 +117,7 @@ wxControl *OptionPage::OptionAdd(wxFlexGridSizer *flex, const wxString &name, co
|
||||||
const agi::OptionValue *opt = OPT_GET(opt_name);
|
const agi::OptionValue *opt = OPT_GET(opt_name);
|
||||||
|
|
||||||
switch (opt->GetType()) {
|
switch (opt->GetType()) {
|
||||||
case agi::OptionValue::Type_Bool: {
|
case agi::OptionType::Bool: {
|
||||||
wxCheckBox *cb = new wxCheckBox(this, -1, name);
|
wxCheckBox *cb = new wxCheckBox(this, -1, name);
|
||||||
flex->Add(cb, 1, wxEXPAND, 0);
|
flex->Add(cb, 1, wxEXPAND, 0);
|
||||||
cb->SetValue(opt->GetBool());
|
cb->SetValue(opt->GetBool());
|
||||||
|
@ -125,28 +125,28 @@ wxControl *OptionPage::OptionAdd(wxFlexGridSizer *flex, const wxString &name, co
|
||||||
return cb;
|
return cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
case agi::OptionValue::Type_Int: {
|
case agi::OptionType::Int: {
|
||||||
wxSpinCtrl *sc = new wxSpinCtrl(this, -1, std::to_wstring((int)opt->GetInt()), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, min, max, opt->GetInt());
|
wxSpinCtrl *sc = new wxSpinCtrl(this, -1, std::to_wstring((int)opt->GetInt()), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, min, max, opt->GetInt());
|
||||||
sc->Bind(wxEVT_SPINCTRL, IntUpdater(opt_name, parent));
|
sc->Bind(wxEVT_SPINCTRL, IntUpdater(opt_name, parent));
|
||||||
Add(flex, name, sc);
|
Add(flex, name, sc);
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
case agi::OptionValue::Type_Double: {
|
case agi::OptionType::Double: {
|
||||||
wxSpinCtrlDouble *scd = new wxSpinCtrlDouble(this, -1, wxString::Format("%g", opt->GetDouble()), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, min, max, opt->GetDouble(), inc);
|
wxSpinCtrlDouble *scd = new wxSpinCtrlDouble(this, -1, wxString::Format("%g", opt->GetDouble()), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, min, max, opt->GetDouble(), inc);
|
||||||
scd->Bind(wxEVT_SPINCTRL, DoubleUpdater(opt_name, parent));
|
scd->Bind(wxEVT_SPINCTRL, DoubleUpdater(opt_name, parent));
|
||||||
Add(flex, name, scd);
|
Add(flex, name, scd);
|
||||||
return scd;
|
return scd;
|
||||||
}
|
}
|
||||||
|
|
||||||
case agi::OptionValue::Type_String: {
|
case agi::OptionType::String: {
|
||||||
wxTextCtrl *text = new wxTextCtrl(this, -1 , to_wx(opt->GetString()));
|
wxTextCtrl *text = new wxTextCtrl(this, -1 , to_wx(opt->GetString()));
|
||||||
text->Bind(wxEVT_TEXT, StringUpdater(opt_name, parent));
|
text->Bind(wxEVT_TEXT, StringUpdater(opt_name, parent));
|
||||||
Add(flex, name, text);
|
Add(flex, name, text);
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
case agi::OptionValue::Type_Color: {
|
case agi::OptionType::Color: {
|
||||||
auto cb = new ColourButton(this, wxSize(40,10), false, opt->GetColor());
|
auto cb = new ColourButton(this, wxSize(40,10), false, opt->GetColor());
|
||||||
cb->Bind(EVT_COLOR, ColourUpdater(opt_name, parent));
|
cb->Bind(EVT_COLOR, ColourUpdater(opt_name, parent));
|
||||||
Add(flex, name, cb);
|
Add(flex, name, cb);
|
||||||
|
@ -166,13 +166,13 @@ void OptionPage::OptionChoice(wxFlexGridSizer *flex, const wxString &name, const
|
||||||
Add(flex, name, cb);
|
Add(flex, name, cb);
|
||||||
|
|
||||||
switch (opt->GetType()) {
|
switch (opt->GetType()) {
|
||||||
case agi::OptionValue::Type_Int: {
|
case agi::OptionType::Int: {
|
||||||
int val = opt->GetInt();
|
int val = opt->GetInt();
|
||||||
cb->Select(val < (int)choices.size() ? val : 0);
|
cb->Select(val < (int)choices.size() ? val : 0);
|
||||||
cb->Bind(wxEVT_COMBOBOX, IntCBUpdater(opt_name, parent));
|
cb->Bind(wxEVT_COMBOBOX, IntCBUpdater(opt_name, parent));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case agi::OptionValue::Type_String: {
|
case agi::OptionType::String: {
|
||||||
wxString val(to_wx(opt->GetString()));
|
wxString val(to_wx(opt->GetString()));
|
||||||
if (cb->FindString(val) != wxNOT_FOUND)
|
if (cb->FindString(val) != wxNOT_FOUND)
|
||||||
cb->SetStringSelection(val);
|
cb->SetStringSelection(val);
|
||||||
|
@ -201,8 +201,8 @@ void OptionPage::OptionBrowse(wxFlexGridSizer *flex, const wxString &name, const
|
||||||
parent->AddChangeableOption(opt_name);
|
parent->AddChangeableOption(opt_name);
|
||||||
const agi::OptionValue *opt = OPT_GET(opt_name);
|
const agi::OptionValue *opt = OPT_GET(opt_name);
|
||||||
|
|
||||||
if (opt->GetType() != agi::OptionValue::Type_String)
|
if (opt->GetType() != agi::OptionType::String)
|
||||||
throw PreferenceIncorrectType("Option must be agi::OptionValue::Type_String for BrowseButton.");
|
throw PreferenceIncorrectType("Option must be agi::OptionType::String for BrowseButton.");
|
||||||
|
|
||||||
wxTextCtrl *text = new wxTextCtrl(this, -1 , to_wx(opt->GetString()));
|
wxTextCtrl *text = new wxTextCtrl(this, -1 , to_wx(opt->GetString()));
|
||||||
text->SetMinSize(wxSize(160, -1));
|
text->SetMinSize(wxSize(160, -1));
|
||||||
|
|
|
@ -200,7 +200,7 @@ void SubsTextEditCtrl::SetSyntaxStyle(int id, wxFont &font, std::string const& n
|
||||||
StyleSetBold(id, OPT_GET("Colour/Subtitle/Syntax/Bold/" + name)->GetBool());
|
StyleSetBold(id, OPT_GET("Colour/Subtitle/Syntax/Bold/" + name)->GetBool());
|
||||||
StyleSetForeground(id, to_wx(OPT_GET("Colour/Subtitle/Syntax/" + name)->GetColor()));
|
StyleSetForeground(id, to_wx(OPT_GET("Colour/Subtitle/Syntax/" + name)->GetColor()));
|
||||||
const agi::OptionValue *background = OPT_GET("Colour/Subtitle/Syntax/Background/" + name);
|
const agi::OptionValue *background = OPT_GET("Colour/Subtitle/Syntax/Background/" + name);
|
||||||
if (background->GetType() == agi::OptionValue::Type_Color)
|
if (background->GetType() == agi::OptionType::Color)
|
||||||
StyleSetBackground(id, to_wx(background->GetColor()));
|
StyleSetBackground(id, to_wx(background->GetColor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -212,50 +212,50 @@ TEST_F(lagi_option, empty_array_decays_to_first_used_type) {
|
||||||
empty_arr_options opt;
|
empty_arr_options opt;
|
||||||
EXPECT_NO_THROW(opt.Get("arr")->GetListBool());
|
EXPECT_NO_THROW(opt.Get("arr")->GetListBool());
|
||||||
|
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidType);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
empty_arr_options opt;
|
empty_arr_options opt;
|
||||||
EXPECT_NO_THROW(opt.Get("arr")->GetListColor());
|
EXPECT_NO_THROW(opt.Get("arr")->GetListColor());
|
||||||
|
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidType);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
empty_arr_options opt;
|
empty_arr_options opt;
|
||||||
EXPECT_NO_THROW(opt.Get("arr")->GetListDouble());
|
EXPECT_NO_THROW(opt.Get("arr")->GetListDouble());
|
||||||
|
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidType);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
empty_arr_options opt;
|
empty_arr_options opt;
|
||||||
EXPECT_NO_THROW(opt.Get("arr")->GetListInt());
|
EXPECT_NO_THROW(opt.Get("arr")->GetListInt());
|
||||||
|
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListString(), agi::OptionValueErrorInvalidType);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
empty_arr_options opt;
|
empty_arr_options opt;
|
||||||
EXPECT_NO_THROW(opt.Get("arr")->GetListString());
|
EXPECT_NO_THROW(opt.Get("arr")->GetListString());
|
||||||
|
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListBool(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListColor(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListDouble(), agi::OptionValueErrorInvalidType);
|
||||||
EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidListType);
|
EXPECT_THROW(opt.Get("arr")->GetListInt(), agi::OptionValueErrorInvalidType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue