Commit 3b5361c2 authored by twanvl's avatar twanvl

DataEditor is done

parent 40241ca8
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <data/settings.hpp> #include <data/settings.hpp>
DECLARE_TYPEOF_COLLECTION(ValueViewerP); DECLARE_TYPEOF_COLLECTION(ValueViewerP);
DECLARE_TYPEOF_COLLECTION(ValueViewer*);
// ----------------------------------------------------------------------------- : DataEditor // ----------------------------------------------------------------------------- : DataEditor
...@@ -54,6 +55,82 @@ ValueViewer* DataEditor::focusedViewer() const { ...@@ -54,6 +55,82 @@ ValueViewer* DataEditor::focusedViewer() const {
// ----------------------------------------------------------------------------- : Selection // ----------------------------------------------------------------------------- : 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 // ----------------------------------------------------------------------------- : Clipboard & Formatting
bool DataEditor::canCut() const { return current_editor && current_editor->canCut(); } bool DataEditor::canCut() const { return current_editor && current_editor->canCut(); }
...@@ -159,6 +236,27 @@ RealPoint DataEditor::mousePoint(const wxMouseEvent& ev) { ...@@ -159,6 +236,27 @@ RealPoint DataEditor::mousePoint(const wxMouseEvent& ev) {
// ----------------------------------------------------------------------------- : Keyboard events // ----------------------------------------------------------------------------- : 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 // ----------------------------------------------------------------------------- : Menu events
void DataEditor::onContextMenu(wxContextMenuEvent& ev) { void DataEditor::onContextMenu(wxContextMenuEvent& ev) {
...@@ -175,9 +273,29 @@ 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 // ----------------------------------------------------------------------------- : 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 // ----------------------------------------------------------------------------- : Event table
BEGIN_EVENT_TABLE(DataEditor, CardViewer) BEGIN_EVENT_TABLE(DataEditor, CardViewer)
...@@ -188,9 +306,9 @@ BEGIN_EVENT_TABLE(DataEditor, CardViewer) ...@@ -188,9 +306,9 @@ BEGIN_EVENT_TABLE(DataEditor, CardViewer)
EVT_MOTION (DataEditor::onMotion) EVT_MOTION (DataEditor::onMotion)
EVT_MOUSEWHEEL (DataEditor::onMouseWheel) EVT_MOUSEWHEEL (DataEditor::onMouseWheel)
EVT_LEAVE_WINDOW (DataEditor::onMouseLeave) EVT_LEAVE_WINDOW (DataEditor::onMouseLeave)
// EVT_CONTEXT_MENU (DataEditor::onContextMenu) EVT_CONTEXT_MENU (DataEditor::onContextMenu)
// EVT_CHAR (DataEditor::onChar) EVT_MENU (wxID_ANY, DataEditor::onMenu)
// EVT_SET_FOCUS (DataEditor::onFocus) EVT_CHAR (DataEditor::onChar)
// EVT_KILL_FOCUS (DataEditor::onLoseFocus) EVT_SET_FOCUS (DataEditor::onFocus)
// EVT_MENU (wxID_ANY, DataEditor::onMenu) EVT_KILL_FOCUS (DataEditor::onLoseFocus)
END_EVENT_TABLE () END_EVENT_TABLE ()
...@@ -30,7 +30,14 @@ class DataEditor : public CardViewer { ...@@ -30,7 +30,14 @@ class DataEditor : public CardViewer {
// --------------------------------------------------- : Selection // --------------------------------------------------- : 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 // --------------------------------------------------- : Clipboard
...@@ -53,12 +60,15 @@ class DataEditor : public CardViewer { ...@@ -53,12 +60,15 @@ class DataEditor : public CardViewer {
/// Create an editor for the given style (as opposed to a normal viewer) /// Create an editor for the given style (as opposed to a normal viewer)
virtual ValueViewerP makeViewer(const StyleP&); virtual ValueViewerP makeViewer(const StyleP&);
virtual void onInit();
// --------------------------------------------------- : Data // --------------------------------------------------- : Data
private: private:
DECLARE_EVENT_TABLE(); DECLARE_EVENT_TABLE();
ValueViewer* current_viewer; ///< The currently selected viewer ValueViewer* current_viewer; ///< The currently selected viewer
ValueEditor* current_editor; ///< The currently selected editor, corresponding to the viewer ValueEditor* current_editor; ///< The currently selected editor, corresponding to the viewer
vector<ValueViewer*> by_tab_index; ///< The editable viewers, sorted by tab index
// --------------------------------------------------- : Events // --------------------------------------------------- : Events
...@@ -87,6 +97,14 @@ class DataEditor : public CardViewer { ...@@ -87,6 +97,14 @@ class DataEditor : public CardViewer {
void selectFieldNoEvents(const RealPoint& pos); void selectFieldNoEvents(const RealPoint& pos);
/// Convert mouse coordinates to internal coordinates /// Convert mouse coordinates to internal coordinates
RealPoint mousePoint(const wxMouseEvent& e); 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 /// By default a DataEditor edits cards
......
...@@ -90,6 +90,7 @@ void DataViewer::setStyles(IndexMap<FieldP,StyleP>& styles) { ...@@ -90,6 +90,7 @@ void DataViewer::setStyles(IndexMap<FieldP,StyleP>& styles) {
} }
// sort viewers by z-index of style // sort viewers by z-index of style
stable_sort(viewers.begin(), viewers.end(), CompareViewer()); stable_sort(viewers.begin(), viewers.end(), CompareViewer());
onInit();
} }
void DataViewer::setData(IndexMap<FieldP,ValueP>& values) { void DataViewer::setData(IndexMap<FieldP,ValueP>& values) {
......
...@@ -73,6 +73,9 @@ class DataViewer : public SetView { ...@@ -73,6 +73,9 @@ class DataViewer : public SetView {
/// Notification that the total image has changed /// Notification that the total image has changed
virtual void onChange() {} virtual void onChange() {}
/// Notification that the viewers are initialized
virtual void onInit() {}
vector<ValueViewerP> viewers; ///< The viewers for the different values in the data vector<ValueViewerP> viewers; ///< The viewers for the different values in the data
CardP card; ///< The card that is currently displayed, if any CardP card; ///< The card that is currently displayed, if any
}; };
......
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