mirror of
https://github.com/ra3xdh/qucs_s
synced 2025-03-28 21:13:26 +00:00

arrow.cpp: Q3PointArray -> QPolygon * unused header: arrowdialog.cpp ellipse.cpp ellipsearc.cpp graphicline.cpp painting.cpp rectangle.cpp graphictext.cpp * unnecessary include: filldialog.h graphictextdialog.h id_dialog.h * add include: graphicline.h: add QPen graphictext.h: add QFont, QColor, QString portsymbol.h: add QString * remove comment painting.h
410 lines
12 KiB
C++
410 lines
12 KiB
C++
/***************************************************************************
|
|
ellipsearc.cpp
|
|
----------------
|
|
begin : Thu Sep 9 2004
|
|
copyright : (C) 2004 by Michael Margraf
|
|
email : michael.margraf@alumni.tu-berlin.de
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
#include <QtGui>
|
|
#include "ellipsearc.h"
|
|
#include "filldialog.h"
|
|
#include "main.h"
|
|
#include "schematic.h"
|
|
|
|
#include <math.h>
|
|
|
|
|
|
EllipseArc::EllipseArc()
|
|
{
|
|
Name = "EArc ";
|
|
isSelected = false;
|
|
Pen = QPen(QColor());
|
|
cx = cy = x1 = x2 = y1 = y2 = Angle = ArcLen = 0;
|
|
}
|
|
|
|
EllipseArc::~EllipseArc()
|
|
{
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
void EllipseArc::paint(ViewPainter *p)
|
|
{
|
|
if(isSelected) {
|
|
p->Painter->setPen(QPen(Qt::darkGray,Pen.width()+5));
|
|
p->drawArc(cx, cy, x2, y2, Angle, ArcLen);
|
|
p->Painter->setPen(QPen(Qt::white, Pen.width(), Pen.style()));
|
|
p->drawArc(cx, cy, x2, y2, Angle, ArcLen);
|
|
|
|
p->Painter->setPen(QPen(Qt::darkRed,2));
|
|
p->drawResizeRect(cx, cy+y2); // markers for changing the size
|
|
p->drawResizeRect(cx, cy);
|
|
p->drawResizeRect(cx+x2, cy+y2);
|
|
p->drawResizeRect(cx+x2, cy);
|
|
return;
|
|
}
|
|
p->Painter->setPen(Pen);
|
|
p->drawArc(cx, cy, x2, y2, Angle, ArcLen);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
void EllipseArc::paintScheme(Schematic *p)
|
|
{
|
|
p->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, ArcLen);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
void EllipseArc::getCenter(int& x, int &y)
|
|
{
|
|
x = cx+(x2>>1);
|
|
y = cy+(y2>>1);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Sets the center of the painting to x/y.
|
|
void EllipseArc::setCenter(int x, int y, bool relative)
|
|
{
|
|
if(relative) { cx += x; cy += y; }
|
|
else { cx = x-(x2>>1); cy = y-(y2>>1); }
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
Painting* EllipseArc::newOne()
|
|
{
|
|
return new EllipseArc();
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
Element* EllipseArc::info(QString& Name, char* &BitmapFile, bool getNewOne)
|
|
{
|
|
Name = QObject::tr("Elliptic Arc");
|
|
BitmapFile = (char *) "ellipsearc";
|
|
|
|
if(getNewOne) return new EllipseArc();
|
|
return 0;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
bool EllipseArc::load(const QString& s)
|
|
{
|
|
bool ok;
|
|
QString n;
|
|
|
|
n = s.section(' ',1,1); // cx
|
|
cx = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
n = s.section(' ',2,2); // cy
|
|
cy = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
n = s.section(' ',3,3); // x2
|
|
x2 = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
n = s.section(' ',4,4); // y2
|
|
y2 = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
n = s.section(' ',5,5); // start angle
|
|
Angle = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
n = s.section(' ',6,6); // arc length
|
|
ArcLen = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
n = s.section(' ',7,7); // color
|
|
QColor co;
|
|
co.setNamedColor(n);
|
|
Pen.setColor(co);
|
|
if(!Pen.color().isValid()) return false;
|
|
|
|
n = s.section(' ',8,8); // thickness
|
|
Pen.setWidth(n.toInt(&ok));
|
|
if(!ok) return false;
|
|
|
|
n = s.section(' ',9,9); // line style
|
|
Pen.setStyle((Qt::PenStyle)n.toInt(&ok));
|
|
if(!ok) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
QString EllipseArc::save()
|
|
{
|
|
QString s = Name +
|
|
QString::number(cx) + " " + QString::number(cy) + " " +
|
|
QString::number(x2) + " " + QString::number(y2) + " " +
|
|
QString::number(Angle) + " " + QString::number(ArcLen) + " " +
|
|
Pen.color().name() + " " + QString::number(Pen.width()) + " " +
|
|
QString::number(Pen.style());
|
|
return s;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
QString EllipseArc::saveCpp()
|
|
{
|
|
QString s =
|
|
QString ("new Arc (%1, %2, %3, %4, %5, %6, "
|
|
"QPen (QColor (\"%7\"), %8, %9))").
|
|
arg(cx).arg(cy).arg(x2).arg(y2).arg(Angle).arg(ArcLen).
|
|
arg(Pen.color().name()).arg(Pen.width()).arg(toPenString(Pen.style()));
|
|
s = "Arcs.append (" + s + ");";
|
|
return s;
|
|
}
|
|
|
|
QString EllipseArc::saveJSON()
|
|
{
|
|
QString s =
|
|
QString ("{\"type\" : \"ellipsearc\", "
|
|
"\"x\" : %1, \"y\" : %2, \"w\" : %3, \"h\" : %4, "
|
|
"\"angle\" : %5, \"arclen\" : %6, "
|
|
"\"color\" : \"%7\", \"thick\" : %8, \"style\" : \"%9\"},").
|
|
arg(cx).arg(cy).arg(x2).arg(y2).arg(Angle).arg(ArcLen).
|
|
arg(Pen.color().name()).arg(Pen.width()).arg(toPenString(Pen.style()));
|
|
return s;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Checks if the resize area was clicked.
|
|
bool EllipseArc::resizeTouched(float fX, float fY, float len)
|
|
{
|
|
float fCX = float(cx), fCY = float(cy);
|
|
float fX2 = float(cx+x2), fY2 = float(cy+y2);
|
|
|
|
State = -1;
|
|
if(fX < fCX-len) return false;
|
|
if(fY < fCY-len) return false;
|
|
if(fX > fX2+len) return false;
|
|
if(fY > fY2+len) return false;
|
|
|
|
State = 0;
|
|
if(fX < fCX+len) State = 1;
|
|
else if(fX <= fX2-len) { State = -1; return false; }
|
|
if(fY < fCY+len) State |= 2;
|
|
else if(fY <= fY2-len) { State = -1; return false; }
|
|
|
|
return true;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Mouse move action during resize.
|
|
void EllipseArc::MouseResizeMoving(int x, int y, Schematic *p)
|
|
{
|
|
paintScheme(p); // erase old painting
|
|
switch(State) {
|
|
case 0: x2 = x-cx; y2 = y-cy; // lower right corner
|
|
break;
|
|
case 1: x2 -= x-cx; cx = x; y2 = y-cy; // lower left corner
|
|
break;
|
|
case 2: x2 = x-cx; y2 -= y-cy; cy = y; // upper right corner
|
|
break;
|
|
case 3: x2 -= x-cx; cx = x; y2 -= y-cy; cy = y; // upper left corner
|
|
break;
|
|
}
|
|
if(x2 < 0) { State ^= 1; x2 *= -1; cx -= x2; }
|
|
if(y2 < 0) { State ^= 2; y2 *= -1; cy -= y2; }
|
|
|
|
paintScheme(p); // paint new painting
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// fx/fy are the precise coordinates, gx/gy are the coordinates set on grid.
|
|
// x/y are coordinates without scaling.
|
|
void EllipseArc::MouseMoving(
|
|
Schematic *paintScale, int fx, int fy, int gx, int gy,
|
|
Schematic *p, int x, int y, bool drawn)
|
|
{
|
|
switch(State) {
|
|
case 0 :
|
|
x2 = gx;
|
|
y2 = gy;
|
|
break;
|
|
case 1 :
|
|
State++;
|
|
x2 = gx - cx;
|
|
y2 = gy - cy;
|
|
paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, 0, 16*360); // paint new painting
|
|
break;
|
|
case 2 :
|
|
paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, 0, 16*360); // erase old painting
|
|
x2 = gx - cx;
|
|
y2 = gy - cy;
|
|
paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, 0, 16*360); // paint new painting
|
|
break;
|
|
case 3 :
|
|
State++;
|
|
paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, 0, 16*360); // erase old painting
|
|
if(x2 < 0) { cx += x2; x2 *= -1; }
|
|
if(y2 < 0) { cy += y2; y2 *= -1; }
|
|
|
|
Angle = int(16.0*180.0/M_PI
|
|
* atan2(double(x2*(cy+(y2>>1) - fy)),
|
|
double(y2*(fx - cx-(x2>>1)))));
|
|
if(Angle < 0) Angle += 16*360;
|
|
paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, 16*180); // new painting
|
|
break;
|
|
case 4 :
|
|
paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, 16*180);// erase old painting
|
|
Angle = int(16.0*180.0/M_PI
|
|
* atan2(double(x2*(cy+(y2>>1) - fy)),
|
|
double(y2*(fx - cx-(x2>>1)))));
|
|
if(Angle < 0) Angle += 16*360;
|
|
paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, 16*180);// paint new painting
|
|
break;
|
|
case 5 :
|
|
State++;
|
|
paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, 16*180);// erase old painting
|
|
ArcLen = int(16.0*180.0/M_PI
|
|
* atan2(double(x2*(cy+(y2>>1) - fy)),
|
|
double(y2*(fx - cx-(x2>>1)))));
|
|
ArcLen -= Angle;
|
|
while(ArcLen < 0) ArcLen += 16*360;
|
|
paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, ArcLen);// paint new painting
|
|
break;
|
|
case 6 :
|
|
paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, ArcLen);// erase old painting
|
|
ArcLen = int(16.0*180.0/M_PI
|
|
* atan2(double(x2*(cy+(y2>>1) - fy)),
|
|
double(y2*(fx - cx-(x2>>1)))));
|
|
ArcLen -= Angle;
|
|
while(ArcLen <= 32) ArcLen += 16*360;
|
|
paintScale->PostPaintEvent(_Arc, cx, cy, x2, y2, Angle, ArcLen);// paint new painting
|
|
break;
|
|
}
|
|
|
|
|
|
// FIXME #warning p->setPen(Qt::SolidLine);
|
|
if(drawn)
|
|
p->PostPaintEvent(_Arc, x1+13, y1, 18, 12, 16*45, 16*200,true); // erase old cursor symbol
|
|
|
|
x1 = x;
|
|
y1 = y;
|
|
p->PostPaintEvent(_Arc, x1+13, y1, 18, 12, 16*45, 16*200,true); // paint new cursor symbol
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
bool EllipseArc::MousePressing()
|
|
{
|
|
State++;
|
|
switch(State) {
|
|
case 1 :
|
|
cx = x2;
|
|
cy = y2; // first corner is determined
|
|
x2 = y2 = Angle = ArcLen = 0;
|
|
break;
|
|
case 7 :
|
|
State = 0;
|
|
return true; // painting is ready
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Checks if the coordinates x/y point to the painting.
|
|
bool EllipseArc::getSelected(float fX, float fY, float w)
|
|
{
|
|
float fX2 = float(x2)/2.0;
|
|
float fY2 = float(y2)/2.0;
|
|
fX -= float(cx) + fX2;
|
|
fY -= float(cy) + fY2;
|
|
|
|
int Phase =
|
|
int(16.0*180.0/M_PI *
|
|
atan2(-double(x2)*double(fY), double(y2)*double(fX)));
|
|
Phase -= Angle;
|
|
while(Phase < 0) Phase += 16*360;
|
|
|
|
if(Phase > ArcLen)
|
|
return false;
|
|
|
|
float a1 = fX / (fX2 - w); a1 *= a1;
|
|
float a2 = fX / (fX2 + w); a2 *= a2;
|
|
float b1 = fY / (fY2 - w); b1 *= b1;
|
|
float b2 = fY / (fY2 + w); b2 *= b2;
|
|
|
|
if(a1+b1 < 1.0) return false;
|
|
if(a2+b2 > 1.0) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Rotates around the center.
|
|
void EllipseArc::rotate()
|
|
{
|
|
cy += (y2-x2) >> 1;
|
|
cx += (x2-y2) >> 1;
|
|
int tmp = x2;
|
|
x2 = y2;
|
|
y2 = tmp;
|
|
|
|
Angle += 16*90;
|
|
if(Angle >= 16*360) Angle -= 16*360;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Mirrors about center line.
|
|
void EllipseArc::mirrorX()
|
|
{
|
|
Angle += ArcLen;
|
|
if(Angle >= 16*360) Angle -= 16*360;
|
|
|
|
if(Angle != 0) Angle = 16*360 - Angle;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Mirrors about center line.
|
|
void EllipseArc::mirrorY()
|
|
{
|
|
Angle += ArcLen;
|
|
if(Angle >= 16*360) Angle -= 16*360;
|
|
|
|
if(Angle <= 16*180) Angle = 16*180 - Angle;
|
|
else Angle = 16*540 - Angle;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Calls the property dialog for the painting and changes them accordingly.
|
|
// If there were changes, it returns 'true'.
|
|
bool EllipseArc::Dialog()
|
|
{
|
|
bool changed = false;
|
|
|
|
FillDialog *d = new FillDialog(QObject::tr("Edit Arc Properties"), false);
|
|
d->ColorButt->setPaletteBackgroundColor(Pen.color());
|
|
d->LineWidth->setText(QString::number(Pen.width()));
|
|
d->StyleBox->setCurrentItem(Pen.style()-1);
|
|
|
|
if(d->exec() == QDialog::Rejected) {
|
|
delete d;
|
|
return false;
|
|
}
|
|
|
|
if(Pen.color() != d->ColorButt->paletteBackgroundColor()) {
|
|
Pen.setColor(d->ColorButt->paletteBackgroundColor());
|
|
changed = true;
|
|
}
|
|
if(Pen.width() != d->LineWidth->text().toInt()) {
|
|
Pen.setWidth(d->LineWidth->text().toInt());
|
|
changed = true;
|
|
}
|
|
if(Pen.style() != (Qt::PenStyle)(d->StyleBox->currentItem()+1)) {
|
|
Pen.setStyle((Qt::PenStyle)(d->StyleBox->currentItem()+1));
|
|
changed = true;
|
|
}
|
|
|
|
delete d;
|
|
return changed;
|
|
}
|