mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
DataEditor is done
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@79 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include <data/settings.hpp>
|
||||
|
||||
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 ()
|
||||
|
||||
@@ -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<ValueViewer*> 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
|
||||
|
||||
@@ -90,6 +90,7 @@ void DataViewer::setStyles(IndexMap<FieldP,StyleP>& styles) {
|
||||
}
|
||||
// sort viewers by z-index of style
|
||||
stable_sort(viewers.begin(), viewers.end(), CompareViewer());
|
||||
onInit();
|
||||
}
|
||||
|
||||
void DataViewer::setData(IndexMap<FieldP,ValueP>& values) {
|
||||
|
||||
@@ -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<ValueViewerP> viewers; ///< The viewers for the different values in the data
|
||||
CardP card; ///< The card that is currently displayed, if any
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user