Касательность окружностей и линии с окружностью
This commit is contained in:
127
Canvas.cpp
127
Canvas.cpp
@@ -1,6 +1,4 @@
|
|||||||
#include "Canvas.h"
|
#include "Canvas.h"
|
||||||
#define WIDGET_POSITION event->pos()
|
|
||||||
#define UCS_POSITION screenToLogical(WIDGET_POSITION)
|
|
||||||
|
|
||||||
std::set<Point*> groups;
|
std::set<Point*> groups;
|
||||||
|
|
||||||
@@ -93,12 +91,12 @@ void Canvas::zoomReset()
|
|||||||
Curve* Canvas::findAt(QPointF& pos, qreal tolerance)
|
Curve* Canvas::findAt(QPointF& pos, qreal tolerance)
|
||||||
{
|
{
|
||||||
for (Curve* curve : curves) {
|
for (Curve* curve : curves) {
|
||||||
if (Line* line = dynamic_cast<Line*>(curve)) {
|
if (Line* line = CURVE_AS_LINE(curve)) {
|
||||||
if (line->contains(pos, tolerance)) {
|
if (line->contains(pos, tolerance)) {
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Circle* circle = dynamic_cast<Circle*>(curve)) {
|
else if (Circle* circle = CURVE_AS_CIRCLE(curve)) {
|
||||||
QPointF center(*circle->center.x, *circle->center.y);
|
QPointF center(*circle->center.x, *circle->center.y);
|
||||||
double radius = *circle->rad;
|
double radius = *circle->rad;
|
||||||
|
|
||||||
@@ -117,7 +115,7 @@ Point* Canvas::findPointAt(QPointF pos, qreal tolerance)
|
|||||||
Point* temp = nullptr;
|
Point* temp = nullptr;
|
||||||
|
|
||||||
for (Curve* curve : curves) {
|
for (Curve* curve : curves) {
|
||||||
if (Line* line = dynamic_cast<Line*>(curve)) {
|
if (Line* line = CURVE_AS_LINE(curve)) {
|
||||||
QPointF p1(*line->p1.x, *line->p1.y);
|
QPointF p1(*line->p1.x, *line->p1.y);
|
||||||
QPointF p2(*line->p2.x, *line->p2.y);
|
QPointF p2(*line->p2.x, *line->p2.y);
|
||||||
|
|
||||||
@@ -126,7 +124,7 @@ Point* Canvas::findPointAt(QPointF pos, qreal tolerance)
|
|||||||
if (dist_P2P(p2, pos) <= tolerance)
|
if (dist_P2P(p2, pos) <= tolerance)
|
||||||
temp = line->end_ref;
|
temp = line->end_ref;
|
||||||
}
|
}
|
||||||
else if (Circle* circle = dynamic_cast<Circle*>(curve)) {
|
else if (Circle* circle = CURVE_AS_CIRCLE(curve)) {
|
||||||
QPointF center(circle->center.get_X(), circle->center.get_Y());
|
QPointF center(circle->center.get_X(), circle->center.get_Y());
|
||||||
if (dist_P2P(center, pos) <= tolerance)
|
if (dist_P2P(center, pos) <= tolerance)
|
||||||
temp = circle->center_ref;
|
temp = circle->center_ref;
|
||||||
@@ -174,6 +172,11 @@ bool Canvas::areAlreadyPerpendicular(Line* line1, Line* line2)
|
|||||||
return perpendicularPairs.count(makeOrderedPair<LinePair>(line1, line2));
|
return perpendicularPairs.count(makeOrderedPair<LinePair>(line1, line2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Canvas::areAlreadyTangent(Curve* curve1, Curve* curve2)
|
||||||
|
{
|
||||||
|
return tangentPairs.count(makeOrderedPair<CurvePair>(curve1, curve2));
|
||||||
|
}
|
||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
// Методы работы с ограничениями
|
// Методы работы с ограничениями
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
@@ -248,7 +251,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Line* found = dynamic_cast<Line*>(findAt(scene));
|
Line* found = CURVE_AS_LINE(findAt(scene));
|
||||||
if (found) {
|
if (found) {
|
||||||
draggedCurve = found;
|
draggedCurve = found;
|
||||||
QPointF lineCenter(
|
QPointF lineCenter(
|
||||||
@@ -259,7 +262,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Circle* found_circle = dynamic_cast<Circle*>(findAt(scene));
|
Circle* found_circle = CURVE_AS_CIRCLE(findAt(scene));
|
||||||
if (found_circle) {
|
if (found_circle) {
|
||||||
draggedCurve = found_circle;
|
draggedCurve = found_circle;
|
||||||
QPointF center(*found_circle->center.x, *found_circle->center.y);
|
QPointF center(*found_circle->center.x, *found_circle->center.y);
|
||||||
@@ -270,7 +273,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
|
|
||||||
// ====================== Режим Horizontal/Vertical ======================
|
// ====================== Режим Horizontal/Vertical ======================
|
||||||
else if (mode == Mode::Horizontal || mode == Mode::Vertical) {
|
else if (mode == Mode::Horizontal || mode == Mode::Vertical) {
|
||||||
Line* found = dynamic_cast<Line*>(findAt(scene));
|
Line* found = CURVE_AS_LINE(findAt(scene));
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
// Проверка: если линия уже вертикальна, нельзя сделать её горизонтальной
|
// Проверка: если линия уже вертикальна, нельзя сделать её горизонтальной
|
||||||
@@ -417,7 +420,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
}
|
}
|
||||||
// ====================== Режим Parallel: задание параллельности ======================
|
// ====================== Режим Parallel: задание параллельности ======================
|
||||||
else if (mode == Mode::Parallel) {
|
else if (mode == Mode::Parallel) {
|
||||||
Line* found = dynamic_cast<Line*>(findAt(scene));
|
Line* found = CURVE_AS_LINE(findAt(scene));
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
current_line = nullptr;
|
current_line = nullptr;
|
||||||
@@ -496,7 +499,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
Line* l2 = nullptr;
|
Line* l2 = nullptr;
|
||||||
|
|
||||||
for (Curve* curve : curves) {
|
for (Curve* curve : curves) {
|
||||||
if (Line* l = dynamic_cast<Line*>(curve)) {
|
if (Line* l = CURVE_AS_LINE(curve)) {
|
||||||
if (l->start_ref == firstPoint || l->end_ref == firstPoint)
|
if (l->start_ref == firstPoint || l->end_ref == firstPoint)
|
||||||
l1 = l;
|
l1 = l;
|
||||||
if (l->start_ref == clickedPoint || l->end_ref == clickedPoint)
|
if (l->start_ref == clickedPoint || l->end_ref == clickedPoint)
|
||||||
@@ -527,7 +530,7 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (mode == Mode::Perpendicular) {
|
else if (mode == Mode::Perpendicular) {
|
||||||
Line* found = dynamic_cast<Line*>(findAt(scene));
|
Line* found = CURVE_AS_LINE(findAt(scene));
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
current_line = nullptr;
|
current_line = nullptr;
|
||||||
@@ -572,6 +575,96 @@ void Canvas::mousePressEvent(QMouseEvent* event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (mode == Mode::Tangent) {
|
||||||
|
// Ищем любой объект под курсором: линия или окружность
|
||||||
|
Curve* selected = findAt(scene);
|
||||||
|
|
||||||
|
if (!selected) {
|
||||||
|
current_curve = nullptr;
|
||||||
|
update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если кликнули по уже выбранному объекту — сброс
|
||||||
|
if (current_curve && selected == current_curve) {
|
||||||
|
current_curve = nullptr;
|
||||||
|
update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Первый выбор
|
||||||
|
if (!current_curve) {
|
||||||
|
current_curve = selected;
|
||||||
|
update(); // подсветим выбранный объект
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Второй выбор — теперь у нас два объекта
|
||||||
|
Curve* first = current_curve;
|
||||||
|
Curve* second = selected;
|
||||||
|
|
||||||
|
// Проверка на уже существующее ограничение касательности
|
||||||
|
if (areAlreadyTangent(first, second)) {
|
||||||
|
QMessageBox::warning(this, "Ошибка",
|
||||||
|
"Эти объекты уже касательны!", QMessageBox::Ok);
|
||||||
|
current_curve = nullptr;
|
||||||
|
update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString message;
|
||||||
|
bool constraintAdded = false;
|
||||||
|
|
||||||
|
// Вариант 1: Линия → Окружность
|
||||||
|
if (Line* line = dynamic_cast<Line*>(first)) {
|
||||||
|
if (Circle* circle = dynamic_cast<Circle*>(second)) {
|
||||||
|
message = "Выбрано: Линия → Окружность\nПрименено касание линии к окружности.";
|
||||||
|
sys.addConstraintTangent(*line, *circle, constraints_count++);
|
||||||
|
constraintAdded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Вариант 2: Окружность → Линия
|
||||||
|
else if (Circle* circle = dynamic_cast<Circle*>(first)) {
|
||||||
|
if (Line* line = dynamic_cast<Line*>(second)) {
|
||||||
|
message = "Выбрано: Окружность → Линия\nПрименено касание линии к окружности.";
|
||||||
|
sys.addConstraintTangent(*line, *circle, constraints_count++); // порядок Line, Circle
|
||||||
|
constraintAdded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Вариант 3: Окружность → Окружность
|
||||||
|
if (Circle* c1 = dynamic_cast<Circle*>(first)) {
|
||||||
|
if (Circle* c2 = dynamic_cast<Circle*>(second)) {
|
||||||
|
message = "Выбрано: Окружность → Окружность\nПрименено касание двух окружностей.";
|
||||||
|
sys.addConstraintTangent(*c1, *c2, constraints_count++);
|
||||||
|
constraintAdded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если комбинация недопустима
|
||||||
|
if (!constraintAdded) {
|
||||||
|
message = "Недопустимая комбинация объектов для касания!\n"
|
||||||
|
"Поддерживаются: линия-окружность или окружность-окружность.";
|
||||||
|
QMessageBox::warning(this, "Ошибка", message, QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Сохраняем информацию об ограничении (для undo и удаления)
|
||||||
|
auto orderedPair = makeOrderedPair<CurvePair>(first, second);
|
||||||
|
tangentPairs.insert(orderedPair);
|
||||||
|
|
||||||
|
C_Info[constraints_count - 1] = { Mode::Tangent, orderedPair };
|
||||||
|
|
||||||
|
QMessageBox::information(this, "Касание применено", message, QMessageBox::Ok);
|
||||||
|
|
||||||
|
after_constraint = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Сброс режима и выделения
|
||||||
|
current_curve = nullptr;
|
||||||
|
mode = Mode::None;
|
||||||
|
solve_for_canvas();
|
||||||
|
update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::mouseMoveEvent(QMouseEvent* event)
|
void Canvas::mouseMoveEvent(QMouseEvent* event)
|
||||||
@@ -598,7 +691,7 @@ void Canvas::mouseMoveEvent(QMouseEvent* event)
|
|||||||
|
|
||||||
// ====================== Перемещение линии ======================
|
// ====================== Перемещение линии ======================
|
||||||
else if (draggedCurve) {
|
else if (draggedCurve) {
|
||||||
if (Line* draggedLine = dynamic_cast<Line*>(draggedCurve)) {
|
if (Line* draggedLine = CURVE_AS_LINE(draggedCurve)) {
|
||||||
QPointF newCenter = UCS_POSITION - dragOffset;
|
QPointF newCenter = UCS_POSITION - dragOffset;
|
||||||
QPointF oldCenter(
|
QPointF oldCenter(
|
||||||
(*draggedLine->p1.x + *draggedLine->p2.x) / 2.0,
|
(*draggedLine->p1.x + *draggedLine->p2.x) / 2.0,
|
||||||
@@ -627,7 +720,7 @@ void Canvas::mouseMoveEvent(QMouseEvent* event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Circle* circle = dynamic_cast<Circle*>(draggedCurve)) {
|
else if (Circle* circle = CURVE_AS_CIRCLE(draggedCurve)) {
|
||||||
QPointF newCenter = UCS_POSITION - dragOffset;
|
QPointF newCenter = UCS_POSITION - dragOffset;
|
||||||
*circle->center.x = newCenter.x();
|
*circle->center.x = newCenter.x();
|
||||||
*circle->center.y = newCenter.y();
|
*circle->center.y = newCenter.y();
|
||||||
@@ -687,7 +780,7 @@ void Canvas::paintEvent(QPaintEvent* event)
|
|||||||
// ====================== Отрисовка линий ======================
|
// ====================== Отрисовка линий ======================
|
||||||
|
|
||||||
for (Curve* curve : curves) {
|
for (Curve* curve : curves) {
|
||||||
if (Line* line = dynamic_cast<Line*>(curve)) {
|
if (Line* line = CURVE_AS_LINE(curve)) {
|
||||||
bool isSelected = (mode == Mode::Parallel && line == current_line);
|
bool isSelected = (mode == Mode::Parallel && line == current_line);
|
||||||
|
|
||||||
// Настройка пера для линии
|
// Настройка пера для линии
|
||||||
@@ -708,7 +801,7 @@ void Canvas::paintEvent(QPaintEvent* event)
|
|||||||
p.drawEllipse(QPointF(*line->p1.x, *line->p1.y), 5, 5);
|
p.drawEllipse(QPointF(*line->p1.x, *line->p1.y), 5, 5);
|
||||||
p.drawEllipse(QPointF(*line->p2.x, *line->p2.y), 5, 5);
|
p.drawEllipse(QPointF(*line->p2.x, *line->p2.y), 5, 5);
|
||||||
}
|
}
|
||||||
else if (Circle* circle = dynamic_cast<Circle*>(curve)) {
|
else if (Circle* circle = CURVE_AS_CIRCLE(curve)) {
|
||||||
p.setPen(QPen(Qt::black, 2));
|
p.setPen(QPen(Qt::black, 2));
|
||||||
p.setBrush(Qt::NoBrush);
|
p.setBrush(Qt::NoBrush);
|
||||||
|
|
||||||
@@ -894,7 +987,7 @@ void Canvas::solve_for_canvas()
|
|||||||
else {
|
else {
|
||||||
sys.applySolution();
|
sys.applySolution();
|
||||||
for (Curve* curve : curves) {
|
for (Curve* curve : curves) {
|
||||||
if (Line* line = dynamic_cast<Line*>(curve)) {
|
if (Line* line = CURVE_AS_LINE(curve)) {
|
||||||
if (abs(*line->p1.x - *line->p2.x) < EPS && abs(*line->p1.y - *line->p2.y) < EPS && after_constraint) {
|
if (abs(*line->p1.x - *line->p2.x) < EPS && abs(*line->p1.y - *line->p2.y) < EPS && after_constraint) {
|
||||||
sys.undoSolution();
|
sys.undoSolution();
|
||||||
flag = true;
|
flag = true;
|
||||||
|
|||||||
16
Canvas.h
16
Canvas.h
@@ -3,6 +3,11 @@
|
|||||||
constexpr auto EPS = 1e-9;
|
constexpr auto EPS = 1e-9;
|
||||||
constexpr auto ZOOM_STEP = 0.05;
|
constexpr auto ZOOM_STEP = 0.05;
|
||||||
|
|
||||||
|
#define WIDGET_POSITION event->pos()
|
||||||
|
#define UCS_POSITION screenToLogical(WIDGET_POSITION)
|
||||||
|
#define CURVE_AS_LINE(CURVE) dynamic_cast<Line*>(CURVE)
|
||||||
|
#define CURVE_AS_CIRCLE(CURVE) dynamic_cast<Circle*>(CURVE)
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QPointF>
|
#include <QPointF>
|
||||||
@@ -35,7 +40,8 @@ enum class Mode : int
|
|||||||
Horizontal = 4, ///< Режим задания горизонтальности
|
Horizontal = 4, ///< Режим задания горизонтальности
|
||||||
Vertical = 5, ///< Режим задания вертикальности
|
Vertical = 5, ///< Режим задания вертикальности
|
||||||
Perpendicular = 6, ///< Режим задания перпендикулярности
|
Perpendicular = 6, ///< Режим задания перпендикулярности
|
||||||
DrawingCircle = 7 ///< Режим рисования окружности
|
DrawingCircle = 7, ///< Режим рисования окружности
|
||||||
|
Tangent = 8 //< Режим задания касательности
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Удобный тип для хранения пары параллельных линий (порядок не важен)
|
/// Удобный тип для хранения пары параллельных линий (порядок не важен)
|
||||||
@@ -44,6 +50,8 @@ using LinePair = std::pair<Line*, Line*>;
|
|||||||
/// Удобный тип для хранения пары точек (порядок не важен)
|
/// Удобный тип для хранения пары точек (порядок не важен)
|
||||||
using PointPair = std::pair<Point*, Point*>;
|
using PointPair = std::pair<Point*, Point*>;
|
||||||
|
|
||||||
|
using CurvePair = std::pair<Curve*, Curve*>;
|
||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
// Основной класс холста
|
// Основной класс холста
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
@@ -226,6 +234,8 @@ private:
|
|||||||
*/
|
*/
|
||||||
bool areAlreadyPerpendicular(Line* line1, Line* line2);
|
bool areAlreadyPerpendicular(Line* line1, Line* line2);
|
||||||
|
|
||||||
|
bool areAlreadyTangent(Curve* curve1, Curve* curve2);
|
||||||
|
|
||||||
// ====================== Методы работы с ограничениями ======================
|
// ====================== Методы работы с ограничениями ======================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -263,6 +273,7 @@ private:
|
|||||||
// ====================== Коллекции ограничений ======================
|
// ====================== Коллекции ограничений ======================
|
||||||
std::set<LinePair> parallelPairs; ///< Пары параллельных линий
|
std::set<LinePair> parallelPairs; ///< Пары параллельных линий
|
||||||
std::set<LinePair> perpendicularPairs; ///< Пары перпендикулярных линий
|
std::set<LinePair> perpendicularPairs; ///< Пары перпендикулярных линий
|
||||||
|
std::set<CurvePair> tangentPairs;
|
||||||
std::set<PointPair> P2Ppairs; ///< Пары совпадающих точек
|
std::set<PointPair> P2Ppairs; ///< Пары совпадающих точек
|
||||||
std::set<PointPair> HORIZ_pairs; ///< Пары точек горизонтальных линий
|
std::set<PointPair> HORIZ_pairs; ///< Пары точек горизонтальных линий
|
||||||
std::set<PointPair> VERT_pairs; ///< Пары точек вертикальных линий
|
std::set<PointPair> VERT_pairs; ///< Пары точек вертикальных линий
|
||||||
@@ -270,6 +281,7 @@ private:
|
|||||||
// ====================== Временные данные для режимов ======================
|
// ====================== Временные данные для режимов ======================
|
||||||
Line* current_line{ nullptr }; ///< Текущая линия в режимах рисования/параллельности
|
Line* current_line{ nullptr }; ///< Текущая линия в режимах рисования/параллельности
|
||||||
Circle* current_circle{ nullptr };
|
Circle* current_circle{ nullptr };
|
||||||
|
Curve* current_curve { nullptr };
|
||||||
Point* firstPoint{ nullptr }; ///< Первая точка в режиме совпадения
|
Point* firstPoint{ nullptr }; ///< Первая точка в режиме совпадения
|
||||||
Mode mode{ Mode::None }; ///< Текущий режим работы
|
Mode mode{ Mode::None }; ///< Текущий режим работы
|
||||||
|
|
||||||
@@ -287,7 +299,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
struct ConstraintInfo {
|
struct ConstraintInfo {
|
||||||
Mode mode; ///< Тип ограничения
|
Mode mode; ///< Тип ограничения
|
||||||
std::variant<LinePair, PointPair> data; ///< Данные ограничения
|
std::variant<LinePair, PointPair, CurvePair> data; ///< Данные ограничения
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<int, ConstraintInfo> C_Info; ///< Карта информации об ограничениях
|
std::map<int, ConstraintInfo> C_Info; ///< Карта информации об ограничениях
|
||||||
|
|||||||
@@ -49,3 +49,9 @@ void DRAWer_2_0::on_Circle_Button_clicked()
|
|||||||
ui.widget->changeMode(Mode::DrawingCircle);
|
ui.widget->changeMode(Mode::DrawingCircle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DRAWer_2_0::on_Tangent_Button_clicked()
|
||||||
|
{
|
||||||
|
ui.widget->changeMode(Mode::Tangent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ private slots:
|
|||||||
|
|
||||||
void on_Circle_Button_clicked();
|
void on_Circle_Button_clicked();
|
||||||
|
|
||||||
|
void on_Tangent_Button_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::DRAWer_2_0Class ui;
|
Ui::DRAWer_2_0Class ui;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -122,6 +122,13 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
|
<widget class="QPushButton" name="Tangent_Button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Tangent</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
<widget class="QPushButton" name="Vertical_Button">
|
<widget class="QPushButton" name="Vertical_Button">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Vertical</string>
|
<string>Vertical</string>
|
||||||
@@ -170,7 +177,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>776</width>
|
<width>776</width>
|
||||||
<height>22</height>
|
<height>21</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
|||||||
Reference in New Issue
Block a user