mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
Painter: Fixed RoundRect scaling issue, Diagram: rotation code refactored
This commit is contained in:
parent
95e667a3e8
commit
dd9e27dfd6
8 changed files with 58 additions and 17 deletions
|
|
@ -165,10 +165,10 @@ protected:
|
|||
virtual void BeginOnPathOp(double q, bool absolute) = 0;
|
||||
|
||||
protected:
|
||||
void DoArc0(double theta, double th_sweep, const Xform2D& m);
|
||||
void DoArc(const Pointf& c, const Pointf& r, double angle, double sweep, double xangle);
|
||||
void DoArc0(double theta, double th_sweep, const Xform2D& m, double scale = 1);
|
||||
void DoArc(const Pointf& c, const Pointf& r, double angle, double sweep, double xangle, double scale = 1);
|
||||
void DoSvgArc(const Pointf& rr, double xangle, int large, int sweep,
|
||||
const Pointf& p, const Pointf& p0);
|
||||
const Pointf& p, const Pointf& p0, double scale = 1);
|
||||
void DrawLineStroke(int width, Color color);
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Upp {
|
||||
|
||||
void Painter::DoArc0(double theta, double th_sweep, const Xform2D& m)
|
||||
void Painter::DoArc0(double theta, double th_sweep, const Xform2D& m, double scale)
|
||||
{
|
||||
int nsegs = int(ceil(fabs(th_sweep / (M_PI * 0.5 + 0.001))));
|
||||
for(int i = 0; i < nsegs; i++) {
|
||||
|
|
@ -18,16 +18,16 @@ void Painter::DoArc0(double theta, double th_sweep, const Xform2D& m)
|
|||
}
|
||||
}
|
||||
|
||||
void Painter::DoArc(const Pointf& c, const Pointf& r, double angle, double sweep, double xangle)
|
||||
void Painter::DoArc(const Pointf& c, const Pointf& r, double angle, double sweep, double xangle, double scale)
|
||||
{
|
||||
Xform2D m = Xform2D::Scale(r.x, r.y);
|
||||
m = m * Xform2D::Translation(c.x, c.y);
|
||||
Line(m.Transform(cos(angle), sin(angle)));
|
||||
DoArc0(angle, sweep, m);
|
||||
DoArc0(angle, sweep, m, scale);
|
||||
}
|
||||
|
||||
void Painter::DoSvgArc(const Pointf& rr, double xangle, int large, int sweep,
|
||||
const Pointf& p1, const Pointf& p0)
|
||||
const Pointf& p1, const Pointf& p0, double scale)
|
||||
{
|
||||
Pointf r(fabs(rr.x), fabs(rr.y));
|
||||
Xform2D m = Xform2D::Rotation(-xangle);
|
||||
|
|
@ -61,7 +61,7 @@ void Painter::DoSvgArc(const Pointf& rr, double xangle, int large, int sweep,
|
|||
m.x *= r;
|
||||
m.y *= r;
|
||||
m = Xform2D::Translation(c.x, c.y) * m;
|
||||
DoArc0(theta, th_sweep, m);
|
||||
DoArc0(theta, th_sweep, m, scale);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ Point DiagramEditor::GetHandle(int i, Point p_) const
|
|||
p -= r.CenterPoint();
|
||||
r -= r.CenterPoint();
|
||||
|
||||
p = Xform2D::Rotation(-M_2PI * m.rotate / 360).Transform(p);
|
||||
p = m.Rotation(-1).Transform(p);
|
||||
|
||||
Rect rr = r.Inflated(5);
|
||||
r.Deflate(min(10, r.GetWidth() / 2), min(10, r.GetHeight() / 2));
|
||||
|
|
@ -328,6 +328,8 @@ void DiagramEditor::MouseMove(Point p, dword keyflags)
|
|||
if(h)
|
||||
(h < 0 ? a1 : a2) = a;
|
||||
};
|
||||
if(!m.IsLine())
|
||||
m.Normalize();
|
||||
Rectf r = m.GetRect();
|
||||
Pointf cp = r.CenterPoint();
|
||||
if(m.IsLine()) {
|
||||
|
|
@ -336,16 +338,17 @@ void DiagramEditor::MouseMove(Point p, dword keyflags)
|
|||
}
|
||||
else
|
||||
if(draghandle.x == -1 && draghandle.y == 1) {
|
||||
Pointf bl = Xform2D::Rotation(M_2PI * base_rotate / 360).Transform(r.BottomLeft() - cp);
|
||||
Pointf bl = Xform2D::Rotation(M_PI * base_rotate / 180.0).Transform(r.BottomLeft() - cp);
|
||||
m.rotate = base_rotate + 180.0 * (Bearing((Pointf)p0 - cp) - Bearing(bl)) / M_PI;
|
||||
if(grid && !GetShift())
|
||||
m.rotate = int(m.rotate + 360 + 7) / 15 * 15;
|
||||
}
|
||||
else {
|
||||
bool rotated = m.rotate && !m.IsLine();
|
||||
bool rotated = m.rotate;
|
||||
if(rotated) {
|
||||
p -= cp;
|
||||
p = Xform2D::Rotation(-M_2PI * m.rotate / 360).Transform(p);
|
||||
r -= cp;
|
||||
p = m.Rotation(-1).Transform(p);
|
||||
p += cp;
|
||||
}
|
||||
Do(draghandle.x, r.left, r.right, p.x);
|
||||
|
|
@ -371,6 +374,8 @@ void DiagramEditor::MouseMove(Point p, dword keyflags)
|
|||
else
|
||||
m.pt[1].y = m.pt[0].y + sz.cy;
|
||||
}
|
||||
if(rotated)
|
||||
r += cp;
|
||||
m.pt[0] = r.TopLeft();
|
||||
m.pt[1] = r.BottomRight();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ bool DiagramItem::IsClick(Point p, const Diagram& diagram, bool relaxed) const
|
|||
Pointf cp = rect.CenterPoint();
|
||||
if(rotate) {
|
||||
p -= cp;
|
||||
p = Xform2D::Rotation(-M_PI * rotate / 180).Transform(p);
|
||||
p = Rotation(-1).Transform(p);
|
||||
p += cp;
|
||||
}
|
||||
if(!rect.Contains(p))
|
||||
|
|
@ -279,7 +279,7 @@ Size Diagram::GetSize() const
|
|||
Pointf cp = r.CenterPoint();
|
||||
Xform2D rot;
|
||||
if(m.rotate)
|
||||
rot = Xform2D::Rotation(M_2PI * m.rotate / 360);
|
||||
rot = m.Rotation();
|
||||
auto Do = [&](Pointf p) {
|
||||
if(m.rotate) {
|
||||
p -= cp;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ struct DiagramItem : Point2 {
|
|||
void Paint(Painter& w, const Diagram& diagram, dword style = 0, const Index<Pointf> *conn = nullptr) const;
|
||||
Sizef GetStdSize(const Diagram& diagram) const;
|
||||
|
||||
bool IsLine() const { return shape == SHAPE_LINE; }
|
||||
bool IsLine() const { return shape == SHAPE_LINE; }
|
||||
|
||||
Vector<Pointf> GetConnections() const;
|
||||
|
||||
|
|
@ -80,8 +80,10 @@ struct DiagramItem : Point2 {
|
|||
Rect GetTextEditRect() const;
|
||||
|
||||
void FixPosition();
|
||||
|
||||
Xform2D Rotation(int d = 1) const { return Xform2D::Rotation(d * M_PI * rotate / 180); }
|
||||
|
||||
void Serialize(Stream& s) { Point2::Serialize(s); s % shape % ink % paper % qtf % width % cap[0] % cap[1] % dash % blob_id % flip_horz % flip_vert % aspect_ratio; }
|
||||
void Serialize(Stream& s) { Point2::Serialize(s); s % shape % ink % paper % qtf % width % cap[0] % cap[1] % dash % blob_id % flip_horz % flip_vert % aspect_ratio; }
|
||||
|
||||
void Reset();
|
||||
void Save(StringBuffer& r) const;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ Vector<Pointf> DiagramItem::GetConnections() const
|
|||
if(shape == SHAPE_ITRIANGLE)
|
||||
p << r.TopLeft() << r.TopRight();
|
||||
if(rotate) {
|
||||
Xform2D rot = Xform2D::Rotation(M_2PI * rotate / 360);
|
||||
Xform2D rot = Rotation();
|
||||
Pointf c = r.CenterPoint();
|
||||
for(Pointf& x : p) {
|
||||
x -= c;
|
||||
|
|
|
|||
9
upptst/RoundRect2/RoundRect2.upp
Normal file
9
upptst/RoundRect2/RoundRect2.upp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
uses
|
||||
CtrlLib;
|
||||
|
||||
file
|
||||
main.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI";
|
||||
|
||||
25
upptst/RoundRect2/main.cpp
Normal file
25
upptst/RoundRect2/main.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
// The reason: stroke width should affect cubic tolerance
|
||||
// the line arc is way to small, so it really contains just 2 points or so...
|
||||
|
||||
struct MyApp : public TopWindow {
|
||||
void Paint(Draw& w) override {
|
||||
DrawPainter p(w, GetSize());
|
||||
p.Clear(White());
|
||||
p.Scale(22);
|
||||
DLOG("-----------------------------");
|
||||
p.Move(10, 10);
|
||||
p.Arc(10, 10, 0.1, M_PI, M_PI);
|
||||
// p.RoundedRectangle(2, 2, 100, 100, 0.1)
|
||||
// p.Stroke(5, Blue());
|
||||
p.Stroke(0.1, Blue());
|
||||
}
|
||||
};
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
MyApp().Run();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue