diff --git a/uppsrc/Core/src.tpp/BinDiff_en-us.tpp b/uppsrc/Core/src.tpp/BinDiff_en-us.tpp index 46d6746dd..40cedeb16 100644 --- a/uppsrc/Core/src.tpp/BinDiff_en-us.tpp +++ b/uppsrc/Core/src.tpp/BinDiff_en-us.tpp @@ -1,4 +1,4 @@ -topic ""; +topic "BinDiff/UndoRedo"; [i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class] [l288;2 $$2,2#27521748481378242620020725143825:desc] [0 $$3,0#96390100711032703541132217272105:end] diff --git a/uppsrc/RichEdit/Bar.cpp b/uppsrc/RichEdit/Bar.cpp new file mode 100644 index 000000000..f262c9a7f --- /dev/null +++ b/uppsrc/RichEdit/Bar.cpp @@ -0,0 +1,71 @@ +#include "RichEdit.h" + +namespace Upp { + +void DiagramEditor::TheBar(Bar& bar) +{ + bool b = IsCursor(); + bool line = b && CursorItem().IsLine(); + + bar.Add(undoredo.IsUndo(), CtrlImg::undo(), [=] { SetCurrent(undoredo.Undo(GetCurrent())); }) + .Key(K_CTRL_Z); + bar.Add(undoredo.IsRedo(), CtrlImg::redo(), [=] { SetCurrent(undoredo.Redo(GetCurrent())); }) + .Key(K_SHIFT|K_CTRL_Z); + bar.Separator(); + bar.Add(b, "Cut", CtrlImg::cut(), [=] { Cut(); }) + .Key(K_SHIFT_DELETE) + .Key(K_CTRL_X); + bar.Add(b, "Copy", CtrlImg::copy(), [=] { Copy(); }) + .Key(K_CTRL_INSERT) + .Key(K_CTRL_C); + bar.Add(IsClipboardAvailableText(), "Paste", CtrlImg::paste(), [=] { Paste(); }) + .Key(K_SHIFT_INSERT) + .Key(K_CTRL_V); + bar.Add(b, "Delete", CtrlImg::remove(), [=] { Delete(); }) + .Key(K_DELETE); + bar.Add(b, "Duplicate", DiagramImg::Duplicate(), [=] { Duplicate(); }) + .Key(K_CTRL_D); + bar.Add("Select all", CtrlImg::select_all(), [=] { SelectAll(); }) + .Key(K_CTRL_A); + bar.Separator(); + bar.Add(b, "Move back", DiagramImg::MoveBack(), [=] { MoveFrontBack(true); }); + bar.Add(b, "Move front", DiagramImg::MoveFront(), [=] { MoveFrontBack(false); }); + bar.Separator(); + bool multi = sel.GetCount() > 1; + bar.Add(multi, "Align left", DiagramImg::AlignLeft(), [=] { Align(true, ALIGN_LEFT); }); + bar.Add(multi, "Horizontal center", DiagramImg::AlignHCenter(), [=] { Align(true, ALIGN_CENTER); }); + bar.Add(multi, "Align right", DiagramImg::AlignRight(), [=] { Align(true, ALIGN_RIGHT); }); + bar.Separator(); + bar.Add(multi, "Align top", DiagramImg::AlignTop(), [=] { Align(false, ALIGN_TOP); }); + bar.Add(multi, "Vertical center", DiagramImg::AlignVCenter(), [=] { Align(false, ALIGN_CENTER); }); + bar.Add(multi, "Align bottom", DiagramImg::AlignBottom(), [=] { Align(false, ALIGN_BOTTOM); }); + bar.Separator(); + bar.Add(multi, "Same width", DiagramImg::SameWidth(), [=] { Align(true, ALIGN_JUSTIFY); }); + bar.Add(multi, "Same height", DiagramImg::SameHeight(), [=] { Align(false, ALIGN_JUSTIFY); }); + bar.Add(multi, "Same size", DiagramImg::SameSize(), [=] { Align(true, ALIGN_JUSTIFY); Align(false, ALIGN_JUSTIFY); }); + bar.Separator(); + bar.Add("Zoom", MakeZoomIcon(0.01 * zoom_percent), [=]{ Zoom(); }); + bar.Add("Snap to grid", DiagramImg::Grid(), [=] { grid = !grid; SetBar(); }).Check(grid); + bar.Separator(); + bar.Add(b, shape, DPI(50)); + bar.Add(line, line_start, DPI(50)); + bar.Add(line, line_end, DPI(50)); + bar.Add(b, line_width, DPI(50)); + bar.Add(b, line_dash, DPI(50)); + bar.Add(b, ink); + bar.Add(b, paper); + bar.Break(); +// ink.DarkContent(IsDarkContent()); + text_editor.FontTools(bar); + text_editor.InkTool(bar); + text_editor.PaperTool(bar); + bar.Separator(); + text_editor.ParaTools(bar); +} + +void DiagramEditor::SetBar() +{ + toolbar.Set([=](Bar& bar) { TheBar(bar); }); +} + +} \ No newline at end of file diff --git a/uppsrc/RichEdit/Clip.cpp b/uppsrc/RichEdit/Clip.cpp index 9f493c696..cf3c449c2 100644 --- a/uppsrc/RichEdit/Clip.cpp +++ b/uppsrc/RichEdit/Clip.cpp @@ -32,6 +32,17 @@ void RichEdit::InsertImage() ClipPaste(clip, "image/raw"); } +void RichEdit::InsertDiagram() +{ + TopWindow app; + app.Icon(DiagramImg::Diagram()); + app.Title("Diagram"); + app.Sizeable().Zoomable(); + DiagramEditor de; + app.Add(de.SizePos()); + app.Execute(); +} + bool RichEdit::Accept(PasteClip& d, RichText& clip, String& fmt) { if(IsReadOnly()) diff --git a/uppsrc/RichEdit/Diagram.iml b/uppsrc/RichEdit/Diagram.iml new file mode 100644 index 000000000..57483b809 --- /dev/null +++ b/uppsrc/RichEdit/Diagram.iml @@ -0,0 +1,442 @@ +PREMULTIPLIED +IMAGE_ID(Diagram__UHD) +IMAGE_ID(RoundRect__UHD) +IMAGE_ID(Arrow__UHD) +IMAGE_ID(Grid) +IMAGE_ID(Duplicate__UHD) +IMAGE_ID(AlignLeft__UHD) +IMAGE_ID(AlignHCenter__UHD) +IMAGE_ID(AlignRight__UHD) +IMAGE_ID(AlignTop__UHD) +IMAGE_ID(AlignVCenter__UHD) +IMAGE_ID(AlignBottom__UHD) +IMAGE_ID(SameWidth__UHD) +IMAGE_ID(SameHeight__UHD) +IMAGE_ID(SameSize__UHD) +IMAGE_ID(OK__UHD) +IMAGE_ID(Ink__UHD) +IMAGE_ID(InkNull__UHD) +IMAGE_ID(InkA__UHD) +IMAGE_ID(Paper__UHD) +IMAGE_ID(PaperNull__UHD) +IMAGE_ID(PaperA__UHD) +IMAGE_ID(MoveFront__UHD) +IMAGE_ID(MoveBack__UHD) +IMAGE_ID(Size__UHD) +IMAGE_ID(Diagram) +IMAGE_ID(RoundRect) +IMAGE_ID(Arrow) +IMAGE_ID(Duplicate) +IMAGE_ID(AlignLeft) +IMAGE_ID(AlignHCenter) +IMAGE_ID(AlignRight) +IMAGE_ID(AlignTop) +IMAGE_ID(AlignVCenter) +IMAGE_ID(AlignBottom) +IMAGE_ID(SameWidth) +IMAGE_ID(SameHeight) +IMAGE_ID(SameSize) +IMAGE_ID(OK) +IMAGE_ID(Ink) +IMAGE_ID(InkNull) +IMAGE_ID(InkA) +IMAGE_ID(Paper) +IMAGE_ID(PaperNull) +IMAGE_ID(PaperA) +IMAGE_ID(MoveFront) +IMAGE_ID(MoveBack) +IMAGE_ID(Size) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,215,221,141,131,48,16,69,97,202,73,89,169,42,149,109,5,105,132,149,31,144,80,132,1,131,205,157,159,115) +IMAGE_DATA(36,63,174,52,254,134,132,236,235,61,189,39,34,34,34,162,196,205,78,78,212,212,174,248,251,56,81,83,187,226,239,227) +IMAGE_DATA(68,77,237,138,255,198,153,103,205,169,205,35,178,121,34,252,181,225,175,205,139,127,212,61,120,243,143,182,3,143,254,145) +IMAGE_DATA(118,224,213,191,247,30,84,191,147,189,251,247,216,65,47,251,43,243,68,240,191,179,131,222,246,173,243,68,241,239,246,236) +IMAGE_DATA(117,60,145,252,91,188,44,216,159,157,197,147,127,139,157,5,251,203,179,24,247,111,49,60,245,119,223,249,211,229,92,216) +IMAGE_DATA(129,87,255,171,59,192,191,159,127,203,30,240,31,231,127,118,7,213,131,255,109,255,91,59,192,191,139,255,229,61,88,243) +IMAGE_DATA(55,120,90,195,95,235,223,116,55,252,135,248,159,190,35,254,67,253,15,239,137,255,112,255,221,187,226,255,136,127,245,190) +IMAGE_DATA(66,255,222,89,152,97,175,232,254,213,59,62,60,67,173,204,254,22,118,144,193,191,122,79,193,28,191,225,175,45,187,191) +IMAGE_DATA(122,7,89,252,171,119,21,205,178,110,207,105,196,81,101,109,158,117,209,237,167,141,89,172,204,181,20,217,126,201,242,108) +IMAGE_DATA(165,200,246,37,239,51,122,182,95,242,48,103,84,251,146,167,89,35,230,237,121,137,24,254,218,240,215,198,119,144,62,252) +IMAGE_DATA(181,241,25,208,135,191,54,252,199,214,251,127,121,213,241,152,218,44,251,30,212,86,153,247,160,246,201,108,95,82,27,101) +IMAGE_DATA(246,87,251,96,191,113,190,127,31,23,103,239,14,18,209,182,92,219,31,248,91,15,123,109,248,235,194,94,23,239,92,109) +IMAGE_DATA(174,237,35,62,251,106,207,36,246,37,252,117,97,175,139,119,174,54,215,246,17,159,125,181,103,18,251,18,254,186,176,215) +IMAGE_DATA(197,59,87,155,107,251,136,207,190,218,51,137,125,9,127,93,216,235,226,157,171,237,104,126,207,199,122,106,159,204,246,37) +IMAGE_DATA(181,81,102,127,181,79,102,251,117,106,171,236,254,75,106,179,204,246,68,68,68,68,97,251,7,165,35,134,131,0,0,0) +IMAGE_END_DATA(480, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,215,65,142,194,64,12,69,65,142,195,177,184,255,37,134,197,172,102,193,36,157,182,243,59,164,74,242,150,200) +IMAGE_DATA(207,128,148,231,235,241,122,0,0,0,0,0,192,197,252,124,249,172,40,221,228,142,183,72,239,190,218,156,41,189,235,170) +IMAGE_DATA(211,45,189,223,85,166,67,122,167,171,77,149,85,238,191,130,179,91,104,254,89,119,27,221,247,233,234,164,251,152,202,94) +IMAGE_DATA(218,31,83,209,77,251,57,179,253,180,159,119,180,161,246,117,70,91,106,95,111,164,169,254,245,42,250,51,103,79,87,223) +IMAGE_DATA(253,62,123,218,106,223,75,255,172,255,250,250,239,233,183,245,78,166,125,63,253,179,244,207,210,63,75,255,44,253,179,244) +IMAGE_DATA(207,210,63,75,255,44,253,179,244,207,210,63,75,255,44,253,179,244,207,210,63,75,255,44,253,179,244,207,210,63,75,255) +IMAGE_DATA(44,253,179,244,207,210,63,107,180,191,27,212,217,106,172,127,175,173,190,250,247,58,218,223,13,230,237,109,171,127,143,189) +IMAGE_DATA(93,253,6,234,141,52,213,191,222,104,83,55,168,115,180,165,27,204,155,105,232,157,108,78,69,63,55,56,166,178,155,27) +IMAGE_DATA(140,169,238,181,245,121,238,240,171,179,211,222,207,190,227,29,206,106,51,242,156,111,191,69,178,197,145,103,223,121,58,164) +IMAGE_DATA(119,186,202,116,75,239,183,234,156,41,189,235,106,147,148,222,253,142,205,63,73,55,185,99,115,0,0,0,0,0,248,227) +IMAGE_DATA(13,179,61,31,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(352, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,214,187,13,195,48,16,68,65,149,227,178,220,127,19,114,226,204,146,172,15,143,183,193,12,192,6,246,1,36) +IMAGE_DATA(95,239,229,189,0,0,0,0,0,0,0,0,173,214,239,97,190,117,227,48,207,214,254,26,204,177,183,189,14,245,206,108) +IMAGE_DATA(175,65,157,43,251,235,80,67,131,12,58,244,211,32,131,14,25,116,232,167,65,6,29,250,105,144,65,135,126,26,100,208) +IMAGE_DATA(161,159,6,25,116,200,160,67,63,13,50,232,208,79,131,12,58,244,211,32,131,14,253,52,200,48,187,131,150,191,102,54) +IMAGE_DATA(176,255,190,234,14,238,179,115,42,58,120,79,174,25,221,192,155,126,207,136,14,254,84,207,60,105,224,95,59,206,157,14) +IMAGE_DATA(246,31,75,131,12,26,244,211,32,131,253,51,104,208,207,254,125,220,67,189,236,223,199,95,168,79,197,246,246,63,175,106) +IMAGE_DATA(127,13,254,171,220,94,131,99,51,182,215,224,152,253,243,105,144,207,254,0,0,0,0,0,0,0,0,192,242,1,209,217) +IMAGE_DATA(23,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(256, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,218,225,109,235,48,12,69,97,143,144,49,58,86,150,206,18,134,119,112,23,144,19,145,166,116,69,250,28,128) +IMAGE_DATA(192,251,209,22,210,199,22,16,30,178,189,182,215,22,216,121,227,223,43,196,249,181,113,126,97,127,239,237,173,62,3,17) +IMAGE_DATA(17,17,145,178,51,201,84,77,237,138,127,142,169,154,218,21,255,28,83,53,181,43,254,141,217,247,189,57,159,207,167,57) +IMAGE_DATA(81,95,127,117,30,145,205,140,240,215,134,191,182,44,254,85,247,144,205,191,218,14,50,250,87,218,65,243,126,87,110,199) +IMAGE_DATA(113,52,39,234,235,175,206,243,101,134,58,76,56,79,118,255,136,29,68,217,123,206,83,193,255,206,14,162,237,173,231,169) +IMAGE_DATA(226,31,246,187,23,56,149,252,45,94,43,216,247,158,37,147,191,197,110,5,123,247,89,22,124,127,122,13,187,190,47,234) +IMAGE_DATA(247,202,177,131,172,254,222,29,224,31,231,111,217,3,254,227,252,123,119,112,57,248,135,252,255,39,254,90,127,247,30,86) +IMAGE_DATA(243,95,112,172,153,126,254,228,247,179,251,156,194,241,132,191,214,191,251,142,248,15,245,255,121,79,252,135,251,127,189,43) +IMAGE_DATA(254,83,252,47,239,43,244,127,90,77,31,225,251,243,105,225,175,13,127,109,248,107,195,95,27,254,250,178,190,157,43,133) +IMAGE_DATA(189,62,236,245,97,175,15,123,125,139,217,159,103,142,169,154,218,21,255,28,83,53,181,43,254,57,166,106,106,87,252,91) +IMAGE_DATA(163,251,92,22,254,248,207,12,127,109,89,252,171,238,33,155,127,181,29,100,244,175,180,131,246,253,162,62,167,100,255,92) +IMAGE_DATA(147,234,93,170,122,39,103,247,143,216,65,148,189,231,60,21,252,239,236,32,218,222,122,158,42,254,113,191,123,115,119,144) +IMAGE_DATA(197,223,226,181,130,125,239,89,50,249,91,236,86,176,247,159,101,189,247,167,215,176,239,251,226,62,151,101,221,65,86,127) +IMAGE_DATA(239,14,240,143,243,183,236,1,255,113,254,150,191,5,252,199,248,223,219,1,254,17,254,254,61,172,230,191,222,88,179,253) +IMAGE_DATA(252,185,239,231,39,248,219,238,134,255,8,255,254,59,226,63,210,255,247,61,241,31,237,255,253,174,248,207,240,191,190,175) +IMAGE_DATA(206,255,105,181,125,116,239,207,167,133,191,54,252,181,225,175,13,127,109,248,235,203,250,118,174,20,246,250,176,215,135,189) +IMAGE_DATA(62,236,245,97,79,68,68,68,20,217,63,250,0,78,51,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(544, 2) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,219,81,142,194,48,12,132,97,142,179,199,218,75,115,9,196,29,88,109,37,186,104,85,135,58,216,29,39,253) +IMAGE_DATA(71,154,183,164,184,95,94,80,41,95,223,151,239,203,75,30,70,201,49,193,95,27,252,181,193,95,27,252,181,193,95,27) +IMAGE_DATA(252,181,193,95,27,252,181,193,95,27,252,181,193,95,27,175,191,181,190,90,19,243,136,188,62,254,174,252,218,227,191,163) +IMAGE_DATA(9,121,218,227,191,163,193,121,181,199,127,71,3,243,223,30,255,29,13,202,150,125,61,255,219,237,182,217,235,245,186,217) +IMAGE_DATA(168,245,29,243,123,104,12,123,252,243,253,91,246,248,231,250,191,179,199,63,207,127,143,61,254,57,254,123,237,241,143,247) +IMAGE_DATA(247,216,215,243,183,220,238,247,251,102,163,214,119,204,191,117,75,78,251,158,226,175,179,199,95,107,143,63,254,21,253,143) +IMAGE_DATA(60,3,252,181,103,144,235,207,247,207,238,224,255,119,107,248,75,253,151,219,195,95,234,191,220,34,254,82,255,229,54,241) +IMAGE_DATA(151,250,47,183,58,140,127,193,6,5,255,206,6,6,255,142,6,7,127,103,19,130,191,163,73,193,127,103,19,35,245,39) +IMAGE_DATA(177,193,95,27,252,181,193,95,27,252,181,193,95,27,252,181,193,95,27,252,181,193,95,27,252,181,193,95,155,40,255,1) +IMAGE_DATA(158,155,89,9,125,158,230,254,112,163,17,215,24,224,12,194,159,39,187,7,48,250,233,254,1,206,32,229,247,20,247,16) +IMAGE_DATA(70,63,217,59,192,25,164,253,158,232,30,196,104,239,190,1,206,32,245,247,116,247,48,70,123,246,12,112,6,233,239,147) +IMAGE_DATA(184,7,50,234,90,31,245,158,121,199,60,158,91,53,236,241,207,247,63,236,125,66,247,96,70,93,235,107,251,31,250,62) +IMAGE_DATA(173,123,56,163,174,245,117,253,15,127,159,220,61,160,81,215,250,154,254,146,255,83,184,135,52,234,90,95,207,223,99,63) +IMAGE_DATA(190,255,249,254,79,23,118,190,147,249,171,157,207,236,175,54,198,191,110,207,224,95,249,12,206,226,95,245,12,114,253,249) +IMAGE_DATA(254,217,157,73,253,151,81,241,231,249,195,219,1,141,186,214,215,245,95,70,198,159,231,207,230,96,70,93,235,235,251,47) +IMAGE_DATA(163,207,224,223,218,147,213,192,76,225,223,218,87,216,126,29,125,6,255,214,222,194,246,235,232,51,248,183,246,23,182,95) +IMAGE_DATA(71,159,193,191,117,141,194,246,235,232,51,248,183,174,83,216,254,153,41,252,73,95,240,215,6,127,109,240,215,6,127,109) +IMAGE_DATA(240,215,6,127,109,240,215,6,127,109,240,215,6,127,109,240,23,230,7,147,27,164,57,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(576, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,154,81,110,194,48,16,68,123,156,30,139,75,115,9,196,29,82,181,149,160,42,118,200,122,198,59,107,152,39) +IMAGE_DATA(237,31,120,103,94,248,64,73,62,79,31,167,143,5,217,58,99,114,176,127,45,246,175,197,254,181,216,191,22,251,215,98) +IMAGE_DATA(255,90,236,95,139,253,107,177,127,45,246,175,229,141,253,111,72,207,158,183,106,51,90,47,225,55,240,189,99,120,143,218) +IMAGE_DATA(235,68,255,144,151,129,61,67,187,212,94,39,249,135,156,0,187,194,251,212,94,39,248,135,124,12,240,127,95,104,167,218) +IMAGE_DATA(43,217,63,228,98,144,214,206,195,123,213,94,137,254,33,15,0,189,189,135,118,55,251,94,46,151,230,156,207,231,230,244) +IMAGE_DATA(206,233,125,190,119,126,239,156,201,14,64,246,118,63,221,255,2,254,161,254,4,158,237,223,205,176,184,127,168,59,137,35) +IMAGE_DATA(25,186,57,22,246,15,245,38,114,52,71,51,203,162,254,161,206,100,34,89,30,242,44,232,31,234,59,217,109,56,83,200) +IMAGE_DATA(219,245,122,109,78,239,156,222,231,163,215,49,209,71,146,255,219,206,133,252,79,119,145,236,127,235,246,173,231,127,186,7) +IMAGE_DATA(251,127,59,255,191,11,214,240,159,226,34,209,255,125,193,58,254,83,124,12,0,237,106,246,245,255,207,8,80,150,5,253) +IMAGE_DATA(195,157,201,64,57,22,245,15,247,38,2,101,88,216,63,220,157,4,180,127,113,255,112,127,2,208,238,23,240,15,59,0) +IMAGE_DATA(129,246,238,117,174,52,179,61,0,64,59,213,94,137,254,97,23,131,64,251,212,94,201,254,127,42,9,253,199,191,188,200) +IMAGE_DATA(68,107,9,252,143,125,121,145,25,169,150,232,127,252,203,139,204,104,189,4,255,37,32,123,51,65,236,95,139,253,107,177) +IMAGE_DATA(127,45,246,175,197,254,181,216,191,22,251,215,98,255,90,236,95,139,253,107,177,255,7,166,220,123,18,223,79,235,198,42) +IMAGE_DATA(120,173,233,247,95,139,220,211,124,136,197,238,73,130,250,12,130,237,158,116,13,50,159,179,68,161,61,135,155,229,30,188) +IMAGE_DATA(6,217,207,25,163,80,158,69,207,118,63,120,13,20,207,217,163,192,239,99,100,185,15,94,3,213,123,38,81,248,239,101) +IMAGE_DATA(177,222,63,239,125,126,114,167,100,248,239,37,106,253,171,223,51,140,242,44,239,110,230,98,254,161,46,34,142,100,238,230) +IMAGE_DATA(46,228,31,234,33,228,104,238,102,246,34,254,161,14,98,34,217,31,242,23,240,15,229,23,57,68,103,223,63,235,253,243) +IMAGE_DATA(231,254,101,189,197,254,111,89,132,254,101,157,139,248,223,104,62,227,254,101,125,237,223,254,255,102,17,249,151,118,46,224) +IMAGE_DATA(255,190,88,231,95,218,155,8,148,161,233,231,253,254,127,34,64,217,11,248,135,59,136,129,114,23,241,15,247,16,2,101) +IMAGE_DATA(46,228,31,238,34,2,202,91,204,63,220,71,0,148,181,160,127,184,83,50,112,206,61,79,51,38,171,87,18,148,140,197) +IMAGE_DATA(220,83,187,77,134,150,175,152,251,91,172,133,252,227,135,77,26,52,214,2,254,121,7,146,135,21,171,176,127,254,161,164) +IMAGE_DATA(97,199,42,232,63,149,36,207,166,131,253,107,177,127,45,246,175,197,254,181,216,191,22,251,215,98,255,90,236,95,139,253) +IMAGE_DATA(107,177,127,45,47,233,255,11,185,137,82,204,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(736, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,155,65,110,195,64,12,3,253,156,62,43,159,246,39,130,252,33,69,117,16,16,84,235,88,187,226,50,235,112) +IMAGE_DATA(0,222,10,147,29,93,130,198,253,185,109,183,77,76,231,217,136,152,131,252,115,145,127,46,242,207,69,254,185,200,63,23) +IMAGE_DATA(249,231,34,255,92,228,159,139,252,115,145,127,46,96,255,79,244,45,91,251,63,45,217,253,69,252,249,135,222,128,237,117) +IMAGE_DATA(17,255,176,27,176,189,46,228,31,114,3,182,215,197,252,151,223,128,237,117,65,255,165,55,96,123,93,212,127,217,13,194) +IMAGE_DATA(253,247,251,61,204,190,239,97,170,126,190,181,39,187,191,200,205,118,236,191,228,6,242,127,172,231,141,255,225,27,200,255) +IMAGE_DATA(177,158,19,254,135,110,32,255,199,122,78,250,239,190,129,252,31,235,73,248,239,186,193,151,249,207,250,236,201,184,255,150) +IMAGE_DATA(183,199,227,17,166,234,231,175,225,63,117,3,249,231,222,64,254,229,255,130,254,79,35,255,60,247,95,232,63,11,212,125) +IMAGE_DATA(115,255,117,63,127,166,245,32,221,111,193,110,249,127,125,60,210,189,21,68,145,127,127,60,210,189,21,68,145,127,127,60) +IMAGE_DATA(210,189,21,68,145,127,127,60,210,189,21,68,145,127,127,60,210,189,21,44,146,236,254,34,160,238,173,96,145,100,247,23) +IMAGE_DATA(1,117,111,5,139,36,187,191,8,168,123,43,88,36,217,253,69,64,221,91,193,34,201,238,47,2,234,222,10,22,73,118) +IMAGE_DATA(191,152,131,252,115,145,127,46,242,207,69,254,185,200,63,23,249,231,34,255,92,228,159,139,252,115,145,127,46,242,207,229) +IMAGE_DATA(195,252,195,255,94,215,44,46,74,85,47,9,248,223,171,195,210,226,84,116,147,128,127,95,243,175,16,148,209,126,18,240) +IMAGE_DATA(239,43,95,202,192,25,217,64,2,254,125,189,23,77,74,239,14,18,240,247,85,172,100,114,122,182,144,224,188,175,85,245) +IMAGE_DATA(94,122,235,249,217,61,69,191,107,7,156,247,21,229,223,231,188,241,143,121,95,87,254,125,206,9,255,245,239,171,203,191) +IMAGE_DATA(207,57,233,191,246,255,53,228,223,231,36,252,119,221,96,113,255,89,63,51,50,238,127,157,255,191,99,187,30,190,129,252) +IMAGE_DATA(115,111,32,255,242,127,65,255,167,145,127,158,251,11,248,71,3,117,111,5,81,214,249,252,137,6,234,222,10,162,200,191) +IMAGE_DATA(207,65,186,183,130,40,242,239,115,144,238,173,32,138,252,251,28,164,123,43,136,34,255,62,7,233,222,10,162,200,191,207) +IMAGE_DATA(65,186,247,146,201,233,217,66,2,238,222,139,38,165,119,7,137,41,238,189,12,156,145,13,36,166,185,247,66,80,70,251) +IMAGE_DATA(73,76,117,239,165,197,169,232,38,49,221,189,23,23,165,170,87,204,65,254,185,200,63,23,249,231,34,255,92,228,159,139) +IMAGE_DATA(252,115,145,127,46,242,207,69,254,185,200,63,23,249,231,18,250,255,5,55,15,164,57,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(640, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,150,193,13,194,48,16,4,93,14,93,145,166,211,68,148,30,2,2,241,65,14,144,96,123,111,237,25,233,126) +IMAGE_DATA(17,154,89,62,190,76,105,74,215,148,30,119,103,227,56,142,227,56,142,27,236,0,0,0,0,224,137,250,93,214,250,253) +IMAGE_DATA(214,171,143,195,254,35,56,69,221,127,52,175,72,157,35,187,169,27,241,211,245,217,58,46,203,146,189,121,158,179,87,234) +IMAGE_DATA(251,130,109,217,223,89,215,53,123,123,158,123,223,215,246,100,127,246,103,127,246,103,127,246,103,255,246,251,31,245,41,245) +IMAGE_DATA(189,75,151,139,103,175,93,46,158,189,118,185,120,246,218,229,226,217,107,151,139,103,175,93,181,61,121,127,126,254,95,216) +IMAGE_DATA(159,253,217,159,253,217,159,253,217,191,191,253,3,222,25,112,212,182,181,236,139,238,167,234,107,209,24,217,45,66,99,205) +IMAGE_DATA(206,168,94,209,58,107,180,70,116,138,188,127,201,94,0,0,0,0,0,0,24,154,109,123,158,43,206,254,47,119,215,6) +IMAGE_DATA(103,255,119,119,183,6,103,255,61,119,151,6,103,255,111,238,209,27,156,253,127,117,143,218,224,236,127,212,61,90,131,179) +IMAGE_DATA(255,89,247,40,13,206,254,255,186,171,27,156,253,75,185,171,26,156,253,75,187,183,110,112,246,175,229,222,170,193,217,191) +IMAGE_DATA(182,123,237,6,103,255,86,238,181,26,156,253,91,187,151,110,112,247,47,213,235,2,254,90,240,215,130,191,22,252,181,224) +IMAGE_DATA(175,5,127,45,248,107,193,95,11,254,90,240,215,130,191,22,252,181,224,175,5,127,45,248,107,193,95,11,254,90,240,215) +IMAGE_DATA(130,191,22,252,181,224,175,5,127,45,248,107,113,247,7,0,0,0,136,197,13,50,5,52,118,0,0,0,0,0,0,0) +IMAGE_END_DATA(384, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,156,81,106,35,49,16,68,231,56,57,150,47,61,151,24,230,14,14,19,72,32,32,141,167,37,181,186,170,85) +IMAGE_DATA(15,250,207,56,175,158,19,111,96,215,251,245,218,94,219,60,222,239,242,161,193,226,105,133,101,23,139,167,21,150,93,44) +IMAGE_DATA(158,86,88,118,177,120,90,97,217,197,226,105,133,101,23,139,167,21,150,93,44,158,86,88,118,177,120,90,97,217,197,226) +IMAGE_DATA(105,37,106,87,237,235,122,31,26,145,158,171,183,191,136,118,93,185,253,5,130,239,170,237,47,80,156,87,108,127,129,228) +IMAGE_DATA(157,161,253,172,247,83,175,173,104,62,145,27,162,182,162,249,180,192,218,190,215,31,9,214,246,173,254,136,176,182,183,250) +IMAGE_DATA(35,195,218,254,169,63,3,172,237,63,249,51,193,218,190,230,207,8,107,251,95,208,124,90,128,104,255,14,58,16,194,191) +IMAGE_DATA(239,23,239,127,17,250,158,163,254,63,132,189,223,171,255,31,33,127,214,170,255,63,166,255,94,177,90,127,52,255,226,243) +IMAGE_DATA(31,199,81,188,125,223,139,87,123,252,4,255,238,173,29,231,230,148,176,63,234,207,241,10,253,145,223,75,179,247,247,110) +IMAGE_DATA(223,187,39,115,255,89,237,123,54,101,237,95,252,186,231,121,22,175,182,171,246,248,129,187,138,207,99,245,169,61,126,160) +IMAGE_DATA(231,144,93,234,175,254,79,60,213,95,253,59,81,127,245,111,246,4,236,127,247,92,58,157,78,167,211,233,116,25,207,74) +IMAGE_DATA(241,121,244,251,103,179,231,144,93,234,175,254,79,60,213,95,253,59,81,127,245,111,246,76,208,191,186,205,241,134,57,38) +IMAGE_DATA(248,251,199,219,125,14,55,212,47,81,255,234,198,129,55,220,45,89,255,234,206,1,231,226,149,176,127,117,107,199,185,57) +IMAGE_DATA(37,237,191,221,248,68,180,175,250,36,238,255,1,253,251,243,56,244,249,139,56,244,249,163,56,244,249,187,56,244,249,211) +IMAGE_DATA(56,244,249,235,56,244,255,15,196,209,218,30,101,51,154,143,133,222,246,209,155,209,124,44,140,106,31,181,25,205,199,194) +IMAGE_DATA(232,246,179,55,163,249,88,240,106,63,107,51,154,143,5,239,246,222,155,209,124,44,204,106,239,181,25,205,103,166,123,244) +IMAGE_DATA(102,52,31,111,144,252,81,191,39,60,65,113,71,255,185,244,2,193,155,229,189,209,131,104,103,239,246,232,175,65,164,239) +IMAGE_DATA(172,246,200,175,65,148,235,236,246,168,175,129,60,99,97,217,197,226,105,133,101,23,139,167,21,150,93,44,158,86,88,118) +IMAGE_DATA(177,120,90,97,217,197,226,105,133,101,23,139,167,21,150,93,44,158,86,88,118,177,120,10,33,132,16,66,112,243,13,133) +IMAGE_DATA(108,82,204,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(608, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,214,193,141,195,48,12,68,81,151,147,178,220,180,155,48,220,131,3,222,37,3,9,68,13,71,254,15,208,205) +IMAGE_DATA(88,252,225,94,242,217,183,125,3,0,0,64,150,251,110,63,23,244,107,209,175,69,191,22,253,90,244,107,209,175,69,191) +IMAGE_DATA(22,253,90,244,107,209,175,69,191,22,253,90,244,107,209,175,69,191,22,253,90,244,107,209,175,69,191,22,253,90,244,107) +IMAGE_DATA(209,175,69,191,86,181,254,94,79,246,163,95,183,97,52,247,254,153,27,178,184,247,207,216,144,205,189,63,115,195,44,238) +IMAGE_DATA(253,25,27,102,115,239,31,185,65,197,189,127,196,6,53,247,254,224,220,30,220,251,131,115,123,112,239,15,206,237,193,189) +IMAGE_DATA(63,56,183,7,247,254,224,220,30,220,251,131,115,123,112,239,15,206,237,193,189,31,0,0,0,0,208,113,155,188,106,123) +IMAGE_DATA(171,245,56,220,255,13,77,85,239,255,182,174,74,59,223,220,166,222,72,159,110,159,109,227,121,158,205,119,28,71,243,141) +IMAGE_DATA(250,126,224,182,230,223,185,174,171,249,122,157,189,239,179,59,185,63,247,231,254,220,159,251,115,127,238,63,255,254,191,246) +IMAGE_DATA(140,250,222,101,151,75,231,170,187,92,58,87,221,229,210,185,234,46,151,206,85,119,185,116,174,186,43,187,147,223,159,207) +IMAGE_DATA(255,23,238,207,253,185,63,247,231,254,220,159,251,175,119,255,130,239,31,52,106,183,205,220,87,189,79,181,111,198,198,202) +IMAGE_DATA(109,21,54,102,238,172,218,85,109,103,198,214,138,77,149,239,63,114,47,0,0,0,158,169,127,63,242,120,60,30,143,199) +IMAGE_DATA(227,77,125,95,150,192,51,184,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(384, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,215,225,109,196,32,12,64,225,27,167,99,221,100,217,42,75,100,137,222,69,21,106,20,65,2,193,128,177,223) +IMAGE_DATA(147,252,143,70,206,71,213,187,254,188,95,239,23,17,17,17,17,17,17,17,17,17,17,17,17,145,209,126,153,46,131,63) +IMAGE_DATA(254,158,7,127,252,61,15,254,19,249,111,219,22,157,117,93,163,195,249,191,193,31,127,207,231,241,199,223,243,121,252,109) +IMAGE_DATA(248,63,221,243,251,163,42,28,106,206,31,223,161,244,249,35,253,247,189,173,248,135,247,152,197,63,236,108,201,127,159,25) +IMAGE_DATA(252,143,251,90,243,79,221,129,22,255,243,174,22,253,99,119,160,193,63,182,167,85,255,243,29,180,246,191,219,51,181,99) +IMAGE_DATA(238,158,26,156,75,127,175,114,190,23,245,240,191,218,207,186,127,184,131,81,254,119,187,121,240,143,125,30,244,240,207,217) +IMAGE_DATA(203,139,127,234,14,90,249,231,238,228,201,63,118,7,45,252,75,246,241,230,127,126,95,41,255,176,87,233,46,94,231,223) +IMAGE_DATA(75,206,127,244,59,205,54,146,254,163,223,101,222,193,223,130,63,127,127,202,71,250,239,63,119,80,102,47,233,207,247,207) +IMAGE_DATA(103,239,219,194,159,255,191,242,222,181,165,127,201,94,218,60,91,249,199,141,218,249,231,238,166,205,179,133,127,218,167,173) +IMAGE_DATA(127,206,103,178,54,79,105,255,171,231,247,240,191,187,3,109,158,146,254,119,207,151,242,175,217,115,22,231,212,249,154,223) +IMAGE_DATA(171,158,254,169,59,208,230,41,225,159,251,252,222,254,177,59,208,230,89,235,95,242,252,17,254,231,59,208,230,89,227,95) +IMAGE_DATA(250,252,81,254,199,189,181,121,62,245,95,150,101,42,255,176,187,54,207,39,254,187,253,72,127,13,14,51,158,199,31,127) +IMAGE_DATA(207,231,241,199,223,243,121,252,109,248,51,226,131,63,254,158,7,127,252,61,15,254,58,253,137,136,136,136,136,136,136,136) +IMAGE_DATA(136,136,136,136,136,136,136,136,136,104,210,62,40,243,160,203,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(448, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,216,225,109,131,48,16,64,225,140,211,177,50,25,91,177,4,75,180,85,163,68,180,53,196,248,108,158,140,223) +IMAGE_DATA(147,238,95,132,162,207,17,92,248,184,223,238,183,6,125,94,116,122,137,118,210,255,154,211,75,180,147,254,215,156,94,162) +IMAGE_DATA(157,244,79,204,178,44,201,153,231,57,57,239,62,255,125,201,159,201,253,124,238,245,183,190,63,100,89,82,115,255,167,253) +IMAGE_DATA(250,12,244,127,213,212,255,175,253,115,244,127,213,204,127,203,126,239,12,244,175,227,255,206,126,235,12,244,143,251,231,218) +IMAGE_DATA(167,206,64,255,199,68,247,156,163,83,186,23,109,125,127,200,178,164,106,254,165,246,235,51,208,191,204,63,106,191,245,60) +IMAGE_DATA(208,63,190,231,212,56,3,253,99,123,78,244,12,244,143,239,57,145,51,24,205,191,213,158,115,116,70,221,63,91,238,57) +IMAGE_DATA(37,103,160,255,57,247,156,156,123,209,200,254,181,246,210,122,215,215,95,255,80,250,179,37,191,127,233,251,159,255,251,225) +IMAGE_DATA(254,94,19,191,190,254,250,135,210,159,77,127,54,253,217,244,103,115,255,100,211,159,77,127,54,253,217,244,103,211,159,205) +IMAGE_DATA(253,147,77,127,54,253,217,244,103,211,159,77,127,54,247,79,54,253,217,244,103,211,159,77,127,54,253,217,220,63,217,244) +IMAGE_DATA(103,211,159,77,127,54,253,217,244,103,115,255,100,211,159,77,127,54,253,217,244,103,211,159,205,253,147,77,127,54,253,217) +IMAGE_DATA(244,103,211,159,77,127,54,247,79,54,253,217,244,103,59,228,191,229,217,122,244,127,204,52,77,167,219,251,251,255,237,127) +IMAGE_DATA(230,25,140,122,255,201,185,15,159,121,207,25,109,255,204,125,14,158,97,175,255,254,30,210,218,94,255,242,61,179,134,189) +IMAGE_DATA(254,121,239,7,162,246,190,127,136,249,71,206,192,247,63,245,254,255,70,238,57,254,255,173,243,254,161,244,126,175,127,29) +IMAGE_DATA(255,156,51,136,94,95,127,223,191,85,168,169,127,234,153,92,242,156,213,191,220,127,125,6,165,123,206,104,254,23,152,94) +IMAGE_DATA(162,157,244,191,230,244,18,237,164,255,53,167,151,104,167,209,253,205,204,204,204,186,232,11,192,238,160,203,0,0,0,0) +IMAGE_END_DATA(480, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,154,81,110,227,48,12,68,115,156,61,86,239,28,228,18,65,238,208,221,108,97,32,117,197,72,116,69,141,68) +IMAGE_DATA(191,1,230,47,160,134,143,77,65,43,254,243,113,249,184,32,132,16,66,8,161,31,250,196,93,237,149,58,111,54,123,165) +IMAGE_DATA(206,155,205,94,169,243,102,179,87,234,188,217,236,149,58,111,54,123,85,172,115,191,223,139,190,221,110,69,71,126,254,95) +IMAGE_DATA(156,255,158,37,207,87,166,115,240,223,216,91,51,128,127,92,191,123,246,165,25,192,63,166,95,139,253,126,6,240,239,223) +IMAGE_DATA(111,141,253,235,12,224,223,183,223,86,246,155,179,242,183,206,125,60,30,69,95,175,215,162,173,207,151,123,242,177,223,220) +IMAGE_DATA(90,191,103,254,108,252,143,178,183,102,0,255,118,254,191,101,95,154,1,252,219,248,247,98,191,159,1,252,235,252,123,179) +IMAGE_DATA(127,157,1,252,107,249,99,216,111,94,157,127,228,254,22,205,126,243,202,251,103,20,255,81,236,173,25,156,153,255,104,246) +IMAGE_DATA(165,25,156,153,127,175,121,169,242,192,31,254,240,31,195,223,58,183,182,191,61,249,28,189,255,217,215,183,248,247,172,63) +IMAGE_DATA(235,254,121,132,127,4,159,104,254,219,12,86,231,31,201,39,154,255,190,230,106,252,71,240,25,81,127,69,254,35,249,140) +IMAGE_DATA(168,191,18,127,5,159,89,234,71,243,175,237,99,86,246,75,199,253,80,85,255,245,12,171,190,146,255,187,220,89,248,111) +IMAGE_DATA(231,204,198,191,150,57,19,255,167,103,226,223,146,55,27,127,107,6,163,249,183,102,205,200,191,52,131,145,252,61,57,179) +IMAGE_DATA(242,223,207,32,154,255,209,140,217,61,114,255,87,247,58,171,71,240,87,247,56,191,225,159,153,63,255,127,108,143,188,255) +IMAGE_DATA(81,247,58,155,21,247,63,222,140,236,159,125,249,243,252,165,125,254,226,254,65,127,255,224,153,65,38,254,86,125,21,255) +IMAGE_DATA(150,220,89,248,191,171,175,228,95,203,158,129,127,173,126,52,127,235,220,85,126,31,140,174,63,3,127,126,127,215,243,175) +IMAGE_DATA(189,199,177,18,255,21,223,63,41,245,178,34,255,149,223,191,122,154,247,15,245,252,121,255,118,220,254,121,100,223,243,126) +IMAGE_DATA(222,226,175,202,243,61,27,252,225,15,255,149,248,91,60,163,13,127,221,12,248,251,47,101,215,176,95,137,191,117,110,109) +IMAGE_DATA(255,108,223,223,98,217,199,231,95,155,127,228,247,160,117,255,63,59,255,136,25,120,158,191,224,223,119,6,222,231,95,248) +IMAGE_DATA(247,155,65,173,62,252,235,124,122,177,207,192,95,245,252,235,101,31,157,71,181,127,170,248,123,190,7,220,63,196,245,219) +IMAGE_DATA(194,30,254,177,253,214,216,195,63,190,223,119,236,225,63,166,95,139,125,102,254,248,176,189,82,231,205,102,175,212,121,179) +IMAGE_DATA(217,43,117,222,108,246,74,157,55,155,189,82,231,205,102,132,16,66,8,33,132,16,66,8,33,116,66,253,5,41,152,87) +IMAGE_DATA(72,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(672, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,213,107,10,131,48,16,69,225,44,167,75,113,159,238,175,91,72,81,136,173,143,201,53,106,117,52,231,64,241) +IMAGE_DATA(95,185,243,33,248,106,66,19,136,136,136,136,136,200,44,94,61,192,113,216,216,197,128,143,21,54,118,113,242,164,111,177) +IMAGE_DATA(125,183,188,59,203,245,54,248,44,134,141,221,96,131,207,44,108,242,225,99,135,141,221,200,6,159,81,216,216,205,108,240) +IMAGE_DATA(25,194,198,110,209,6,159,62,108,236,76,27,124,176,201,148,181,169,220,7,27,59,105,83,177,15,54,118,171,108,42,245) +IMAGE_DATA(193,198,110,181,205,9,62,222,252,61,217,12,155,38,191,43,243,232,51,218,21,174,115,242,106,179,184,47,156,251,78,121) +IMAGE_DATA(183,201,238,12,255,181,42,178,113,240,205,90,179,237,168,125,119,179,73,173,221,185,103,111,177,141,35,159,174,210,205,37) +IMAGE_DATA(219,239,110,147,218,122,67,238,142,77,54,78,125,186,246,220,50,189,233,105,54,169,205,119,253,90,29,240,31,158,219,117) +IMAGE_DATA(223,195,109,82,248,232,176,209,225,163,195,70,135,143,14,27,29,62,58,108,116,248,232,176,209,225,163,195,70,135,143,14) +IMAGE_DATA(27,29,62,58,108,116,248,232,176,209,225,163,195,70,135,15,81,69,125,0,184,23,211,173,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(288, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,212,193,109,195,48,16,69,65,151,147,178,220,127,19,201,49,128,225,40,20,181,228,167,197,25,96,175,162,248) +IMAGE_DATA(214,214,215,243,241,124,0,0,0,0,0,192,7,251,190,201,124,146,116,171,29,119,145,110,178,243,46,210,13,210,147,146) +IMAGE_DATA(190,247,106,51,83,250,174,171,206,104,43,190,211,104,171,220,57,125,254,10,82,13,118,239,254,106,118,15,221,223,155,209) +IMAGE_DATA(69,251,99,35,251,104,223,102,84,39,237,219,85,183,210,254,188,170,102,218,247,171,104,167,127,191,145,253,105,115,165,159) +IMAGE_DATA(223,254,117,87,26,106,95,67,255,172,158,142,190,61,117,122,90,106,95,75,255,44,253,179,244,207,210,63,75,255,44,253) +IMAGE_DATA(179,244,207,210,63,75,255,44,253,179,244,207,210,63,75,255,44,253,179,244,207,210,63,75,255,44,253,179,244,207,210,63) +IMAGE_DATA(75,255,44,253,179,244,207,170,234,111,7,231,245,182,212,191,70,111,71,253,107,84,247,183,131,118,87,27,234,127,205,213) +IMAGE_DATA(126,254,3,253,42,218,233,223,175,170,157,29,156,87,221,204,14,218,141,104,117,244,76,59,248,53,178,147,29,28,155,209) +IMAGE_DATA(199,14,222,155,213,229,191,115,118,219,67,162,71,235,153,119,222,67,186,193,153,243,239,178,139,21,239,220,243,78,59,204) +IMAGE_DATA(76,233,187,174,54,41,233,123,167,103,5,233,6,59,183,127,149,110,178,99,243,191,164,91,237,216,28,0,0,0,0,0) +IMAGE_DATA(30,63,12,97,215,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(352, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,216,221,113,195,32,16,69,97,151,147,178,92,138,75,75,103,202,248,201,26,69,32,1,187,123,23,124,190,153) +IMAGE_DATA(188,225,88,58,250,1,243,243,124,60,31,0,0,0,0,0,0,0,0,204,234,245,122,109,251,191,109,251,61,253,59,142) +IMAGE_DATA(203,54,94,221,177,197,12,61,71,198,171,251,158,201,212,39,114,188,186,251,91,230,62,17,227,85,221,103,233,19,53,62) +IMAGE_DATA(186,189,250,124,51,142,247,238,222,115,156,222,199,228,45,203,188,208,114,159,120,124,127,6,170,121,225,238,115,106,249,157) +IMAGE_DATA(153,221,125,47,89,125,159,250,189,151,85,68,255,76,243,126,70,158,125,162,158,175,217,121,189,31,106,243,172,229,241,175) +IMAGE_DATA(160,54,47,247,252,63,230,217,118,86,235,240,218,58,199,235,216,87,97,241,187,128,254,253,60,251,123,30,247,74,70,250) +IMAGE_DATA(179,206,31,55,242,187,184,52,143,71,28,247,74,122,215,141,244,183,209,211,191,182,191,20,117,220,171,232,217,159,252,182) +IMAGE_DATA(253,76,111,244,215,162,191,86,107,79,246,217,108,181,246,164,191,45,250,107,209,95,139,254,90,244,215,106,237,201,250,211) +IMAGE_DATA(22,235,127,45,250,107,209,95,139,254,90,244,215,98,255,71,139,245,191,22,253,181,232,175,69,127,45,250,107,177,255,163) +IMAGE_DATA(197,250,95,139,254,90,86,253,153,3,218,189,155,245,220,207,244,183,81,234,127,245,57,250,219,232,237,127,182,94,98,30) +IMAGE_DATA(104,179,191,111,123,214,242,244,31,83,234,127,247,243,165,254,92,131,107,199,247,54,253,99,89,244,127,43,245,231,26,148) +IMAGE_DATA(157,173,91,70,246,112,74,253,185,6,255,149,214,141,35,107,199,218,60,206,154,244,163,212,199,226,94,173,245,231,57,136) +IMAGE_DATA(233,227,121,125,103,22,245,126,184,234,255,109,215,161,54,207,122,189,159,239,244,95,253,58,212,246,39,35,230,198,187,253) +IMAGE_DATA(87,154,163,91,207,55,226,156,175,158,187,150,251,100,165,241,222,221,143,215,64,125,190,153,198,71,182,223,155,165,143,215) +IMAGE_DATA(120,85,247,189,204,125,60,199,171,187,159,201,212,199,99,188,186,111,139,25,122,222,25,175,238,8,0,0,0,0,0,0) +IMAGE_DATA(0,64,171,63,67,49,87,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(512, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,150,237,177,131,48,12,4,83,206,43,43,165,211,73,94,1,137,29,7,125,156,108,237,206,220,31,6,49,104) +IMAGE_DATA(15,6,254,158,143,231,3,0,0,0,0,0,0,0,0,224,38,175,195,83,17,181,147,142,93,168,119,175,150,76,42,222) +IMAGE_DATA(83,36,85,246,173,112,15,106,84,14,58,59,31,145,225,164,251,243,254,141,72,63,120,95,199,219,21,238,127,199,211,89) +IMAGE_DATA(70,143,59,196,107,103,245,252,9,177,58,136,156,27,205,158,24,139,143,172,153,183,92,215,181,69,86,247,9,112,233,238) +IMAGE_DATA(94,237,50,161,11,175,14,92,221,171,189,37,247,224,209,129,199,187,34,247,36,236,193,219,63,238,99,59,192,125,157,14) +IMAGE_DATA(76,254,213,46,138,117,16,233,31,247,182,14,62,157,119,187,63,245,238,85,98,113,104,232,78,190,119,149,88,61,222,153) +IMAGE_DATA(83,239,92,45,78,254,103,224,223,199,255,172,3,220,231,116,128,127,252,31,151,12,255,234,29,171,7,255,248,239,28,252) +IMAGE_DATA(227,191,115,240,143,255,206,193,63,254,59,7,255,248,239,28,252,227,191,115,240,143,255,206,193,63,254,59,7,255,103,251) +IMAGE_DATA(167,131,101,247,248,199,127,171,4,250,167,3,63,247,51,255,188,3,241,254,103,238,127,154,83,239,92,37,86,143,139,115) +IMAGE_DATA(111,179,234,189,171,196,226,112,114,108,169,59,245,238,234,252,248,12,143,206,51,125,59,212,14,54,113,31,230,191,99,7) +IMAGE_DATA(35,15,55,253,211,129,214,253,200,41,29,196,184,247,240,63,236,224,196,30,102,187,222,244,100,57,111,169,131,19,122,248) +IMAGE_DATA(182,159,163,251,176,14,118,235,98,117,159,0,247,119,103,102,179,39,198,226,35,114,110,54,127,66,172,14,50,231,103,215) +IMAGE_DATA(217,41,94,59,123,92,195,114,79,29,200,232,145,14,62,19,229,42,226,253,60,137,44,63,116,240,78,182,147,168,239,213) +IMAGE_DATA(78,84,112,16,249,239,80,145,138,251,102,254,3,238,16,37,234,221,59,58,31,161,118,210,209,57,0,0,0,0,0,0) +IMAGE_DATA(0,0,20,229,31,234,246,24,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(480, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,209,193,113,196,48,16,3,193,11,199,97,93,254,73,216,9,248,3,138,210,112,161,233,170,249,99,201,159,239) +IMAGE_DATA(231,251,145,36,73,146,36,73,146,36,73,146,36,73,199,251,45,237,100,244,219,188,245,47,232,119,160,163,208,119,159,214) +IMAGE_DATA(147,232,91,79,237,9,244,141,167,119,39,250,182,41,221,129,190,105,90,59,209,183,76,109,23,250,142,169,237,64,223,48) +IMAGE_DATA(189,171,232,253,211,187,130,222,222,210,42,122,119,75,171,232,221,45,173,160,55,183,149,162,247,182,149,162,247,182,149,162) +IMAGE_DATA(247,182,149,162,247,182,149,162,247,182,149,162,247,182,149,162,247,182,149,162,247,182,149,162,247,182,149,162,247,182,149,162) +IMAGE_DATA(247,182,149,162,247,182,149,162,247,182,149,162,247,182,149,162,247,182,149,162,247,182,149,162,247,182,149,162,247,182,149,162) +IMAGE_DATA(247,182,149,162,247,182,149,162,247,182,149,162,247,182,149,162,247,182,181,130,222,220,210,42,122,119,75,171,232,221,45,93) +IMAGE_DATA(65,111,159,222,85,244,254,233,237,64,223,48,181,93,232,59,166,182,19,125,203,180,238,64,223,52,165,59,209,183,157,222) +IMAGE_DATA(19,232,27,79,237,73,244,173,167,69,161,239,166,59,5,253,14,111,125,247,255,208,111,243,198,55,151,36,73,146,36,73) +IMAGE_DATA(146,36,73,146,36,233,181,254,0,50,87,105,97,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(320, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,209,65,78,132,80,20,68,81,150,227,178,122,169,238,12,99,76,15,58,33,38,162,15,170,252,231,36,140,168) +IMAGE_DATA(1,239,242,246,216,30,27,0,0,0,0,0,0,0,144,109,223,223,247,163,231,243,213,209,83,180,79,150,208,231,202,125) +IMAGE_DATA(138,212,62,87,237,111,81,212,231,146,253,108,237,87,9,247,38,238,103,171,127,73,186,55,113,63,91,191,167,195,205,251) +IMAGE_DATA(241,246,97,247,38,238,71,219,7,222,27,183,215,191,191,127,211,189,137,123,253,171,251,199,222,85,182,215,95,255,149,247) +IMAGE_DATA(167,219,135,124,255,127,216,235,175,255,202,251,159,197,239,185,171,98,175,191,254,43,239,245,215,127,229,189,254,93,253,91) +IMAGE_DATA(238,42,218,235,175,255,202,123,253,245,95,121,175,127,81,255,162,187,42,246,250,235,191,242,94,127,253,87,222,235,223,213) +IMAGE_DATA(191,229,174,162,189,254,250,175,188,63,35,233,251,155,247,103,165,124,127,251,94,255,206,254,91,248,93,241,251,223,180,215) +IMAGE_DATA(255,254,254,207,223,208,114,111,210,254,143,218,235,127,127,255,195,127,144,118,111,216,126,66,242,189,73,251,49,101,29,46) +IMAGE_DATA(223,79,182,127,74,186,55,105,63,91,253,85,194,189,73,251,217,218,223,170,232,51,184,79,145,218,103,106,31,43,164,207) +IMAGE_DATA(196,30,0,0,0,0,0,0,0,8,244,1,121,209,189,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(320, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,215,65,142,194,64,12,69,65,142,195,177,184,255,37,134,197,172,102,193,36,157,182,243,59,164,74,242,150,200) +IMAGE_DATA(207,128,148,231,235,241,122,0,0,0,0,0,192,197,252,124,249,172,40,221,228,142,183,72,239,190,218,156,41,189,235,170) +IMAGE_DATA(211,45,189,223,85,166,67,122,167,171,77,149,85,238,191,130,179,91,104,254,89,119,27,221,247,233,234,164,251,152,202,94) +IMAGE_DATA(218,31,83,209,77,251,57,179,253,180,159,119,180,161,246,117,70,91,106,95,111,164,169,254,245,42,250,51,103,79,87,223) +IMAGE_DATA(253,62,123,218,106,223,75,255,172,255,250,250,239,233,183,245,78,166,125,63,253,179,244,207,210,63,75,255,44,253,179,244) +IMAGE_DATA(207,210,63,75,255,44,253,179,244,207,210,63,75,255,44,253,179,244,207,210,63,75,255,44,253,179,244,207,210,63,75,255) +IMAGE_DATA(44,253,179,244,207,210,63,107,180,191,27,212,217,106,172,127,175,173,190,250,247,58,218,223,13,230,237,109,171,127,143,189) +IMAGE_DATA(93,253,6,234,141,52,213,191,222,104,83,55,168,115,180,165,27,204,155,105,232,157,108,78,69,63,55,56,166,178,155,27) +IMAGE_DATA(140,169,238,181,245,121,238,240,171,179,211,222,207,190,227,29,206,106,51,242,156,111,191,69,178,197,145,103,223,121,58,164) +IMAGE_DATA(119,186,202,116,75,239,183,234,156,41,189,235,106,147,148,222,253,142,205,63,73,55,185,99,115,0,0,0,0,0,248,227) +IMAGE_DATA(13,179,61,31,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(352, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,211,75,118,195,48,12,67,209,44,167,203,202,82,178,243,116,238,196,174,84,139,2,65,62,156,131,169,63,23) +IMAGE_DATA(210,207,243,241,124,16,66,8,33,132,16,105,222,131,37,107,50,234,205,30,235,178,202,156,45,230,242,167,221,123,176,35) +IMAGE_DATA(207,218,254,119,121,115,219,251,230,30,157,19,234,62,177,67,199,108,115,31,220,161,75,100,238,236,144,199,190,225,6,233) +IMAGE_DATA(236,155,109,144,210,254,98,131,74,73,109,95,124,3,11,251,162,27,88,217,23,220,192,206,254,100,3,199,88,158,253,66) +IMAGE_DATA(119,192,214,190,192,29,176,62,251,198,119,224,227,155,213,134,1,27,236,44,254,198,254,106,187,2,27,224,127,52,121,189) +IMAGE_DATA(98,139,63,254,201,122,252,47,7,127,181,153,237,29,192,31,255,132,197,31,127,252,241,199,31,127,252,241,199,63,183,127) +IMAGE_DATA(165,13,142,255,133,127,209,179,143,63,254,9,235,234,95,97,131,143,127,194,191,238,217,15,240,119,222,96,251,217,199,95) +IMAGE_DATA(123,246,131,252,29,55,144,156,253,149,254,135,103,169,61,45,206,126,160,191,211,6,178,179,191,218,223,112,3,169,125,132) +IMAGE_DATA(191,209,6,114,251,40,127,131,13,82,216,111,244,207,180,193,183,111,43,231,159,116,131,84,246,209,254,201,54,72,103,191) +IMAGE_DATA(195,63,193,14,41,221,119,251,159,108,16,185,195,217,251,228,230,42,255,139,13,86,238,112,245,14,185,183,218,127,96,135) +IMAGE_DATA(217,61,70,158,37,119,206,230,63,177,195,173,170,125,179,251,71,108,161,54,117,245,255,239,30,106,195,170,254,29,138,63) +IMAGE_DATA(254,157,139,63,254,157,139,63,254,157,139,63,254,157,139,63,254,157,139,63,254,157,139,63,254,157,139,63,254,157,139,63) +IMAGE_DATA(254,157,139,63,254,157,187,202,159,174,232,108,212,223,91,173,179,81,127,111,181,18,66,8,33,132,16,66,8,217,156,95) +IMAGE_DATA(148,216,52,215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(448, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,211,187,17,2,49,16,68,65,194,33,44,66,33,115,48,113,248,72,32,78,210,78,79,213,51,161,142,94,238) +IMAGE_DATA(124,57,93,78,102,102,102,102,54,117,183,198,108,204,90,189,221,99,220,70,153,187,69,223,62,218,221,26,107,249,174,195) +IMAGE_DATA(127,221,186,251,217,251,199,123,36,239,175,238,29,119,72,220,97,238,141,119,72,217,52,119,119,88,199,62,240,6,203,217) +IMAGE_DATA(135,221,96,73,251,55,55,168,180,165,237,139,223,96,11,251,162,55,216,202,190,224,13,182,179,127,113,131,29,183,229,127) +IMAGE_DATA(191,208,59,176,173,125,129,119,96,235,255,254,198,239,192,179,103,214,247,245,110,246,243,86,171,119,179,159,183,90,189,123) +IMAGE_DATA(124,246,122,213,55,241,231,159,28,127,254,201,241,231,159,28,127,254,201,241,231,159,28,127,254,201,241,231,159,28,127,254) +IMAGE_DATA(201,241,231,159,28,127,254,201,241,231,159,28,127,254,201,241,231,159,28,127,254,201,241,231,159,28,127,254,201,241,231,159) +IMAGE_DATA(28,127,254,201,241,231,159,28,127,254,201,241,231,159,28,127,254,201,241,231,159,28,127,254,201,241,231,159,28,127,254,201) +IMAGE_DATA(241,231,159,28,127,254,201,141,242,215,136,122,55,251,121,171,213,187,217,207,91,45,51,51,51,51,51,51,59,120,119,144) +IMAGE_DATA(206,175,247,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(320, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,214,97,78,194,64,20,0,97,142,227,177,60,202,220,92,35,17,131,10,42,118,219,89,202,124,201,254,108,247) +IMAGE_DATA(117,94,72,120,122,62,60,31,242,25,135,195,203,219,177,231,120,84,188,247,167,61,40,248,210,159,118,177,41,126,232,79) +IMAGE_DATA(187,88,29,127,236,79,123,88,5,55,246,167,93,12,197,130,254,180,135,197,24,208,159,118,241,111,12,238,207,192,93,172) +IMAGE_DATA(57,219,35,157,91,187,159,216,115,239,237,220,86,191,254,86,247,147,17,239,152,29,19,118,191,52,219,210,119,205,138,201) +IMAGE_DATA(154,95,155,109,228,123,103,194,100,205,175,205,182,214,29,54,38,236,126,105,182,181,239,178,48,89,243,107,179,109,121,239) +IMAGE_DATA(150,152,176,251,165,217,140,251,183,192,100,205,207,49,209,44,107,97,178,230,231,152,116,174,145,152,248,251,120,128,254,51) +IMAGE_DATA(163,254,42,234,175,162,254,42,234,175,162,254,42,234,175,162,254,42,234,175,162,254,42,234,175,162,254,42,234,175,162,254) +IMAGE_DATA(42,234,175,162,254,42,234,175,162,254,42,234,175,162,254,42,234,175,162,254,42,234,175,162,254,42,234,175,162,254,42,234) +IMAGE_DATA(175,162,254,42,234,175,162,254,42,234,175,162,254,42,234,175,162,254,42,234,175,162,254,42,234,175,162,254,42,234,175,162) +IMAGE_DATA(254,42,234,175,162,254,171,225,172,237,168,179,233,7,124,224,229,251,217,226,217,101,216,69,255,75,253,254,218,113,201,179) +IMAGE_DATA(99,176,219,246,191,117,92,242,236,192,47,168,255,46,126,3,91,205,250,89,253,169,255,242,175,168,191,218,255,56,205,221) +IMAGE_DATA(181,63,185,239,255,63,31,147,220,109,255,55,75,250,249,237,143,83,220,117,255,125,160,246,42,234,175,163,246,42,234,175) +IMAGE_DATA(162,254,58,106,175,162,254,58,106,175,162,254,42,234,175,163,246,42,234,175,162,254,58,106,175,162,254,58,106,175,162,254) +IMAGE_DATA(73,146,36,25,224,21,2,152,45,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(448, 1) diff --git a/uppsrc/RichEdit/Diagram.lay b/uppsrc/RichEdit/Diagram.lay new file mode 100644 index 000000000..00515fe14 --- /dev/null +++ b/uppsrc/RichEdit/Diagram.lay @@ -0,0 +1,9 @@ +LAYOUT(SizeLayout, 212, 148) + ITEM(Upp::Switch, size, SetLabel(t_("1250x1000 (4:3)\n1600x900 (16:9)\n1600x800 (2:1)\n1000x1250 (3:4)\nCustom")).LeftPosZ(8, 192).TopPosZ(8, 88)) + ITEM(Upp::Label, dv___1, SetLabel(t_("x")).LeftPosZ(92, 40).TopPosZ(88, 19)) + ITEM(Upp::WithDropChoice, cx, NotNull(true).LeftPosZ(24, 64).TopPosZ(88, 19)) + ITEM(Upp::WithDropChoice, cy, NotNull(true).LeftPosZ(100, 64).TopPosZ(88, 19)) + ITEM(Upp::Button, ok, SetLabel(t_("OK")).LeftPosZ(68, 64).TopPosZ(116, 24)) + ITEM(Upp::Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(138, 64).TopPosZ(116, 24)) +END_LAYOUT + diff --git a/uppsrc/RichEdit/DiagramClip.cpp b/uppsrc/RichEdit/DiagramClip.cpp new file mode 100644 index 000000000..d7dd63e87 --- /dev/null +++ b/uppsrc/RichEdit/DiagramClip.cpp @@ -0,0 +1,89 @@ +#include "RichEdit.h" + +namespace Upp { + +void DiagramEditor::Delete() +{ + FinishText(); + if(!IsCursor()) + return; + Vector h = clone(sel.GetKeys()); + Sort(h); + data.item.Remove(h); + CancelSelection(); + Commit(); +} + +void DiagramEditor::Copy() +{ + StringBuffer cb; + for(int i : sel) + data.item[i].Save(cb); + WriteClipboardText(cb); +} + +void DiagramEditor::Cut() +{ + Copy(); + Delete(); +} + +void DiagramEditor::Paste() +{ + String txt = ReadClipboardText(); + try { + CParser p(txt); + while(!p.IsEof()) { + DiagramItem m; + m.Load(p); + int ii = data.item.GetCount(); + data.item << m; + SetCursor(ii); + } + } + catch(CParser::Error) {} + Commit(); +} + +void DiagramEditor::Duplicate() +{ + if(!IsCursor()) + return; + + Rect r = CursorItem().GetRect(); + for(int i : sel) + r.Union(data.item[i].GetRect()); + + Size sz = r.GetSize(); + Point offset = sz.cx > sz.cy ? Point(0, sz.cy + 16) : Point(sz.cx + 16, 0); + + int p = data.item.GetCount(); + int q = p; + data.item.SetCount(data.item.GetCount() + sel.GetCount()); + for(int i : sel) { + DiagramItem& m = data.item[q++]; + m = data.item[i]; + m.p1 += offset; + m.p2 += offset; + } + sel.Clear(); + for(int i = p; i < data.item.GetCount(); i++) { + sel << i; + cursor = i; + } + + Commit(); + Sync(); +} + +void DiagramEditor::SelectAll() +{ + sel.Clear(); + for(int i = 0; i < data.item.GetCount(); i++) { + sel.Add(i); + cursor = i; + } + Sync(); +} + +} diff --git a/uppsrc/RichEdit/DiagramCursor.cpp b/uppsrc/RichEdit/DiagramCursor.cpp new file mode 100644 index 000000000..3d8e35060 --- /dev/null +++ b/uppsrc/RichEdit/DiagramCursor.cpp @@ -0,0 +1,25 @@ +#include "RichEdit.h" + +namespace Upp { + +void DiagramEditor::SetCursor(int i) +{ + cursor = i; + if(i < 0) { + ink <<= Black(); + paper <<= Black(); + } + else + sel.FindAdd(i); + GetAttrs(); +} + +DiagramItem& DiagramEditor::CursorItem() +{ + static DiagramItem nil; + if(cursor >= 0 && cursor < data.item.GetCount()) + return data.item[cursor]; + return nil; +} + +} \ No newline at end of file diff --git a/uppsrc/RichEdit/DiagramEditor.cpp b/uppsrc/RichEdit/DiagramEditor.cpp new file mode 100644 index 000000000..83cd20c1c --- /dev/null +++ b/uppsrc/RichEdit/DiagramEditor.cpp @@ -0,0 +1,241 @@ +#include "RichEdit.h" + +namespace Upp { + +#define IMAGECLASS DiagramImg +#define IMAGEFILE +#include + +DiagramEditor::DiagramEditor() +{ + AddFrame(toolbar); + + Add(text_editor); + text_editor.NoRuler().ViewBorder(0); + text_editor.WhenRefreshBar = [=] { SetBar(); }; + text_editor.WhenEnter << [=] { FinishText(); }; + text_editor.WhenEsc << [=] { edit_text = false; Sync(); }; + text_editor.WhenAction << [=] { + SyncEditorRect(); + }; + + ink.ColorImage(DiagramImg::Ink()) + .NullImage(DiagramImg::InkNull()) + .StaticImage(DiagramImg::InkA()); + ink.NotNull(); + ink.Tip(t_("Line color")); + ink << [=] { SetAttrs(); }; + + paper.ColorImage(DiagramImg::Paper()) + .NullImage(DiagramImg::PaperNull()) + .StaticImage(DiagramImg::PaperA()); + paper.NotNull(); + paper.Tip(t_("Background color")); + paper << [=] { SetAttrs(); }; + + int cy = GetStdFontCy(); + + auto MakeImage = [=](DiagramItem& m) -> Image { + ImagePainter iw(DPI(24), cy); + iw.Scale(DPI(1)); + iw.Clear(); + m.Paint(iw); + return iw; + }; + + cy /= DPI(1); + + for(int i = 0; i < DiagramItem::SHAPE_COUNT; i++) { + DiagramItem m; + m.p1 = Point(2, 2); + m.p2 = Point(23, cy - 2); + m.width = DPI(1); + m.shape = i; + shape.Add(i, MakeImage(m)); + } + shape << [=] { SetAttrs(); }; + + struct Dialine : DiagramItem { + Dialine() { + shape = SHAPE_LINE; + p1.y = p2.y = 7; + p1.x = -9999; + p2.x = 9999; + } + }; + + auto LDL = [=](DropList& dl, bool left) { + for(int i = DiagramItem::CAP_NONE; i < DiagramItem::CAP_COUNT; i++) { + Dialine m; + m.line_end = m.line_start = i; + + if(left) + m.p1.x = 8; + else + m.p2.x = 16; + + dl.Add(i, MakeImage(m)); + } + dl << [=] { SetAttrs(); }; + }; + + LDL(line_start, true); + LDL(line_end, false); + + for(int i = 0; i < DiagramItem::DASH_COUNT; i++) { + Dialine m; + m.dash = i; + line_dash.Add(i, MakeImage(m)); + } + line_dash << [=] { SetAttrs(); }; + + for(int i = 0; i < 10; i++) + line_width.Add(i); + line_width << [=] { SetAttrs(); }; + + ResetUndo(); + Sync(); + + sb.AutoHide(); + sb.WithSizeGrip(); + AddFrame(sb); + sb.WhenScroll << [=] { Sync(); }; + + editor = true; +} + +void DiagramEditor::Paint(Draw& w) +{ + RTIMING("Paint"); + Size sz = GetSize(); + DrawPainter iw(w, GetSize()); + iw.Co(); + iw.Clear(SWhite()); + + iw.Scale(GetZoom()); + iw.Offset(-(Point)sb); + Size dsz = data.GetSize(); + iw.Move(dsz.cx, 0).Line(dsz.cx, dsz.cy).Line(0, dsz.cy).Stroke(0.2, SColorHighlight()); + + if(data.item.GetCount() == 0) + iw.DrawText(DPI(30), DPI(30), "Right-click to insert item(s)", ArialZ(30).Italic(), SLtGray()); + + data.Paint(iw, *this); + + if(HasCapture() && doselection) { + Rect r(dragstart, dragcurrent); + r.Normalize(); + iw.Rectangle(r).Fill(30 * SColorHighlight()).Stroke(1, LtRed()).Dash("4").Stroke(1, White()); + } +} + +void DiagramEditor::Sync() +{ + Refresh(); + SetBar(); + sb.SetTotal(data.GetSize()); + sb.SetPage(GetSize() / GetZoom()); + sb.SetLine(8, 8); + SyncEditor(); +} + +void DiagramEditor::Layout() +{ + Sync(); +} + +void DiagramEditor::ResetUndo() +{ + undoredo.Reset(GetCurrent()); +} + +void DiagramEditor::Commit() +{ + if(IsCursor()) { + DiagramItem& m = CursorItem(); + if(!m.IsLine()) + m.Normalize(); + } + if(undoredo.Commit(GetCurrent())) { + SetBar(); + Sync(); + } +} + +String DiagramEditor::GetCurrent() +{ + return StoreAsString(data); +} + +bool DiagramEditor::SetCurrent(const String& s) +{ + bool b = LoadFromString(data, s); + Sync(); + return b; +} + +void DiagramEditor::CancelSelection() +{ + FinishText(); + sel.Clear(); + KillCursor(); + Sync(); +} + +void DiagramEditor::Zoom() +{ + zoom_percent = (zoom_percent / 25 + 1) * 25; + if(zoom_percent > 400) + zoom_percent = 25; + Sync(); +} + +void DiagramEditor::MouseWheel(Point, int zdelta, dword keyflags) { + if(keyflags & K_CTRL) { + zoom_percent = clamp((zoom_percent / 25 + sgn(zdelta)) * 25, 25, 400); + Sync(); + return; + } + if(keyflags & K_SHIFT) + sb.WheelX(zdelta); + else + sb.WheelY(zdelta); +} + +void DiagramEditor::HorzMouseWheel(Point, int zdelta, dword) +{ + sb.WheelX(zdelta); +} + +String DiagramEditor::Save() const +{ + StringBuffer r; + data.Save(r); + return r; +} + +bool DiagramEditor::Load(const String& s) +{ + CParser p(s); + try { + data.Load(p); + } + catch(CParser::Error) { + Reset(); + return false; + } + Reset(); + return true; +} + +void DiagramEditor::Reset() +{ + doselection = false; + grid = true; + edit_text = false; + creating = false; + ResetUndo(); + Sync(); +} + +} \ No newline at end of file diff --git a/uppsrc/RichEdit/DiagramEditor.h b/uppsrc/RichEdit/DiagramEditor.h new file mode 100644 index 000000000..569c271a7 --- /dev/null +++ b/uppsrc/RichEdit/DiagramEditor.h @@ -0,0 +1,98 @@ +#define IMAGECLASS DiagramImg +#define IMAGEFILE +#include + +//#define LAYOUTFILE +//#include + +struct DiaRichEdit : RichEdit { + bool Key(dword key, int count) override; + + Event<> WhenEnter; + Event<> WhenEsc; +}; + +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; + void Layout() override; + +private: + Diagram data; + + Point draghandle = Point(0, 0); + Point dragstart = Point(0, 0); + Point dragcurrent = Point(0, 0); + Rect dragfrom = Rect(0, 0, 0, 0); + Vector sdragfrom; + bool doselection = false; // we are doing rect selection + bool grid = true; // snap to grid + bool edit_text = false; // text editor is visible + bool creating = false; // right-click adding new item (allow resize) + int zoom_percent = 100; + + BinUndoRedo undoredo; + + int tool = 0; + ToolBar toolbar; + DropList shape, line_start, line_end, line_width, line_dash; + DiaRichEdit text_editor; + + ColorButton ink, paper; + + ScrollBars sb; + + void CancelSelection(); + bool IsCursor() const { return cursor >= 0 && cursor < data.item.GetCount(); } + DiagramItem& CursorItem(); + const DiagramItem& CursorItem() const { return const_cast(this)->CursorItem(); } + Rect GetCursorRect() const { return IsCursor() ? data.item[cursor].GetRect() : Null; } + void SetCursor(int i); + void KillCursor() { SetCursor(-1); } + 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); + + void SetAttrs(); + void GetAttrs(); + + 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); + + DiagramEditor(); +}; diff --git a/uppsrc/RichEdit/DiagramMouse.cpp b/uppsrc/RichEdit/DiagramMouse.cpp new file mode 100644 index 000000000..f9f74ad2c --- /dev/null +++ b/uppsrc/RichEdit/DiagramMouse.cpp @@ -0,0 +1,234 @@ +#include "RichEdit.h" + +namespace Upp { + +void DiagramEditor::Map(Point& p) +{ + p = (Pointf)p / GetZoom() + (Pointf)(Point)sb; +} + +Point DiagramEditor::GetHandle(int i, Point p) const +{ // -1 top/left, 1 right/botom + Point h(0, 0); + if(i >= 0) { + const DiagramItem& m = data.item[i]; + if(m.IsLine()) { + if(Distance(m.p1, p) < 6) + return Point(-1, -1); + if(Distance(m.p2, p) < 6) + return Point(1, 1); + + } + else { + Rect r = m.GetRect(); + Rect rr = r.Inflated(5); + r.Deflate(min(10, r.GetWidth() / 2), min(10, r.GetHeight() / 2)); + if(rr.Contains(p)) { + if(p.y < r.top) + h.y = -1; + if(p.y > r.bottom) + h.y = 1; + if(p.x < r.left) + h.x = -1; + if(p.x > r.right) + h.x = 1; + } + } + } + return h; +} + +int DiagramEditor::FindItem(Point p) const +{ + int mini = -1; + double mina = INT_MAX; + for(int i = data.item.GetCount() - 1; i >= 0; i--) { + Rectf r = data.item[i].GetRect(); + if(data.item[i].IsClick(p) || data.item[i].IsTextClick(p)) { + double a = r.Width() * r.Height(); + if(a < mina) { + mina = a; + mini = i; + } + } + } + return mini; +} + +Image DiagramEditor::CursorImage(Point p, dword keyflags) +{ + Map(p); + + for(int i = 0; i < data.item.GetCount(); i++) + if(data.item[i].IsTextClick(p)) + return Image::IBeam(); + + int i = FindItem(p); + + Point h = HasCapture() ? draghandle : IsCursor() ? GetHandle(cursor, p) : Null; + + if(IsNull(h)) + return Image::Arrow(); + + if(HasCapture() && i >= 0 && data.item[i].IsLine()) + return Image::Arrow(); + + int m = h.x * h.y; + if((h.x || h.y) && i >= 0 && data.item[i].IsLine()) + return Image::SizeAll(); + if(m > 0) + return Image::SizeBottomRight(); + if(m < 0) + return Image::SizeBottomLeft(); + if(h.x) + return Image::SizeHorz(); + if(h.y) + return Image::SizeVert(); + + return Image::Arrow(); +} + +void DiagramEditor::LeftDouble(Point p, dword keyflags) +{ + if(IsCursor()) + StartText(); +} + +void DiagramEditor::LeftDown(Point p, dword keyflags) +{ + Map(p); + + FinishText(); + dragstart = dragcurrent = p; + + SetCapture(); + + if(IsCursor()) { + Point h = GetHandle(cursor, p); + if(h.x || h.y) { + draghandle = h; + Sync(); + return; + } + } + + if((keyflags & K_CTRL) == 0) { + sel.Clear(); + cursor = -1; + } + int i = FindItem(p); + if(i >= 0) { + SetCursor(i); + dragfrom = GetCursorRect(); + if(dragfrom.Contains(p)) { + sdragfrom.SetCount(sel.GetCount()); + for(int i = 0; i < sel.GetCount(); i++) + sdragfrom[i] = data.item[sel[i]]; + draghandle = Null; + } + } + else { + sel.Clear(); + doselection = true; + } + + Sync(); +} + +void DiagramEditor::MouseMove(Point p, dword keyflags) +{ + Map(p); + + if(HasCapture() && doselection) { + dragcurrent = p; + Rect r(dragstart, dragcurrent); + r.Normalize(); + sel.Clear(); + KillCursor(); + for(int i = 0; i < data.item.GetCount(); i++) + if(r.Contains(data.item[i].p1) && r.Contains(data.item[i].p2)) { + sel.FindAdd(i); + SetCursor(i); + } + Sync(); + return; + } + if(HasCapture() && IsCursor()) { + DiagramItem& m = CursorItem(); + if(grid) + p = p / 8 * 8; + if(IsNull(draghandle)) { + Point offset = p - dragstart; + Rect to = dragfrom.Offseted(offset); + m.p1 = to.TopLeft(); + m.p2 = to.BottomRight(); + for(int i = 0; i < sel.GetCount(); i++) { + int ii = sel[i]; + if(ii >= 0 && ii < data.item.GetCount() && i < sdragfrom.GetCount()) { + (Point2 &)data.item[ii] = sdragfrom[i].Offseted(offset); + } + } + } + else { + if(draghandle.x) + (draghandle.x < 0 ? m.p1.x : m.p2.x) = p.x; + if(draghandle.y) + (draghandle.y < 0 ? m.p1.y : m.p2.y) = p.y; + } + Sync(); + } +} + +void DiagramEditor::LeftUp(Point p, dword keyflags) +{ + Map(p); + + Sync(); + doselection = false; + Commit(); + if(Distance(dragstart, p) < 2 && CursorItem().IsTextClick(p)) { + StartText(); + return; + } +} + +void DiagramEditor::RightDown(Point p, dword keyflags) +{ + Map(p); + FinishText(); + DiagramItem s; + s.p1 = Point(0, 0); + s.p2 = Point(256, 64); + if(IsCursor()) + s = CursorItem(); + else + if(data.item.GetCount()) + s = data.item.Top(); + CancelSelection(); + DiagramItem& m = data.item.Add(); + m = s; + Pointf pf = p; + if(m.IsLine()) { + m.p1 = pf + Pointf(-50, 0); + m.p2 = m.p1 + Pointf(100, 0); + } + else { + Sizef sz = m.GetRect().GetSize(); + m.p1 = p - sz / 2; + if(grid) + m.p1 = 8 * (Point)m.p1 / 8; + m.p2 = m.p1 + s.GetRect().GetSize(); + } + m.qtf.Clear(); + dragstart = p; + creating = true; + SetCursor(data.item.GetCount() - 1); + Sync(); +} + +void DiagramEditor::RightUp(Point, dword keyflags) +{ + Commit(); +} + +} \ No newline at end of file diff --git a/uppsrc/RichEdit/Mouse.cpp b/uppsrc/RichEdit/Mouse.cpp index ae29883fe..bde0c488f 100644 --- a/uppsrc/RichEdit/Mouse.cpp +++ b/uppsrc/RichEdit/Mouse.cpp @@ -308,6 +308,7 @@ void RichEdit::StdBar(Bar& menu) } } LoadImageTool(menu); + InsertDiagramTool(menu); } } diff --git a/uppsrc/RichEdit/Ops.cpp b/uppsrc/RichEdit/Ops.cpp new file mode 100644 index 000000000..513e06bdc --- /dev/null +++ b/uppsrc/RichEdit/Ops.cpp @@ -0,0 +1,166 @@ +#include "RichEdit.h" + +namespace Upp { + +void DiagramEditor::SetAttrs() +{ + for(int i = 0; i < sel.GetCount(); i++) { + DiagramItem& m = data.item[sel[i]]; + m.shape = ~shape; + m.line_start = ~line_start; + m.line_end = ~line_end; + m.width = ~line_width; + m.dash = ~line_dash; + m.ink = ~ink; + m.paper = ~paper; + } + Sync(); + Commit(); +} + +void DiagramEditor::GetAttrs() +{ + DiagramItem& m = CursorItem(); + shape <<= m.shape; + line_start <<= m.line_start; + line_end <<= m.line_end; + line_width <<= m.width; + line_dash <<= m.dash; + ink <<= m.ink; + paper <<= m.paper; +} + +void DiagramEditor::MoveFrontBack(bool back) +{ + FinishText(); + Array item; + Index newsel; + int newcursor = -1; + for(int pass = 0; pass < 2; pass++) + for(int i = 0; i < data.item.GetCount(); i++) { + bool isel = sel.Find(i) >= 0; + bool b = pass; + if(back) + b = !b; + if(isel == b) { + int ii = item.GetCount(); + if(isel) + newsel.Add(ii); + if(cursor == i) + newcursor = ii; + item.Add(data.item[i]); + } + } + data.item = pick(item); + sel = pick(newsel); + cursor = newcursor; + Sync(); +} + +void DiagramEditor::Align(bool horz, int align) +{ + FinishText(); + + if(!IsCursor()) + return; + + auto HoVe = [&](Pointf& p) -> double& { + return horz ? p.x : p.y; + }; + + Rect cr = GetCursorRect(); + Pointf cp1 = cr.TopLeft(); + Pointf cp2 = cr.BottomRight(); + double csz = HoVe(cp2) - HoVe(cp1); + for(int ii : sel) { + if(ii != cursor) { + DiagramItem& m = data.item[ii]; + m.Normalize(); + Pointf& p1 = m.p1; + Pointf& p2 = m.p2; + double sz = abs(HoVe(p2) - HoVe(p1)); + if(align == ALIGN_LEFT) { + HoVe(p1) = HoVe(cp1); + HoVe(p2) = HoVe(cp1) + sz; + } + if(align == ALIGN_RIGHT) { + HoVe(p2) = HoVe(cp2); + HoVe(p1) = HoVe(cp2) - sz; + } + if(align == ALIGN_CENTER) { + HoVe(p1) = HoVe(cp1) + csz / 2 - sz / 2; + HoVe(p2) = HoVe(p1) + sz; + } + if(align == ALIGN_JUSTIFY) + HoVe(p2) = HoVe(p1) + csz; + } + } + Commit(); +} + +/* TODO remove + +struct SizeDlg : WithSizeLayout { + SizeDlg(); + + static Size sz[]; + + void Set(Size sz); + Size Get() const; + void Sync(); +}; + +Size SizeDlg::sz[] = +{ + Size(1250, 1000), + Size(1600, 900), + Size(1600, 800), + Size(1000, 1250), +}; + +Size SizeDlg::Get() const +{ + int q = ~size; + if(q >= 0 && q < __countof(sz)) { + return sz[q]; + } + auto cl = [](int x) { return clamp(x, 64, 10000); }; + return Size(cl(~cx), cl(~cy)); +} + +void SizeDlg::Sync() +{ + Size sz = Get(); + cx <<= sz.cx; + cy <<= sz.cy; + bool b = ~size == 4; + cx.Enable(b); + cy.Enable(b); +} + +void SizeDlg::Set(Size sz) +{ + cx <<= sz.cx; + cy <<= sz.cy; + int i = FindIndex(SubRange(sz, __countof(sz)), sz); + size = i < 0 ? 4 : i; + Sync(); +} + +SizeDlg::SizeDlg() +{ + CtrlLayoutOKCancel(*this, "Canvas size"); + size << [=] { Sync(); }; +} + +void DiagramEditor::ChangeSize() +{ + SizeDlg dlg; + dlg.Set(data.sz); + if(dlg.ExecuteOK()) { + data.sz = dlg.Get(); + Commit(); + } +} +*/ +} \ No newline at end of file diff --git a/uppsrc/RichEdit/RichEdit.h b/uppsrc/RichEdit/RichEdit.h index 89e97d0f4..906cdbdf5 100644 --- a/uppsrc/RichEdit/RichEdit.h +++ b/uppsrc/RichEdit/RichEdit.h @@ -645,6 +645,7 @@ private: void ZoomClip(RichText& text) const; void InsertImage(); + void InsertDiagram(); RichObject Adjust(RichObject o); @@ -789,6 +790,7 @@ public: void PastePlainTextTool(Bar& bar, dword key = K_CTRL_V|K_SHIFT); void ObjectTool(Bar& bar, dword key = 0); void LoadImageTool(Bar& bar, dword key = 0); + void InsertDiagramTool(Bar& bar, dword key = 0); void FindReplaceTool(Bar& bar, dword key = K_CTRL_F); void InsertTableTool(Bar& bar, dword key = K_CTRL_F12); @@ -914,6 +916,8 @@ public: void AppendClipboard(RichText&& txt); +#include "DiagramEditor.h" + } #endif diff --git a/uppsrc/RichEdit/RichEdit.upp b/uppsrc/RichEdit/RichEdit.upp index a4c196cf8..67c9a7574 100644 --- a/uppsrc/RichEdit/RichEdit.upp +++ b/uppsrc/RichEdit/RichEdit.upp @@ -27,6 +27,17 @@ file RichEdit.t charset "UTF-8", RichEdit.lay, RichEdit.iml, + Diagram readonly separator, + DiagramEditor.h, + DiagramEditor.cpp, + DiagramMouse.cpp, + DiagramCursor.cpp, + Ops.cpp, + Bar.cpp, + Text.cpp, + DiagramClip.cpp, + Diagram.iml, + Diagram.lay, Info readonly separator, Copying; diff --git a/uppsrc/RichEdit/Text.cpp b/uppsrc/RichEdit/Text.cpp new file mode 100644 index 000000000..96192a178 --- /dev/null +++ b/uppsrc/RichEdit/Text.cpp @@ -0,0 +1,77 @@ +#include "RichEdit.h" + +namespace Upp { + +bool DiaRichEdit::Key(dword key, int count) +{ + if(key == K_ENTER) { + WhenEnter(); + return true; + } + if(key == K_ESCAPE) { + WhenEsc(); + return true; + } + if(findarg(key, K_SHIFT|K_ENTER, K_CTRL|K_ENTER) >= 0) + key = K_ENTER; + + return RichEdit::Key(key, count); +} + +void DiagramEditor::SyncEditor() +{ + if(edit_text && cursor >= 0) { + text_editor.SetEditable(); // to enable toolbar widgets + text_editor.Floating(-Diagram::TextZoom().AsDouble() * GetZoom()); + text_editor.OverridePaper(CursorItem().paper); + text_editor.Show(); + } + else { + text_editor.Hide(); + text_editor.SetReadOnly(); // to disable toolbar widgets + return; + } + SyncEditorRect(); +} + +void DiagramEditor::SyncEditorRect() +{ + Rectf r = CursorItem().GetTextEditRect(); + r = GetZoom() * r; + r.Offset(-(Pointf)(Point)sb * GetZoom()); + Upp::Zoom z = Diagram::TextZoom(); + z.m *= GetZoom(); + int cy = max(30, text_editor.Get().GetHeight(z, r.GetWidth()) + DPI(10)); + r.top = r.CenterPoint().y - cy / 2; + r.bottom = r.top + cy; + r.left -= DPI(2); + r.right += DPI(2) + ScrollBarSize(); + + int q = GetSize().cx - r.right; + if(q < 0) + r.Offset(q, 0); + if(r.left < 0) + r.left = 0; + text_editor.SetRect(r); +} + +void DiagramEditor::StartText() +{ + FinishText(); + edit_text = true; + Sync(); + text_editor.SetFocus(); + text_editor.SetQTF("[= " + CursorItem().qtf); + text_editor.Select(0, text_editor.GetLength()); + SyncEditorRect(); +} + +void DiagramEditor::FinishText() +{ + if(edit_text && cursor >= 0) + CursorItem().qtf = AsQTF(text_editor.Get(), CHARSET_UTF8, QTF_BODY|QTF_NOCHARSET|QTF_NOLANG|QTF_NOSTYLES); + edit_text = false; + Sync(); +} + +} \ No newline at end of file diff --git a/uppsrc/RichEdit/Tool.cpp b/uppsrc/RichEdit/Tool.cpp index 2b3e207f7..b0d09f01c 100644 --- a/uppsrc/RichEdit/Tool.cpp +++ b/uppsrc/RichEdit/Tool.cpp @@ -352,6 +352,11 @@ void RichEdit::LoadImageTool(Bar& bar, dword key) bar.Add(!IsReadOnly(), t_("Insert image from file.."), CtrlImg::open(), THISBACK(InsertImage)); } +void RichEdit::InsertDiagramTool(Bar& bar, dword key) +{ + bar.Add(!IsReadOnly(), t_("Insert diagram.."), DiagramImg::Diagram(), [=] { InsertDiagram(); }); +} + void RichEdit::PrintTool(Bar& bar, dword key) { bar.Add(t_("Print"), CtrlImg::print(), USERBACK(DoPrint)) diff --git a/uppsrc/RichText/Diagram.cpp b/uppsrc/RichText/Diagram.cpp new file mode 100644 index 000000000..2130abed2 --- /dev/null +++ b/uppsrc/RichText/Diagram.cpp @@ -0,0 +1,361 @@ +#include "RichText.h" + +namespace Upp { + +double DistanceFromSegment(Pointf P, Pointf P0, Pointf P1, Pointf *p = NULL) +{ + Pointf v = P1 - P0; + Pointf w = P - P0; + auto Dot = [](Pointf a, Pointf b) { return a.x * b.x + a.y * b.y; }; + double c1 = Dot(w, v); + double c2 = Dot(v, v); + if(p) + *p = Null; + if(c1 <= 0) + return Distance(P, P0); + if(c1 >= c2) + return Distance(P, P1); + Pointf sp = P0 + c1 / c2 * v; + if(p) + *p = sp; + return Distance(P, sp); +} + +Index DiagramItem::LineCap = { "none", "arrow", "round" }; +Index DiagramItem::Shape = { "line", "rect", "round_rect", "ellipse", "diamond", "oval", "parallelogram" }; + +void DiagramItem::Reset() +{ + shape = SHAPE_RECT; + qtf.Clear(); + width = 2; + ink = Black(); + paper = White(); + + line_start = CAP_NONE; + line_end = CAP_NONE; + dash = 0; +} + +void Point2::Normalize() +{ + if(p1.x > p2.x) + Swap(p1.x, p2.x); + if(p1.y > p2.y) + Swap(p1.y, p2.y); +} + +bool DiagramItem::IsClick(Point p) const +{ + if(IsLine()) + return DistanceFromSegment(p, p1, p2) < width + 20; + else + return GetRect().Inflated(5).Contains(p); +} + +bool DiagramItem::IsTextClick(Point p0) const +{ + Zoom zoom = Diagram::TextZoom(); + double z = zoom.AsDouble(); + RichText txt = ParseQTF(qtf); + Rect r = GetRect(); + Rect page; + Pointf p; + if(IsLine()) { + int cx = Distance(p1, p2); + int txt_cy = txt.GetHeight(zoom, cx); + Pointf sp; + double dist = DistanceFromSegment(p0, p1, p2, &sp); + p.y = txt_cy + 10 - dist; + if(p0.y >= sp.y) // only consider text above + return false; + p.x = Distance(p1.x < p2.x ? p1 : p2, sp); + if(dist < 25 && abs(p.x - cx / 2) < 10) + return true; + p = p / z; + page.top = 0; + page.left = 0; + page.right = cx / z; + } + else { + int txt_cy = txt.GetHeight(zoom, r.GetWidth()); + r = RectC(r.left, r.top + (r.GetHeight() - txt_cy) / 2, r.GetWidth(), txt_cy); + Rect r2 = r; + int x = r.CenterPoint().x; + r2.left = x - 20; + r2.right = x + 20; + if(r2.Contains(p0)) + return true; + if(!r.Contains(p0)) + return false; + p = (Pointf)p0 / z; + page = (Rectf)r / z; + } + page.bottom = INT_MAX; + int pos = txt.GetPos((int)p.x, PageY(0, (int)p.y), page); + return pos < txt.GetLength() && txt.GetRichPos(pos).chr != '\n' && txt.GetCaret(pos, page).Contains(p); +} + +Rect DiagramItem::GetTextEditRect() const +{ + if(IsLine()) { + int d = max(10, int(Distance(p1, p2) + 0.5)); + Point c = (p1 + p2) / 2; + return Rect(c.x - d / 2, c.y, c.x + d, c.y); + } + return GetRect(); +} + +void DiagramItem::Paint(Painter& w, dword style) const +{ + Zoom zoom = Diagram::TextZoom(); + + RichText txt = ParseQTF(qtf); + + static Vector dashes[4] = { { 0 }, { 1 }, { 2 }, { 1, 2 } }; + + auto DoDash = [&] { + if(dash) { + Vector d = clone(dashes[clamp(dash, 0, __countof(dashes))]); + for(double& h : d) + h *= width; + w.Dash(d, 0); + } + }; + + Color sel1 = SColorHighlight(); + Color sel2 = Blend(SColorHighlight(), SWhite()); + + if(IsLine()) { + Pointf v = p2 - p1; + if(style) { + w.Move(p1).Line(p2).EndPath(); + w.Begin(); + if((style & EDITOR) && width == 0) + w.Dash("5 1").Stroke(1, 100 * sel2); + if(style & (Display::CURSOR | Display::SELECT)) { + w.LineCap(LINECAP_ROUND).Stroke(width + 12, (style & Display::SELECT ? 30 : 200) * sel2); + double r = (width + 12) / 2 - 1; + w.Circle(p1, r).Fill(sel1); + w.Circle(p2, r).Fill(sel1); + } + w.End(); + } + double d = Length(v); + v = Upp::Normalize(v); + + Pointf a1 = p1; + Pointf a2 = p2; + if(d > 20) { // enough length to have caps + if(line_start == CAP_ARROW) + a1 += v * 8; + if(line_end == CAP_ARROW) + a2 -= v * 8; + } + + w.Move(a1).Line(a2); + DoDash(); + w.Stroke(width, ink); + + Pointf o = Orthogonal(v); + if(d > 20) { + auto PaintCap = [&](int k, Pointf p, Pointf a) { + switch(k) { + case CAP_ARROW: + w.Move(p).Line(a + 4 * o).Line(a - 4 * o).Fill(ink); + break; + case CAP_CIRCLE: + w.Circle(p, 5).Fill(ink); + break; + } + }; + PaintCap(line_start, p1, a1 + v); + PaintCap(line_end, p2, a2 - v); + } + + int cx = Distance(p1, p2); + int txt_cy = txt.GetHeight(zoom, cx); + + w.Begin(); + double angle = Bearing(p2 - p1); + if(angle >= -M_PI / 2 && angle <= M_PI / 2) { + w.Translate(p1 - o * (txt_cy + 10)); + w.Rotate(angle); + } + else { + w.Translate(p2 + o * (txt_cy + 10)); + w.Rotate(angle + M_PI); + } + txt.Paint(zoom, w, 0, 0, cx); + w.End(); + } + else { + if(style & (Display::CURSOR | Display::SELECT)) { + w.RoundedRectangle(GetRect(), 5) + .Fill((style & Display::SELECT ? 30 : 200) * sel2); + w.RoundedRectangle(GetRect().Inflated(2), 5) + .Stroke(6, (style & Display::SELECT ? 30 : 200) * sel1); + } + + int txt_cy = txt.GetHeight(zoom, GetRect().GetWidth()); + Rectf r(p1, p2); + r.Normalize(); + Pointf c = r.CenterPoint(); + int sz = min(r.Width(), r.Height()); + switch(shape) { + case SHAPE_ROUNDRECT: + w.RoundedRectangle(r.left, r.top, r.GetWidth(), r.GetHeight(), sz > 30 ? 8 : sz > 15 ? 4 : 2); + break; + case SHAPE_OVAL: + if(r.GetWidth() > r.GetHeight()) { + double ra = r.GetHeight() / 2; + w.Move(r.left + ra, r.top) + .Line(r.right - ra, r.top) + .Arc(r.right - ra, r.top + ra, ra, -M_PI / 2, M_PI) + .Line(r.left + ra, r.bottom) + .Arc(r.left + ra, r.top + ra, ra, M_PI / 2, M_PI); + break; + } + case SHAPE_ELLIPSE: + w.Ellipse(r); + break; + case SHAPE_DIAMOND: + w.Move(c.x, r.top).Line(r.right, c.y).Line(c.x, r.bottom).Line(r.left, c.y).Close(); + break; + case SHAPE_PARALLELOGRAM: + w.Move(r.left + r.Width() / 6, r.top).Line(r.right, r.top) + .Line(r.right - r.Width() / 6, r.bottom).Line(r.left, r.bottom).Close(); + break; + default: + w.Rectangle(r); + break; + } + DoDash(); + w.Stroke(width, ink).Fill(paper); + txt.Paint(zoom, w, r.left, r.top + (r.GetHeight() - txt_cy) / 2, r.GetWidth()); + } +} + +void DiagramItem::Save(StringBuffer& r) const +{ + r << Shape[clamp(shape, 0, Shape.GetCount())] << ' '; + r << p1.x << ' ' << p1.y << ' ' << p2.x << ' ' << p2.y; + if(qtf.GetCount()) + r << " " << AsCString(qtf); + auto col = [&](Color c) { + return Format("%02x%02x%02x", (int)c.GetR(), (int)c.GetG(), (int)c.GetB()); + }; + if(ink != Black()) + r << " ink " << col(ink); + if(paper != White()) + r << " paper " << col(paper); + if(width != 2) + r << " width " << width; + if(line_start != CAP_NONE) + r << " start " << LineCap[clamp(line_start, 0, LineCap.GetCount())]; + if(line_end != CAP_NONE) + r << " end " << LineCap[clamp(line_end, 0, LineCap.GetCount())]; + if(dash) + r << " dash " << dash; + r << ";"; +} + +void DiagramItem::Load(CParser& p) +{ + Reset(); + int q = Shape.Find(p.ReadId()); + if(q < 0) + p.ThrowError("Unknown element"); + shape = q; + p1.x = p.ReadDouble(); + p1.y = p.ReadDouble(); + p2.x = p.ReadDouble(); + p2.y = p.ReadDouble(); + auto col = [&] { + dword x = p.ReadNumber(16); + return Color(byte(x >> 16), byte(x >> 8), byte(x)); + }; + for(;;) { + auto cap = [&] { return max(LineCap.Find(p.ReadId()), 0); }; + if(p.Char(';')) + break; + else + if(p.IsString()) + qtf = p.ReadString(); + else + if(p.Id("ink")) + ink = col(); + else + if(p.Id("paper")) + paper = col(); + else + if(p.Id("width")) + width = clamp(p.ReadDouble(), 0.0, 50.0); + else + if(p.Id("start")) + line_start = cap(); + else + if(p.Id("end")) + line_end = cap(); + else + if(p.Id("dash")) + dash = clamp(p.ReadInt(), 0, (int)DASH_COUNT); + else + p.Skip(); + } +} + +Size Diagram::GetSize() const +{ // TODO: Negatives? + if(item.GetCount() == 0) + return Size(0, 0); + Pointf tl, br; + tl = br = item[0].p1; + for(const DiagramItem& m : item) { + tl.x = min(tl.x, m.p1.x, m.p2.x); + tl.y = min(tl.y, m.p1.y, m.p2.y); + br.x = max(br.x, m.p1.x, m.p2.x); + br.y = max(br.y, m.p1.y, m.p2.y); + } + + Sizef fsz = br + tl; + + return Size(ceil(fsz.cx), ceil(fsz.cy)); +} + +void Diagram::Paint(Painter& w, const Diagram::PaintInfo& p) const +{ + for(int i = 0; i < item.GetCount(); i++) { + dword style = 0; + if(i == p.cursor) + style = Display::CURSOR; + else + if(p.sel.Find(i) >= 0) + style = Display::SELECT; + if(p.editor) + style |= DiagramItem::EDITOR; + item[i].Paint(w, style); + } +} + +void Diagram::Serialize(Stream& s) +{ + s % item; +} + +void Diagram::Save(StringBuffer& r) const +{ + for(const DiagramItem& m : item) { + m.Save(r); + r << '\n'; + } +} + +void Diagram::Load(CParser& p) +{ + item.Clear(); + while(!p.IsEof()) + item.Add().Load(p); +} + +} diff --git a/uppsrc/RichText/Diagram.h b/uppsrc/RichText/Diagram.h new file mode 100644 index 000000000..04ccf370d --- /dev/null +++ b/uppsrc/RichText/Diagram.h @@ -0,0 +1,89 @@ +struct Point2 : Moveable { + Pointf p1; + Pointf p2; + + void Offset(Pointf p) { p1 += p; p2 += p; } + Point2 Offseted(Pointf p) const { Point2 r = *this; r.Offset(p); return r; } + void Normalize(); + Rectf GetRect() const { return Rect(p1, p2).Normalized(); } + String ToString() const { return String() << p1 << " - " << p2; } + + void Serialize(Stream& s) { s % p1 % p2; } +}; + +struct DiagramItem : Point2 { + int shape; + String qtf; + double width; + Color ink; + Color paper; + + enum { + SHAPE_LINE, + SHAPE_RECT, + SHAPE_ROUNDRECT, + SHAPE_ELLIPSE, + SHAPE_DIAMOND, + SHAPE_OVAL, + SHAPE_PARALLELOGRAM, + SHAPE_COUNT, + }; + + enum LineEnding { + CAP_NONE, + CAP_ARROW, + CAP_CIRCLE, + + CAP_COUNT + }; + + enum Dash { + DASH_COUNT = 4 + }; + + enum { + EDITOR = 0x8000 + }; + + int line_start = CAP_NONE; + int line_end = CAP_NONE; + int dash = 0; + + void Paint(Painter& w, dword style = 0) const; + + bool IsLine() const { return shape == SHAPE_LINE; } + + bool IsClick(Point p) const; + bool IsTextClick(Point p) const; + Rect GetTextEditRect() const; + + void Serialize(Stream& s) { Point2::Serialize(s); s % shape % ink % paper % qtf % width % line_start % line_end % dash; } + + void Reset(); + void Save(StringBuffer& r) const; + void Load(CParser& p); + + DiagramItem() { Reset(); } + +private: + static Index LineCap; + static Index Shape; +}; + +struct Diagram { + Array item; + + struct PaintInfo { + bool editor = false; + int cursor = -1; + Index sel; + }; + + Size GetSize() const; + void Paint(Painter& w, const PaintInfo& pi) const; + void Serialize(Stream& s); + void Save(StringBuffer& r) const; + void Load(CParser& p); + + static Zoom TextZoom() { return Zoom(96, 600); } +}; diff --git a/uppsrc/RichText/RichText.h b/uppsrc/RichText/RichText.h index 59af324b0..ce600482b 100644 --- a/uppsrc/RichText/RichText.h +++ b/uppsrc/RichText/RichText.h @@ -6,7 +6,7 @@ #include namespace Upp { - + #define IMAGECLASS RichTextImg #define IMAGEFILE #include @@ -43,6 +43,8 @@ struct Zoom { friend int operator/(int x, Zoom z) { return z.m ? iscale(x, z.d, z.m) : 0; } }; +#include "Diagram.h" + inline bool IsNull(Zoom z) { return (z.m | z.d) == 0; } inline int operator*(int x, Zoom m) diff --git a/uppsrc/RichText/RichText.upp b/uppsrc/RichText/RichText.upp index 24f7fb984..270f35e3c 100644 --- a/uppsrc/RichText/RichText.upp +++ b/uppsrc/RichText/RichText.upp @@ -35,6 +35,9 @@ file ParseHTML.cpp, Util.cpp, RichText.iml, + Diagram readonly separator, + Diagram.h, + Diagram.cpp, Info readonly separator, srcdoc.tpp, src.tpp, diff --git a/upptst/Diagram/Diagram.upp b/upptst/Diagram/Diagram.upp new file mode 100644 index 000000000..f758038f5 --- /dev/null +++ b/upptst/Diagram/Diagram.upp @@ -0,0 +1,10 @@ +uses + CtrlLib, + RichEdit; + +file + main.cpp; + +mainconfig + "" = "GUI"; + diff --git a/upptst/Diagram/main.cpp b/upptst/Diagram/main.cpp new file mode 100644 index 000000000..3fd0dab13 --- /dev/null +++ b/upptst/Diagram/main.cpp @@ -0,0 +1,15 @@ +#include + +using namespace Upp; + +GUI_APP_MAIN +{ + TopWindow app; + app.Sizeable().Zoomable(); + DiagramEditor de; + app.Add(de.SizePos()); + String fn = "c:/xxx/test.qdf"; + de.Load(LoadFile(fn)); + app.Run(); + SaveFile(fn, de.Save()); +}