ultimatepp/uppsrc/RichEdit/DiagramEditor.h

214 lines
5.9 KiB
C++

#define IMAGECLASS DiagramImg
#define IMAGEFILE <RichEdit/Diagram.iml>
#include <Draw/iml_header.h>
#define LAYOUTFILE <RichEdit/Diagram.lay>
#include <CtrlCore/lay.h>
class DiaRichEdit : public RichEdit {
bool Key(dword key, int count) override;
void PasteFilter(RichText& txt, const String& fmt) override;
public:
Event<> WhenEnter;
Event<> WhenEsc;
};
class ColumnPopUp : public Ctrl {
int cursor = -1;
void Paint(Draw& w) override;
void MouseMove(Point p, dword keyflags) override;
void LeftUp(Point, dword keyflags) override;
void MouseLeave() override;
void Deactivate() override;
public:
void PopUp(const Rect& sr, Ctrl *owner);
int Execute(const Rect& sr, Ctrl *owner);
int Execute();
int columns = 4;
Size isz = Size(64, 32);
int count = 18;
Event<int> WhenSelect;
Event<Draw&, const Rect&, int, bool> WhenPaintItem;
ColumnPopUp();
};
const VectorMap<String, Vector<Tuple<int, String>>>& UnicodeSymbols();
String SelectFontSymbolSvg(Sizef& sz);
int SelectFontSymbol(Font& fnt);
int SelectSpecialSymbol();
class DiagramEditor : public Ctrl, Diagram::PaintInfo {
public:
void Paint(Draw& w) override;
Image CursorImage(Point p, dword keyflags) override;
void LeftDown(Point p, dword keyflags) override;
void LeftDouble(Point p, dword keyflags) override;
void MouseMove(Point p, dword keyflags) override;
void LeftUp(Point, dword keyflags) override;
void RightDown(Point p, dword keyflags) override;
void RightUp(Point p, dword keyflags) override;
void HorzMouseWheel(Point p, int zdelta, dword keyflags) override;
void MouseWheel(Point p, int zdelta, dword keyflags) override;
bool Key(dword key, int count) override;
void Layout() override;
void Skin() override;
private:
struct DropColumns : public MultiButton, public Display {
ColumnPopUp popup;
using MultiButton::Paint;
void Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const override;
DropColumns();
};
Diagram data;
bool allow_dark_content = false;
bool dark_content = false;
Size icon_sz;
Point sizehandle = Point(0, 0);
Point draghandle = Point(0, 0);
Point dragstart = Point(0, 0);
Point dragcurrent = Point(0, 0);
Pointf dragfrom = Point(0, 0);
Pointf drag_cp = Point(0, 0);
double base_rotate = 0;
Vector<Pointf> sdragfrom;
bool doselection = false; // we are doing rect selection
bool grid = true; // snap to grid
bool edit_text = false; // text editor is visible
int zoom_percent = 100;
int paint_ms = 0;
struct Cn : Moveable<Cn> {
int mi; // item index
int ci; // connection index
int li; // line item index
int pi; // point index
};
bool moving = false; // moving hysteresis
bool moved = false; // move detection (for fast paints)
Vector<Cn> conns; // connections, created at the drag start, updates line connections
BinUndoRedo undoredo;
ToolBar toolbar;
DropColumns shape, line_start, line_end, line_dash, line_width;
DiaRichEdit text_editor;
RichEdit editor_bar; // misusing RichEdit to implement selection bar
ColorButton ink, paper;
int tool = -1;
int tool_count = 2; // TODO
DiagramItem tl[2];
ScrollBars sb;
void SetupDark(ColorPusher& c) const;
bool IsDarkContent() const;
void CancelSelection();
bool IsCursor() const { return cursor >= 0 && cursor < data.item.GetCount(); }
DiagramItem& CursorItem();
const DiagramItem& CursorItem() const { return const_cast<DiagramEditor *>(this)->CursorItem(); }
Rectf GetCursorRect() const { return IsCursor() ? data.item[cursor].GetRect() : Null; }
void SetCursor(int i);
void KillCursor() { SetCursor(-1); }
Point GetSizeHandle(Point p) const;
Point GetHandle(int item, Point p) const;
void TheBar(Bar& bar);
void SetBar();
void SyncEditor();
void SyncEditorRect();
void Sync();
void Reset();
void ResetUndo();
void Commit();
int FindItem(Point p) const;
String GetCurrent();
bool SetCurrent(const String& s);
void StartText();
void FinishText();
void MoveFrontBack(bool back);
// void ChangeSize();
void Zoom();
double GetZoom() const { return DPI(1) * 0.01 * zoom_percent; }
void Map(Point& p);
Image MakeIcon(DiagramItem& m, Size isz);
int IconDlCx() { return DPI(24 + 4 + 18); }
Image ShapeIcon(int i);
Image CapIcon(int start, int end);
Image DashIcon(int i);
Image WidthIcon(int i);
void PrepareConns();
void UseConns();
void Grid(Point& p);
void Grid(Pointf& p);
void ChangeSize();
void PopPaint(Draw& w, const Rect& r, const Image& m, bool sel);
void Shapes(ColumnPopUp& shape);
void Caps(ColumnPopUp& m, bool left);
void Dashes(ColumnPopUp& m);
void Widths(ColumnPopUp& m);
void AddImage(Pointf pos, const Image& img);
RichText::FormatInfo GetFormatInfo(int itemi) const;
RichText::FormatInfo GetSelectionFormatInfo() const;
void FixPositions();
void ForEachConst(Event<const DiagramItem&> fn) const;
void ForEach(Event<DiagramItem&> fn);
enum {
ATTR_SHAPE = 0x0001,
ATTR_CAP0 = 0x0002,
ATTR_CAP1 = 0x0004,
ATTR_WIDTH = 0x0008,
ATTR_DASH = 0x0010,
ATTR_INK = 0x0020,
ATTR_PAPER = 0x0040,
ATTR_ALL = 0xffffffff
};
void SetAttrs(DiagramItem& m, dword attrs);
void SetAttrs(dword attr);
void GetAttrs(const DiagramItem& m);
void GetAttrs();
void ComputeAspectSize(DiagramItem& m, Sizef& sz_cx, Sizef& sz_cy);
DiagramItem& AddItem(int shape);
void Copy();
void Cut();
void Paste();
void Delete();
void Duplicate();
void SelectAll();
void Align(bool horz, int align);
public:
String Save() const;
bool Load(const String& s);
void SerializeSettings(Stream& s);
DiagramEditor& DarkContent(bool b = true);
DiagramEditor& AllowDarkContent(bool b = true);
DiagramEditor();
};