Commit fe606b03 authored by twanvl's avatar twanvl

Fixed Actions for TextCtrl, actions used to apply to the wrong value.

Changed some TABs to spaces in macros, that should end the conflicts because we use different tab sizes (4 vs 8)
parent b787142d
...@@ -35,6 +35,7 @@ class SimpleValueAction : public ValueAction { ...@@ -35,6 +35,7 @@ class SimpleValueAction : public ValueAction {
virtual void perform(bool to_undo) { virtual void perform(bool to_undo) {
swap(static_cast<T&>(*valueP).*member, new_value); swap(static_cast<T&>(*valueP).*member, new_value);
valueP->onAction(*this, to_undo); // notify value
} }
virtual bool merge(const Action& action) { virtual bool merge(const Action& action) {
...@@ -76,6 +77,7 @@ void TextValueAction::perform(bool to_undo) { ...@@ -76,6 +77,7 @@ void TextValueAction::perform(bool to_undo) {
swap(value().value, new_value); swap(value().value, new_value);
value().last_update.update(); value().last_update.update();
swap(selection_end, new_selection_end); swap(selection_end, new_selection_end);
valueP->onAction(*this, to_undo); // notify value
} }
bool TextValueAction::merge(const Action& action) { bool TextValueAction::merge(const Action& action) {
......
...@@ -127,10 +127,13 @@ Value::~Value() {} ...@@ -127,10 +127,13 @@ Value::~Value() {}
IMPLEMENT_REFLECTION_NAMELESS(Value) { IMPLEMENT_REFLECTION_NAMELESS(Value) {
} }
bool Value::equals(const Value* that) {
return this == that;
}
void init_object(const FieldP& field, ValueP& value) { void init_object(const FieldP& field, ValueP& value) {
if (!value) value = field->newValue(field); if (!value) value = field->newValue(field);
} }
template <> ValueP read_new<Value>(Reader&) { template <> ValueP read_new<Value>(Reader&) {
throw InternalError(_("IndexMap contains nullptr ValueP the application should have crashed already")); throw InternalError(_("IndexMap contains nullptr ValueP the application should have crashed already"));
} }
...@@ -21,6 +21,7 @@ DECLARE_POINTER_TYPE(Style); ...@@ -21,6 +21,7 @@ DECLARE_POINTER_TYPE(Style);
DECLARE_POINTER_TYPE(Value); DECLARE_POINTER_TYPE(Value);
class Context; class Context;
class Dependency; class Dependency;
class Action;
// for DataViewer/editor // for DataViewer/editor
class DataViewer; class DataEditor; class DataViewer; class DataEditor;
...@@ -134,6 +135,14 @@ class Value { ...@@ -134,6 +135,14 @@ class Value {
virtual String toString() const = 0; virtual String toString() const = 0;
/// Apply scripts to this value, return true if the value has changed /// Apply scripts to this value, return true if the value has changed
virtual bool update(Context&) { last_script_update.update(); return false; } virtual bool update(Context&) { last_script_update.update(); return false; }
/// This value has been updated by an action
/** Does nothing for most Values, only FakeValues can update underlying data */
virtual void onAction(Action& a, bool undone) {}
/// Is this value the same as some other value (for the same field&card)
/** Has behaviour other than == for FakeTextValue.
* In that case, afterwards this becomes equal to that if they use the same underlying object.
*/
virtual bool equals(const Value* that);
private: private:
DECLARE_REFLECTION_VIRTUAL(); DECLARE_REFLECTION_VIRTUAL();
......
...@@ -105,3 +105,18 @@ bool TextValue::update(Context& ctx) { ...@@ -105,3 +105,18 @@ bool TextValue::update(Context& ctx) {
IMPLEMENT_REFLECTION_NAMELESS(TextValue) { IMPLEMENT_REFLECTION_NAMELESS(TextValue) {
if (fieldP->save_value || tag.scripting()) REFLECT_NAMELESS(value); if (fieldP->save_value || tag.scripting()) REFLECT_NAMELESS(value);
} }
// ----------------------------------------------------------------------------- : FakeTextValue
void FakeTextValue::onAction(Action& a, bool undone) {
*underlying = value;
}
bool FakeTextValue::equals(const Value* that) {
if (this == that) return true;
const FakeTextValue* thatT = dynamic_cast<const FakeTextValue*>(that);
if (!thatT || underlying != thatT->underlying) return false;
// update the value
value = *underlying;
return true;
}
...@@ -98,5 +98,22 @@ class TextValue : public Value { ...@@ -98,5 +98,22 @@ class TextValue : public Value {
DECLARE_REFLECTION(); DECLARE_REFLECTION();
}; };
// ----------------------------------------------------------------------------- : TextValue
/// A 'fake' TextValue that is used to edit some other string
/** Used by TextCtrl */
class FakeTextValue : public TextValue {
public:
inline FakeTextValue(const TextFieldP& field, String* underlying)
: TextValue(field), underlying(underlying) {}
String* const underlying; ///< The underlying actual value
/// Update underlying data
virtual void onAction(Action& a, bool undone);
/// Editing the same underlying value?
virtual bool equals(const Value* that);
};
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
#endif #endif
...@@ -59,6 +59,7 @@ class Keyword { ...@@ -59,6 +59,7 @@ class Keyword {
* captures 2,4,... capture the parameters * captures 2,4,... capture the parameters
*/ */
wxRegEx matchRe; wxRegEx matchRe;
bool fixed; ///< Is this keyword uneditable? (true for game keywods, false for set keywords)
/// Prepare the expansion: (re)generate matchRe and the list of parameters. /// Prepare the expansion: (re)generate matchRe and the list of parameters.
/** Throws when there is an error in the input /** Throws when there is an error in the input
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include <data/set.hpp> #include <data/set.hpp>
#include <data/game.hpp> #include <data/game.hpp>
#include <data/keyword.hpp> #include <data/keyword.hpp>
#include <util/tagged_string.hpp>
#include <gfx/gfx.hpp>
DECLARE_TYPEOF_COLLECTION(KeywordP); DECLARE_TYPEOF_COLLECTION(KeywordP);
...@@ -23,7 +25,7 @@ KeywordList::KeywordList(Window* parent, int id, long additional_style) ...@@ -23,7 +25,7 @@ KeywordList::KeywordList(Window* parent, int id, long additional_style)
: ItemList(parent, id, additional_style) : ItemList(parent, id, additional_style)
{ {
// Add columns // Add columns
InsertColumn(0, _LABEL_("keyword"), wxLIST_FORMAT_LEFT, 100); InsertColumn(0, _LABEL_("keyword"), wxLIST_FORMAT_LEFT, 0);
InsertColumn(1, _LABEL_("match"), wxLIST_FORMAT_LEFT, 200); InsertColumn(1, _LABEL_("match"), wxLIST_FORMAT_LEFT, 200);
InsertColumn(2, _LABEL_("mode"), wxLIST_FORMAT_LEFT, 100); InsertColumn(2, _LABEL_("mode"), wxLIST_FORMAT_LEFT, 100);
InsertColumn(3, _LABEL_("uses"), wxLIST_FORMAT_RIGHT, 80); InsertColumn(3, _LABEL_("uses"), wxLIST_FORMAT_RIGHT, 80);
...@@ -51,11 +53,21 @@ void KeywordList::onAction(const Action& action, bool undone) { ...@@ -51,11 +53,21 @@ void KeywordList::onAction(const Action& action, bool undone) {
// ----------------------------------------------------------------------------- : KeywordListBase : for ItemList // ----------------------------------------------------------------------------- : KeywordListBase : for ItemList
String match_string(const Keyword& a) {
return untag(replace_all(replace_all(
a.match,
_("<param>"), _("")),
_("</param>"), _(""))
);
}
void KeywordList::getItems(vector<VoidP>& out) const { void KeywordList::getItems(vector<VoidP>& out) const {
FOR_EACH(k, set->keywords) { FOR_EACH(k, set->keywords) {
k->fixed = false;
out.push_back(k); out.push_back(k);
} }
FOR_EACH(k, set->game->keywords) { FOR_EACH(k, set->game->keywords) {
k->fixed = true;
out.push_back(k); out.push_back(k);
} }
} }
...@@ -83,7 +95,7 @@ String KeywordList::OnGetItemText (long pos, long col) const { ...@@ -83,7 +95,7 @@ String KeywordList::OnGetItemText (long pos, long col) const {
const Keyword& kw = *getKeyword(pos); const Keyword& kw = *getKeyword(pos);
switch(col) { switch(col) {
case 0: return kw.keyword; case 0: return kw.keyword;
case 1: return kw.match; case 1: return match_string(kw);
case 2: return kw.mode; case 2: return kw.mode;
case 3: return _("TODO"); case 3: return _("TODO");
case 4: return _("TODO"); case 4: return _("TODO");
...@@ -93,3 +105,11 @@ String KeywordList::OnGetItemText (long pos, long col) const { ...@@ -93,3 +105,11 @@ String KeywordList::OnGetItemText (long pos, long col) const {
int KeywordList::OnGetItemImage(long pos) const { int KeywordList::OnGetItemImage(long pos) const {
return -1; return -1;
} }
wxListItemAttr* KeywordList::OnGetItemAttr(long pos) const {
// black for set keywords, grey for game keywords (uneditable)
const Keyword& kw = *getKeyword(pos);
if (!kw.fixed) return nullptr;
item_attr.SetTextColour(lerp(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW),wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT),0.5));
return &item_attr;
}
...@@ -68,9 +68,13 @@ class KeywordList : public ItemList, public SetView { ...@@ -68,9 +68,13 @@ class KeywordList : public ItemList, public SetView {
/// Get the image of an item, by default no image is used /// Get the image of an item, by default no image is used
/** Overrides a function from wxListCtrl */ /** Overrides a function from wxListCtrl */
virtual int OnGetItemImage(long pos) const; virtual int OnGetItemImage(long pos) const;
/// Get the color for an item
virtual wxListItemAttr* OnGetItemAttr(long pos) const;
private: private:
void storeColumns(); void storeColumns();
mutable wxListItemAttr item_attr; // for OnGetItemAttr
}; };
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
......
...@@ -37,7 +37,7 @@ void TextCtrl::setValue(String* value) { ...@@ -37,7 +37,7 @@ void TextCtrl::setValue(String* value) {
// create a field, style and value // create a field, style and value
TextFieldP field(new TextField); TextFieldP field(new TextField);
TextStyleP style(new TextStyle(field)); TextStyleP style(new TextStyle(field));
TextValueP value(new TextValue(field)); TextValueP value(new FakeTextValue(field, this->value));
// set stuff // set stuff
field->index = 0; field->index = 0;
field->multi_line = true; field->multi_line = true;
...@@ -57,6 +57,11 @@ void TextCtrl::setValue(String* value) { ...@@ -57,6 +57,11 @@ void TextCtrl::setValue(String* value) {
viewers.front()->getEditor()->determineSize(true); viewers.front()->getEditor()->determineSize(true);
// We don't wan to change the window size // We don't wan to change the window size
//SetMinSize(RealSize(style->width + 6, style->height + 6)); //SetMinSize(RealSize(style->width + 6, style->height + 6));
} else if (value) {
// create a new value, for a different underlying actual value
ValueViewer& viewer = *viewers.front();
TextValueP new_value(new FakeTextValue(static_pointer_cast<TextField>(viewer.getField()), this->value));
viewer.setValue(new_value);
} }
valueChanged(); valueChanged();
} }
...@@ -70,13 +75,15 @@ void TextCtrl::valueChanged() { ...@@ -70,13 +75,15 @@ void TextCtrl::valueChanged() {
} }
void TextCtrl::onAction(const Action& action, bool undone) { void TextCtrl::onAction(const Action& action, bool undone) {
DataEditor::onAction(action, undone); DataEditor::onAction(action, undone);
/*
TYPE_CASE(action, TextValueAction) { TYPE_CASE(action, TextValueAction) {
TextValue& tv = static_cast<TextValue&>(*viewers.front()->getValue()); FakeTextValue& tv = static_cast<FakeTextValue&>(*viewers.front()->getValue());
if (&tv == action.valueP.get()) { if (tv.equals(action.valueP.get())) {
// the value has changed // the value has changed
if (value) *value = tv.value(); if (value) *value = tv.value();
} }
} }
*/
} }
void TextCtrl::onChangeSet() { void TextCtrl::onChangeSet() {
DataEditor::onChangeSet(); DataEditor::onChangeSet();
......
...@@ -8,8 +8,10 @@ ...@@ -8,8 +8,10 @@
#include <gui/set/keywords_panel.hpp> #include <gui/set/keywords_panel.hpp>
#include <gui/control/keyword_list.hpp> #include <gui/control/keyword_list.hpp>
#include <gui/control/text_ctrl.hpp>
#include <data/keyword.hpp> #include <data/keyword.hpp>
#include <wx/listctrl.h> #include <wx/listctrl.h>
#include <wx/splitter.h>
// ----------------------------------------------------------------------------- : KeywordsPanel // ----------------------------------------------------------------------------- : KeywordsPanel
...@@ -17,16 +19,42 @@ KeywordsPanel::KeywordsPanel(Window* parent, int id) ...@@ -17,16 +19,42 @@ KeywordsPanel::KeywordsPanel(Window* parent, int id)
: SetWindowPanel(parent, id) : SetWindowPanel(parent, id)
{ {
// init controls // init controls
list = new KeywordList(this, wxID_ANY); Panel* panel;
splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
list = new KeywordList(splitter, wxID_ANY);
panel = new Panel(splitter, wxID_ANY);
keyword = new TextCtrl(panel, wxID_ANY);
match = new TextCtrl(panel, wxID_ANY);
reminder = new TextCtrl(panel, wxID_ANY);
rules = new TextCtrl(panel, wxID_ANY);
// init sizer for panel
wxSizer* sp = new wxBoxSizer(wxVERTICAL);
sp->Add(new wxStaticText(panel, wxID_ANY, _("Keyword:")), 0, wxALL, 6);
sp->Add(keyword, 0, wxEXPAND | wxALL & ~wxTOP, 6);
wxSizer* s2 = new wxStaticBoxSizer(wxVERTICAL, panel, _("Match"));
s2->Add(new wxStaticText(panel, wxID_ANY, _("Keyword format:")), 0, wxALL, 6);
s2->Add(match, 0, wxEXPAND | wxALL & ~wxTOP, 6);
s2->Add(new wxStaticText(panel, wxID_ANY, _("Parameters:")), 0, wxALL, 6);
sp->Add(s2, 0, wxEXPAND | wxALL, 6);
sp->Add(new wxStaticText(panel, wxID_ANY, _("Reminder:")), 0, wxALL, 6);
sp->Add(reminder, 0, wxEXPAND | wxALL & ~wxTOP, 6);
sp->Add(new wxStaticText(panel, wxID_ANY, _("Rules:")), 0, wxALL, 6);
sp->Add(rules, 0, wxEXPAND | wxALL & ~wxTOP, 6);
panel->SetSizer(sp);
// init splitter
splitter->SetMinimumPaneSize(100);
splitter->SetSashGravity(0.5);
splitter->SplitVertically(list, panel, -200);
// init sizer // init sizer
wxSizer* s = new wxBoxSizer(wxHORIZONTAL); wxSizer* s = new wxBoxSizer(wxHORIZONTAL);
s->Add(list, 1, wxEXPAND); s->Add(splitter, 1, wxEXPAND);
s->SetSizeHints(this);
SetSizer(s);
//s->Add(new wxStaticText(this, wxID_ANY, _("Sorry, no keywords for now"),wxDefaultPosition,wxDefaultSize,wxALIGN_CENTER), 1, wxALIGN_CENTER); // TODO: Remove //s->Add(new wxStaticText(this, wxID_ANY, _("Sorry, no keywords for now"),wxDefaultPosition,wxDefaultSize,wxALIGN_CENTER), 1, wxALIGN_CENTER); // TODO: Remove
/* wxSizer* s2 = new wxBoxSizer(wxVERTICAL); /* wxSizer* s2 = new wxBoxSizer(wxVERTICAL);
s2->Add(list_active, 1, wxEXPAND); s2->Add(list_active, 1, wxEXPAND);
s2->Add(list_inactive, 1, wxEXPAND);*/ s2->Add(list_inactive, 1, wxEXPAND);*/
s->SetSizeHints(this);
SetSizer(s);
} }
void KeywordsPanel::onChangeSet() { void KeywordsPanel::onChangeSet() {
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <util/prec.hpp> #include <util/prec.hpp>
#include <gui/set/panel.hpp> #include <gui/set/panel.hpp>
class wxSplitterWindow;
class KeywordList; class KeywordList;
class TextCtrl; class TextCtrl;
...@@ -25,8 +26,13 @@ class KeywordsPanel : public SetWindowPanel { ...@@ -25,8 +26,13 @@ class KeywordsPanel : public SetWindowPanel {
virtual void onChangeSet(); virtual void onChangeSet();
private: private:
// --------------------------------------------------- : Controls
wxSplitterWindow* splitter;
KeywordList* list; KeywordList* list;
TextCtrl* keyword; TextCtrl* keyword;
TextCtrl* match;
TextCtrl* reminder;
TextCtrl* rules;
}; };
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
......
...@@ -125,7 +125,7 @@ void DataViewer::onAction(const Action& action, bool undone) { ...@@ -125,7 +125,7 @@ void DataViewer::onAction(const Action& action, bool undone) {
} }
TYPE_CASE(action, ValueAction) { TYPE_CASE(action, ValueAction) {
FOR_EACH(v, viewers) { FOR_EACH(v, viewers) {
if (v->getValue() == action.valueP) { if (v->getValue()->equals( action.valueP.get() )) {
// refresh the viewer // refresh the viewer
v->onAction(action, undone); v->onAction(action, undone);
onChange(); onChange();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment