From d40d3de46c2adcc4ce8e467ef237c5ae0b702df0 Mon Sep 17 00:00:00 2001 From: twanvl Date: Mon, 20 Nov 2006 00:41:09 +0000 Subject: [PATCH] DataEditor is done git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@79 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/gui/control/card_editor.cpp | 128 ++++++++++++++++++++++++++++++-- src/gui/control/card_editor.hpp | 20 ++++- src/render/card/viewer.cpp | 1 + src/render/card/viewer.hpp | 3 + 4 files changed, 146 insertions(+), 6 deletions(-) diff --git a/src/gui/control/card_editor.cpp b/src/gui/control/card_editor.cpp index 84005cc4..254928d4 100644 --- a/src/gui/control/card_editor.cpp +++ b/src/gui/control/card_editor.cpp @@ -14,6 +14,7 @@ #include DECLARE_TYPEOF_COLLECTION(ValueViewerP); +DECLARE_TYPEOF_COLLECTION(ValueViewer*); // ----------------------------------------------------------------------------- : DataEditor @@ -54,6 +55,82 @@ ValueViewer* DataEditor::focusedViewer() const { // ----------------------------------------------------------------------------- : Selection +void DataEditor::select(ValueViewer* v) { + ValueEditor* old_editor = current_editor; + current_viewer = v; + current_editor = v->getEditor(); + if (current_editor != old_editor) { + // selection has changed + if (old_editor) old_editor->onLoseFocus(); + if (current_editor) current_editor->onFocus(); + onChange(); + } +} + +void DataEditor::selectFirst() { + selectByTabPos(0); +} +bool DataEditor::selectNext() { + return selectByTabPos(currentTabPos() + 1); +} +bool DataEditor::selectPrevious() { + return selectByTabPos(currentTabPos() - 1); +} + +bool DataEditor::selectByTabPos(int tab_pos) { + if (tab_pos >= 0 && (size_t)tab_pos < by_tab_index.size()) { + select(by_tab_index[tab_pos]); + return true; + } else if (!by_tab_index.empty()) { + // also select something! so when we regain focus the selected editor makes sense + if (tab_pos < 0) select(by_tab_index.back()); + else select(by_tab_index.front()); + } + return false; +} +int DataEditor::currentTabPos() const { + int i = 0; + FOR_EACH_CONST(v, by_tab_index) { + if (v == current_viewer) return i; + ++i; + } + return -1; +} + +struct CompareTabIndex { + bool operator() (ValueViewer* a, ValueViewer* b) { + Style& as = *a->getStyle(), &bs = *b->getStyle(); + Field& af = *as.fieldP, &bf = *bs.fieldP; + if (af.tab_index < bf.tab_index) return true; + if (af.tab_index > bf.tab_index) return false; + if (abs(as.top - bs.top) < 15) { + // the fields are almost on the same 'row' + // compare horizontally first + if (as.left < bs.left) return true; // horizontal sorting + if (as.left > bs.left) return false; + if (as.top < bs.top) return true; // vertical sorting + } else { + // compare vertically first + if (as.top < bs.top) return true; // vertical sorting + if (as.top > bs.top) return false; + if (as.left < bs.left) return true; // horizontal sorting + } + return false; + } +}; +void DataEditor::createTabIndex() { + by_tab_index.clear(); + FOR_EACH(v, viewers) { + if (v->getField()->editable && v->getStyle()->visible) { + by_tab_index.push_back(v.get()); + } + } + stable_sort(by_tab_index.begin(), by_tab_index.end(), CompareTabIndex()); +} +void DataEditor::onInit() { + createTabIndex(); +} + // ----------------------------------------------------------------------------- : Clipboard & Formatting bool DataEditor::canCut() const { return current_editor && current_editor->canCut(); } @@ -159,6 +236,27 @@ RealPoint DataEditor::mousePoint(const wxMouseEvent& ev) { // ----------------------------------------------------------------------------- : Keyboard events +void DataEditor::onChar(wxKeyEvent& ev) { + if (ev.GetKeyCode() == WXK_TAB) { + if (!ev.ShiftDown()) { + // try to select the next editor + if (selectNext()) return; + // send a navigation event to our parent, to select another control + wxNavigationKeyEvent evt; + GetParent()->ProcessEvent(evt); + } else { + // try to select the previos editor + if (selectPrevious()) return; + // send a navigation event to our parent, to select another control + wxNavigationKeyEvent evt; + evt.SetDirection(false); + GetParent()->ProcessEvent(evt); + } + } else if (current_editor) { + current_editor->onChar(ev); + } +} + // ----------------------------------------------------------------------------- : Menu events void DataEditor::onContextMenu(wxContextMenuEvent& ev) { @@ -175,9 +273,29 @@ void DataEditor::onContextMenu(wxContextMenuEvent& ev) { } } } +void DataEditor::onMenu(wxCommandEvent& ev) { + if (current_editor) { + current_editor->onMenu(ev); + } else { + ev.Skip(); + } +} // ----------------------------------------------------------------------------- : Focus events +void DataEditor::onFocus(wxFocusEvent& ev) { + if (current_editor) { + current_editor->onFocus(); + onChange(); + } +} +void DataEditor::onLoseFocus(wxFocusEvent& ev) { + if (current_editor) { + current_editor->onLoseFocus(); + onChange(); + } +} + // ----------------------------------------------------------------------------- : Event table BEGIN_EVENT_TABLE(DataEditor, CardViewer) @@ -188,9 +306,9 @@ BEGIN_EVENT_TABLE(DataEditor, CardViewer) EVT_MOTION (DataEditor::onMotion) EVT_MOUSEWHEEL (DataEditor::onMouseWheel) EVT_LEAVE_WINDOW (DataEditor::onMouseLeave) -// EVT_CONTEXT_MENU (DataEditor::onContextMenu) -// EVT_CHAR (DataEditor::onChar) -// EVT_SET_FOCUS (DataEditor::onFocus) -// EVT_KILL_FOCUS (DataEditor::onLoseFocus) -// EVT_MENU (wxID_ANY, DataEditor::onMenu) + EVT_CONTEXT_MENU (DataEditor::onContextMenu) + EVT_MENU (wxID_ANY, DataEditor::onMenu) + EVT_CHAR (DataEditor::onChar) + EVT_SET_FOCUS (DataEditor::onFocus) + EVT_KILL_FOCUS (DataEditor::onLoseFocus) END_EVENT_TABLE () diff --git a/src/gui/control/card_editor.hpp b/src/gui/control/card_editor.hpp index 9126124d..4b9b2375 100644 --- a/src/gui/control/card_editor.hpp +++ b/src/gui/control/card_editor.hpp @@ -30,7 +30,14 @@ class DataEditor : public CardViewer { // --------------------------------------------------- : Selection - // TODO + /// Select the given viewer, sends focus events + void select(ValueViewer* v); + /// Select the first editable and visible editor (by tab index) + void selectFirst(); + /// Select the next editable editor, returns false if the current editor is the last one + bool selectNext(); + /// Select the previous editable editor, returns false if the current editor is the first one + bool selectPrevious(); // --------------------------------------------------- : Clipboard @@ -53,12 +60,15 @@ class DataEditor : public CardViewer { /// Create an editor for the given style (as opposed to a normal viewer) virtual ValueViewerP makeViewer(const StyleP&); + virtual void onInit(); + // --------------------------------------------------- : Data private: DECLARE_EVENT_TABLE(); ValueViewer* current_viewer; ///< The currently selected viewer ValueEditor* current_editor; ///< The currently selected editor, corresponding to the viewer + vector by_tab_index; ///< The editable viewers, sorted by tab index // --------------------------------------------------- : Events @@ -87,6 +97,14 @@ class DataEditor : public CardViewer { void selectFieldNoEvents(const RealPoint& pos); /// Convert mouse coordinates to internal coordinates RealPoint mousePoint(const wxMouseEvent& e); + + // Create tab index ordering of the (editable) viewers + void createTabIndex(); + /// Select the field with the given position in the by_tab_index list + /** Returns success */ + bool selectByTabPos(int tab_pos); + /// Find the tab pos of the current viewer, returns -1 if not found + int currentTabPos() const; }; /// By default a DataEditor edits cards diff --git a/src/render/card/viewer.cpp b/src/render/card/viewer.cpp index 03c81dcf..c0ea623c 100644 --- a/src/render/card/viewer.cpp +++ b/src/render/card/viewer.cpp @@ -90,6 +90,7 @@ void DataViewer::setStyles(IndexMap& styles) { } // sort viewers by z-index of style stable_sort(viewers.begin(), viewers.end(), CompareViewer()); + onInit(); } void DataViewer::setData(IndexMap& values) { diff --git a/src/render/card/viewer.hpp b/src/render/card/viewer.hpp index 4aa0c189..cca68ea0 100644 --- a/src/render/card/viewer.hpp +++ b/src/render/card/viewer.hpp @@ -73,6 +73,9 @@ class DataViewer : public SetView { /// Notification that the total image has changed virtual void onChange() {} + /// Notification that the viewers are initialized + virtual void onInit() {} + vector viewers; ///< The viewers for the different values in the data CardP card; ///< The card that is currently displayed, if any };