mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 13:06:59 -04:00
Partially working text editor
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@99 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
+52
-13
@@ -32,7 +32,7 @@ struct TextViewer::Line {
|
||||
/// Index just beyond the last character on this line
|
||||
size_t end() const { return start + positions.size() - 1; }
|
||||
/// Find the index of the character at the given position on this line
|
||||
/** Always returns a value in the range [start..end()) */
|
||||
/** Always returns a value in the range [start..end()] */
|
||||
size_t posToIndex(double x) const;
|
||||
|
||||
/// Is this line visible using the given rectangle?
|
||||
@@ -47,13 +47,12 @@ struct TextViewer::Line {
|
||||
|
||||
size_t TextViewer::Line::posToIndex(double x) const {
|
||||
// largest index with pos <= x
|
||||
vector<double>::const_iterator it1 = lower_bound(positions.begin(), positions.end(), x);
|
||||
if (it1 == positions.end()) return end();
|
||||
vector<double>::const_iterator it2 = lower_bound(positions.begin(), positions.end(), x);
|
||||
if (it2 == positions.begin()) return start;
|
||||
// first index with pos > x
|
||||
vector<double>::const_iterator it2 = it1 + 1;
|
||||
if (it2 == positions.end()) return it1 - positions.begin();
|
||||
if (x - *it1 <= *it2 - x) return it1 - positions.begin(); // it1 is closer
|
||||
else return it2 - positions.begin(); // it2 is closer
|
||||
vector<double>::const_iterator it1 = it2 - 1;
|
||||
if (x - *it1 <= *it2 - x) return it1 - positions.begin() + start; // it1 is closer
|
||||
else return it2 - positions.begin() + start; // it2 is closer
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : TextViewer
|
||||
@@ -65,7 +64,7 @@ TextViewer::~TextViewer() {}
|
||||
// ----------------------------------------------------------------------------- : Drawing
|
||||
|
||||
void TextViewer::draw(RotatedDC& dc, const String& text, const TextStyle& style, Context& ctx, DrawWhat what) {
|
||||
Rotater r(dc, Rotation(style.angle, style.getRect()));
|
||||
Rotater r(dc, style.getRotation());
|
||||
if (lines.empty()) {
|
||||
// not prepared yet
|
||||
prepareElements(text, style, ctx);
|
||||
@@ -81,7 +80,7 @@ void TextViewer::draw(RotatedDC& dc, const String& text, const TextStyle& style,
|
||||
}
|
||||
|
||||
void TextViewer::drawSelection(RotatedDC& dc, const TextStyle& style, size_t sel_start, size_t sel_end) {
|
||||
Rotater r(dc, Rotation(style.angle, style.getRect()));
|
||||
Rotater r(dc, style.getRotation());
|
||||
if (sel_start == sel_end) return;
|
||||
if (sel_end < sel_start) swap(sel_start, sel_end);
|
||||
dc.SetBrush(*wxBLACK_BRUSH);
|
||||
@@ -109,6 +108,25 @@ void TextViewer::reset() {
|
||||
|
||||
// ----------------------------------------------------------------------------- : Positions
|
||||
|
||||
const TextViewer::Line& TextViewer::findLine(size_t index) const {
|
||||
FOR_EACH_CONST(l, lines) {
|
||||
if (l.end() > index) return l;
|
||||
}
|
||||
return lines.front();
|
||||
}
|
||||
|
||||
size_t TextViewer::moveLine(size_t index, int delta) const {
|
||||
const Line* line1 = &findLine(index);
|
||||
const Line* line2 = line1 + delta;
|
||||
if (line2 >= &lines.front() && line2 <= &lines.back()) {
|
||||
size_t idx = index - line1->start;
|
||||
if (idx < 0 || idx >= line1->positions.size()) return index; // can't move
|
||||
return line2->posToIndex(line1->positions[idx]); // character at the same position
|
||||
} else {
|
||||
return index; // can't move
|
||||
}
|
||||
}
|
||||
|
||||
size_t TextViewer::lineStart(size_t index) const {
|
||||
if (lines.empty()) return 0;
|
||||
return findLine(index).start;
|
||||
@@ -119,11 +137,32 @@ size_t TextViewer::lineEnd(size_t index) const {
|
||||
return findLine(index).end();
|
||||
}
|
||||
|
||||
const TextViewer::Line& TextViewer::findLine(size_t index) const {
|
||||
FOR_EACH_CONST(l, lines) {
|
||||
if (l.end() > index) return l;
|
||||
struct CompareTop {
|
||||
inline bool operator () (const TextViewer::Line& l, double y) const { return l.top < y; }
|
||||
inline bool operator () (double y, const TextViewer::Line& l) const { return y < l.top; }
|
||||
};
|
||||
size_t TextViewer::indexAt(const RealPoint& pos) const {
|
||||
// 1. find the line
|
||||
vector<Line>::const_iterator l = lower_bound(lines.begin(), lines.end(), pos.y, CompareTop());
|
||||
if (l != lines.begin()) l--;
|
||||
assert(l != lines.end());
|
||||
// 2. find char on line
|
||||
return l->posToIndex(pos.x);
|
||||
}
|
||||
|
||||
RealRect TextViewer::charRect(size_t index) const {
|
||||
const Line& l = findLine(index);
|
||||
size_t pos = index - l.start;
|
||||
if (pos >= l.positions.size()) {
|
||||
return RealRect(l.positions.back(), l.top, 0, l.line_height);
|
||||
} else {
|
||||
return RealRect(l.positions[pos], l.top, l.positions[pos + 1] - l.positions[pos], l.line_height);
|
||||
}
|
||||
return lines.front();
|
||||
}
|
||||
|
||||
double TextViewer::heightOfLastLine() const {
|
||||
if (lines.empty()) return 0;
|
||||
else return lines.back().line_height;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Elements
|
||||
|
||||
@@ -56,16 +56,32 @@ class TextViewer {
|
||||
|
||||
// --------------------------------------------------- : Positions
|
||||
|
||||
/// Find the character index that is before the given index, and which has a nonzero width
|
||||
size_t moveLeft(size_t index) const;
|
||||
/// Find the character index that is before/after the given index, and which has a nonzero width
|
||||
// size_t moveChar(size_t index, int delta) const;
|
||||
/// Find the character index that is on a line above/below index
|
||||
/** If this would move outisde the text, returns the input index */
|
||||
size_t moveLine(size_t index, int delta) const;
|
||||
|
||||
/// The character index of the start of the line that character #index is on
|
||||
size_t lineStart(size_t index) const;
|
||||
/// The character index past the end of the line that character #index is on
|
||||
size_t lineEnd (size_t index) const;
|
||||
|
||||
/// Find the index of the character at the given position
|
||||
/** If the position is before everything returns 0,
|
||||
* if it is after everything returns text.size().
|
||||
* The position is in internal coordinates */
|
||||
size_t indexAt(const RealPoint& pos) const;
|
||||
/// Find the position of the character at the given index
|
||||
/** The position is in internal coordinates */
|
||||
RealPoint posOf(size_t index) const;
|
||||
|
||||
/// Return the rectangle around a single character
|
||||
RealRect charRect(size_t index) const;
|
||||
|
||||
/// Return the height of the last line
|
||||
double heightOfLastLine() const;
|
||||
|
||||
private:
|
||||
// --------------------------------------------------- : More drawing
|
||||
double scale; /// < Scale when drawing
|
||||
|
||||
@@ -25,7 +25,7 @@ class TextValueViewer : public ValueViewer {
|
||||
virtual void onValueChange();
|
||||
virtual void onStyleChange();
|
||||
|
||||
private:
|
||||
protected:
|
||||
TextViewer v;
|
||||
};
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ RealRect ValueViewer::boundingBox() const {
|
||||
|
||||
void ValueViewer::drawFieldBorder(RotatedDC& dc) {
|
||||
if (viewer.drawBorders() && getField()->editable) {
|
||||
dc.SetPen(viewer.borderPen(viewer.focusedViewer() == this));
|
||||
dc.SetPen(viewer.borderPen(isCurrent()));
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc.DrawRectangle(styleP->getRect().grow(dc.trInvS(1)));
|
||||
}
|
||||
@@ -50,6 +50,9 @@ void ValueViewer::drawFieldBorder(RotatedDC& dc) {
|
||||
bool ValueViewer::nativeLook() const {
|
||||
return viewer.nativeLook();
|
||||
}
|
||||
bool ValueViewer::isCurrent() const {
|
||||
return viewer.focusedViewer() == this;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Type dispatch
|
||||
|
||||
|
||||
Reference in New Issue
Block a user