circle.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* circle.cpp - draw circle tool
  2. * Copyright (C) 2017-2018 caryoscelus
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include <QGraphicsEllipseItem>
  18. #include <core/node/abstract_value.h>
  19. #include <core/node/abstract_node.h>
  20. #include <core/node/make.h>
  21. #include <core/node_info/node_info.h>
  22. #include <geom_helpers/circle.h>
  23. #include <util/pen.h>
  24. #include "shape.h"
  25. namespace rainynite::studio {
  26. namespace tools {
  27. class Circle : public Shape {
  28. public:
  29. string icon() const override {
  30. return "draw-circle";
  31. }
  32. string name() const override {
  33. return global_name();
  34. }
  35. static string global_name() {
  36. return "Circle";
  37. }
  38. protected:
  39. bool mouse_press(QPoint const& pos) override {
  40. circle_center = pos;
  41. preview.reset(get_scene()->addEllipse({}, pens::cosmetic_dash()));
  42. return is_drawing = true;
  43. }
  44. bool mouse_move(QPoint const& pos) override {
  45. if (is_drawing) {
  46. preview->setRect(get_rect(
  47. get_canvas()->mapToScene(circle_center),
  48. get_canvas()->mapToScene(pos)
  49. ));
  50. }
  51. return is_drawing;
  52. }
  53. bool mouse_release(QPoint const& pos) override {
  54. if (is_drawing) {
  55. circle_drawn(
  56. get_canvas()->mapToScene(circle_center),
  57. get_canvas()->mapToScene(pos)
  58. );
  59. get_scene()->removeItem(preview.get());
  60. preview.reset();
  61. is_drawing = false;
  62. return true;
  63. }
  64. return false;
  65. }
  66. private:
  67. void circle_drawn(QPointF a, QPointF b) {
  68. using namespace core;
  69. auto circle_node = make_node_with_name_as<AbstractNode>("CirclePR");
  70. circle_node->set_property("position", make_value<Geom::Point>(a.x(), a.y()));
  71. auto radius = get_radius(a, b);
  72. circle_node->set_property("radius", make_value<double>(radius));
  73. write_shape(abstract_value_cast(circle_node));
  74. }
  75. double get_radius(QPointF const& a, QPointF const& b) {
  76. auto vec = a-b;
  77. return Geom::Point(vec.x(), vec.y()).length();
  78. }
  79. QRectF get_rect(QPointF const& center, QPointF const& end) {
  80. auto radius = get_radius(center, end);
  81. return {
  82. center-QPointF(radius, radius),
  83. center+QPointF(radius, radius)
  84. };
  85. }
  86. private:
  87. bool is_drawing = false;
  88. QPoint circle_center;
  89. observer_ptr<QGraphicsEllipseItem> preview;
  90. };
  91. } // namespace tools
  92. REGISTER_CANVAS_TOOL(tools::Circle, Canvas, 0x11);
  93. } // namespace rainynite::studio