mirror of https://github.com/KLayout/klayout.git
WIP: better highlighting of snap objects.
This commit is contained in:
parent
e42136ee27
commit
307c10f184
|
|
@ -61,8 +61,7 @@ ac_from_buttons (unsigned int buttons)
|
|||
// -------------------------------------------------------------
|
||||
|
||||
Service::Service (db::Manager *manager, lay::LayoutView *view, db::ShapeIterator::flags_type flags)
|
||||
: lay::ViewService (view->view_object_widget ()),
|
||||
lay::Editable (view),
|
||||
: lay::EditorServiceBase (view),
|
||||
lay::Plugin (view),
|
||||
db::Object (manager),
|
||||
mp_view (view),
|
||||
|
|
@ -83,8 +82,7 @@ Service::Service (db::Manager *manager, lay::LayoutView *view, db::ShapeIterator
|
|||
}
|
||||
|
||||
Service::Service (db::Manager *manager, lay::LayoutView *view)
|
||||
: lay::ViewService (view->view_object_widget ()),
|
||||
lay::Editable (view),
|
||||
: lay::EditorServiceBase (view),
|
||||
lay::Plugin (view),
|
||||
db::Object (manager),
|
||||
mp_view (view),
|
||||
|
|
@ -116,7 +114,6 @@ Service::~Service ()
|
|||
}
|
||||
m_edit_markers.clear ();
|
||||
|
||||
reset_mouse_cursor ();
|
||||
clear_transient_selection ();
|
||||
}
|
||||
|
||||
|
|
@ -480,71 +477,6 @@ Service::selection_bbox ()
|
|||
return box;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class MouseCursorViewObject
|
||||
: public lay::ViewObject
|
||||
{
|
||||
public:
|
||||
MouseCursorViewObject (lay::ViewObjectWidget *widget, const db::DPoint &pt)
|
||||
: lay::ViewObject (widget, false), m_pt (pt)
|
||||
{ }
|
||||
|
||||
virtual void render (const lay::Viewport &vp, lay::ViewObjectCanvas &canvas)
|
||||
{
|
||||
int dither_pattern = 0; // solid
|
||||
int lw = int (0.5 + 1.0 / canvas.resolution ());
|
||||
|
||||
std::vector <lay::ViewOp> ops;
|
||||
ops.resize (1);
|
||||
ops[0] = lay::ViewOp (canvas.foreground_color ().rgb (), lay::ViewOp::Copy, 0, (unsigned int) dither_pattern, 0, lay::ViewOp::Rect, lw, 0);
|
||||
lay::CanvasPlane *plane = canvas.plane (ops);
|
||||
|
||||
lay::Renderer &r = canvas.renderer ();
|
||||
|
||||
double rad = 4.0 / canvas.resolution () / vp.trans ().mag ();
|
||||
|
||||
const size_t num_pts = 16;
|
||||
db::DPoint pts [num_pts];
|
||||
for (size_t i = 0; i < num_pts; ++i) {
|
||||
double x = rad * cos (M_PI * 2.0 * double (i) / double (num_pts));
|
||||
double y = rad * sin (M_PI * 2.0 * double (i) / double (num_pts));
|
||||
pts [i] = m_pt + db::DVector (x, y);
|
||||
}
|
||||
db::DPolygon circle;
|
||||
circle.assign_hull (pts, pts + num_pts);
|
||||
|
||||
r.draw (circle, vp.trans (), 0, plane, 0, 0);
|
||||
|
||||
r.draw (db::DEdge (m_pt + db::DVector (0, rad * 0.5), m_pt + db::DVector (0, rad * 4)), vp.trans (), 0, plane, 0, 0);
|
||||
r.draw (db::DEdge (m_pt + db::DVector (rad * 0.5, 0), m_pt + db::DVector (rad * 4, 0)), vp.trans (), 0, plane, 0, 0);
|
||||
r.draw (db::DEdge (m_pt + db::DVector (0, -rad * 0.5), m_pt + db::DVector (0, -rad * 4)), vp.trans (), 0, plane, 0, 0);
|
||||
r.draw (db::DEdge (m_pt + db::DVector (-rad * 0.5, 0), m_pt + db::DVector (-rad * 4, 0)), vp.trans (), 0, plane, 0, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
db::DPoint m_pt;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
Service::set_mouse_cursor (const db::DPoint &pt)
|
||||
{
|
||||
reset_mouse_cursor ();
|
||||
m_mouse_cursor_markers.push_back (new MouseCursorViewObject (widget (), pt));
|
||||
}
|
||||
|
||||
void
|
||||
Service::reset_mouse_cursor ()
|
||||
{
|
||||
for (std::vector<lay::ViewObject *>::iterator r = m_mouse_cursor_markers.begin (); r != m_mouse_cursor_markers.end (); ++r) {
|
||||
delete *r;
|
||||
}
|
||||
m_mouse_cursor_markers.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
Service::set_edit_marker (lay::ViewObject *edit_marker)
|
||||
{
|
||||
|
|
@ -881,7 +813,7 @@ Service::activated ()
|
|||
void
|
||||
Service::deactivated ()
|
||||
{
|
||||
reset_mouse_cursor ();
|
||||
clear_mouse_cursors ();
|
||||
|
||||
edit_cancel ();
|
||||
|
||||
|
|
|
|||
|
|
@ -27,9 +27,8 @@
|
|||
|
||||
#include "edtCommon.h"
|
||||
|
||||
#include "layEditable.h"
|
||||
#include "layEditorServiceBase.h"
|
||||
#include "layPlugin.h"
|
||||
#include "layViewObject.h"
|
||||
#include "layMarker.h"
|
||||
#include "laySnap.h"
|
||||
#include "layObjectInstPath.h"
|
||||
|
|
@ -72,8 +71,7 @@ std::map<std::string, tl::Variant> pcell_parameters_from_string (const std::stri
|
|||
// -------------------------------------------------------------
|
||||
|
||||
class EDT_PUBLIC Service
|
||||
: public lay::ViewService,
|
||||
public lay::Editable,
|
||||
: public lay::EditorServiceBase,
|
||||
public lay::Plugin,
|
||||
public db::Object
|
||||
{
|
||||
|
|
@ -458,16 +456,6 @@ protected:
|
|||
*/
|
||||
virtual void service_configuration_changed ();
|
||||
|
||||
/**
|
||||
* @brief Sets the mouse cursor to the given point
|
||||
*/
|
||||
void set_mouse_cursor (const db::DPoint &pt);
|
||||
|
||||
/**
|
||||
* @brief Resets the mouse cursor
|
||||
*/
|
||||
void reset_mouse_cursor ();
|
||||
|
||||
/**
|
||||
* @brief Install a marker for representing the edited object
|
||||
*
|
||||
|
|
@ -578,9 +566,6 @@ private:
|
|||
// The marker representing the object to be edited
|
||||
std::vector<lay::ViewObject *> m_edit_markers;
|
||||
|
||||
// The marker representing the mouse cursor
|
||||
std::vector<lay::ViewObject *> m_mouse_cursor_markers;
|
||||
|
||||
// True, if editing is in progress.
|
||||
bool m_editing;
|
||||
|
||||
|
|
|
|||
|
|
@ -417,14 +417,23 @@ void
|
|||
PolygonService::do_mouse_move_inactive (const db::DPoint &p)
|
||||
{
|
||||
lay::PointSnapToObjectResult snap_details = snap2_details (p);
|
||||
set_mouse_cursor (snap_details.snapped_point);
|
||||
|
||||
clear_mouse_cursors ();
|
||||
|
||||
add_mouse_cursor (snap_details.snapped_point,
|
||||
snap_details.object_snap == lay::PointSnapToObjectResult::ObjectVertex ||
|
||||
(snap_details.object_snap == lay::PointSnapToObjectResult::ObjectUnspecific && snap_details.object_ref.is_degenerate ()));
|
||||
|
||||
if (snap_details.object_snap == lay::PointSnapToObjectResult::ObjectEdge ||
|
||||
(snap_details.object_snap == lay::PointSnapToObjectResult::ObjectUnspecific && ! snap_details.object_ref.is_degenerate ())) {
|
||||
add_edge_marker (snap_details.object_ref, false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PolygonService::do_mouse_move (const db::DPoint &p)
|
||||
{
|
||||
lay::PointSnapToObjectResult snap_details = snap2_details (p);
|
||||
set_mouse_cursor (snap_details.snapped_point);
|
||||
do_mouse_move_inactive (p);
|
||||
|
||||
set_cursor (lay::Cursor::cross);
|
||||
if (m_points.size () >= 2) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,200 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "layEditorServiceBase.h"
|
||||
#include "layViewport.h"
|
||||
#include "layLayoutView.h"
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
template <size_t num_pts>
|
||||
static void
|
||||
make_circle (double r, const db::DPoint ¢er, db::DPolygon &poly, bool as_hole)
|
||||
{
|
||||
db::DPoint pts [num_pts];
|
||||
for (size_t i = 0; i < num_pts; ++i) {
|
||||
double x = r * cos (M_PI * 2.0 * double (i) / double (num_pts));
|
||||
double y = r * sin (M_PI * 2.0 * double (i) / double (num_pts));
|
||||
pts [i] = center + db::DVector (x, y);
|
||||
}
|
||||
|
||||
if (! as_hole) {
|
||||
poly.assign_hull (pts, pts + num_pts);
|
||||
} else {
|
||||
poly.insert_hole (pts, pts + num_pts);
|
||||
}
|
||||
}
|
||||
|
||||
class MouseCursorViewObject
|
||||
: public lay::ViewObject
|
||||
{
|
||||
public:
|
||||
MouseCursorViewObject (lay::ViewObjectWidget *widget, const db::DPoint &pt, bool solid)
|
||||
: lay::ViewObject (widget, false), m_pt (pt), m_solid (solid)
|
||||
{ }
|
||||
|
||||
virtual void render (const lay::Viewport &vp, lay::ViewObjectCanvas &canvas)
|
||||
{
|
||||
int dither_pattern = 0; // solid
|
||||
int cross_dither_pattern = 6; // dotted
|
||||
|
||||
int lw = int (0.5 + 1.0 / canvas.resolution ());
|
||||
|
||||
std::vector <lay::ViewOp> ops;
|
||||
ops.resize (1);
|
||||
ops[0] = lay::ViewOp (canvas.foreground_color ().rgb (), lay::ViewOp::Copy, 0, (unsigned int) dither_pattern, 0, lay::ViewOp::Rect, lw, 0);
|
||||
lay::CanvasPlane *plane = canvas.plane (ops);
|
||||
|
||||
ops[0] = lay::ViewOp (canvas.foreground_color ().rgb (), lay::ViewOp::Copy, 0, (unsigned int) cross_dither_pattern, 0, lay::ViewOp::Rect, lw, 0);
|
||||
lay::CanvasPlane *cross_plane = canvas.plane (ops);
|
||||
|
||||
lay::Renderer &r = canvas.renderer ();
|
||||
|
||||
double rad = 4.0 / canvas.resolution () / vp.trans ().mag ();
|
||||
|
||||
db::DPolygon c;
|
||||
if (! m_solid) {
|
||||
make_circle<size_t (16)> (rad, m_pt, c, false);
|
||||
r.draw (c, vp.trans (), 0, plane, 0, 0);
|
||||
} else {
|
||||
make_circle<size_t (16)> (rad * 2, m_pt, c, false);
|
||||
r.draw (c, vp.trans (), 0, plane, 0, 0);
|
||||
make_circle<size_t (16)> (rad, m_pt, c, false);
|
||||
r.draw (c, vp.trans (), 0, plane, 0, 0);
|
||||
}
|
||||
|
||||
r.draw (db::DEdge (m_pt + db::DVector (0, -rad * 4), m_pt + db::DVector (0, rad * 4)), vp.trans (), 0, cross_plane, 0, 0);
|
||||
r.draw (db::DEdge (m_pt + db::DVector (-rad * 4, 0), m_pt + db::DVector (rad * 4, 0)), vp.trans (), 0, cross_plane, 0, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
db::DPoint m_pt;
|
||||
bool m_solid;
|
||||
};
|
||||
|
||||
class EdgeMarkerViewObject
|
||||
: public lay::ViewObject
|
||||
{
|
||||
public:
|
||||
EdgeMarkerViewObject (lay::ViewObjectWidget *widget, const db::DEdge &edge, bool solid)
|
||||
: lay::ViewObject (widget, false), m_edge (edge), m_solid (solid)
|
||||
{ }
|
||||
|
||||
virtual void render (const lay::Viewport &vp, lay::ViewObjectCanvas &canvas)
|
||||
{
|
||||
if (m_edge.is_degenerate ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int dashed_style = 2;
|
||||
int solid_style = 0;
|
||||
|
||||
int lw = int (0.5 + 1.0 / canvas.resolution ());
|
||||
|
||||
std::vector <lay::ViewOp> ops;
|
||||
ops.resize (1);
|
||||
ops[0] = lay::ViewOp (canvas.foreground_color ().rgb (), lay::ViewOp::Copy, solid_style, 0, 0, lay::ViewOp::Rect, lw, 0);
|
||||
lay::CanvasPlane *arrow_plane = canvas.plane (ops);
|
||||
|
||||
ops[0] = lay::ViewOp (canvas.foreground_color ().rgb (), lay::ViewOp::Copy, m_solid ? solid_style : dashed_style, 1, 0, lay::ViewOp::Rect, lw, 0);
|
||||
lay::CanvasPlane *edge_plane = canvas.plane (ops);
|
||||
|
||||
lay::Renderer &r = canvas.renderer ();
|
||||
r.draw (m_edge, vp.trans (), 0, edge_plane, 0, 0);
|
||||
|
||||
double arrow_length = 12.0 / canvas.resolution () / vp.trans ().mag ();
|
||||
|
||||
double arrow_width_half = arrow_length * 0.25882; // sin(15 deg)
|
||||
db::DVector n = db::DVector (m_edge.dy (), -m_edge.dx ()) * (arrow_width_half / m_edge.length ());
|
||||
db::DVector d = db::DVector (m_edge.dx (), m_edge.dy ()) * (arrow_length / m_edge.length ());
|
||||
|
||||
if (m_edge.length () < 2 * arrow_length) {
|
||||
|
||||
r.draw (db::DEdge (m_edge.p1 () - n, m_edge.p1 () + n), vp.trans (), 0, arrow_plane, 0, 0);
|
||||
r.draw (db::DEdge (m_edge.p2 () - n, m_edge.p2 () + n), vp.trans (), 0, arrow_plane, 0, 0);
|
||||
|
||||
} else {
|
||||
|
||||
db::DPoint pts[3];
|
||||
db::DPolygon p;
|
||||
|
||||
pts[0] = m_edge.p1 ();
|
||||
pts[1] = m_edge.p1 () + d - n;
|
||||
pts[2] = m_edge.p1 () + d + n;
|
||||
|
||||
p.assign_hull (pts, pts + 3);
|
||||
r.draw (p, vp.trans (), 0, arrow_plane, 0, 0);
|
||||
|
||||
pts[0] = m_edge.p2 ();
|
||||
pts[1] = m_edge.p2 () - d + n;
|
||||
pts[2] = m_edge.p2 () - d - n;
|
||||
|
||||
p.assign_hull (pts, pts + 3);
|
||||
r.draw (p, vp.trans (), 0, arrow_plane, 0, 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
db::DEdge m_edge;
|
||||
bool m_solid;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
EditorServiceBase::EditorServiceBase (lay::LayoutView *view)
|
||||
: lay::ViewService (view->view_object_widget ()),
|
||||
lay::Editable (view)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
EditorServiceBase::~EditorServiceBase ()
|
||||
{
|
||||
clear_mouse_cursors ();
|
||||
}
|
||||
|
||||
void
|
||||
EditorServiceBase::add_mouse_cursor (const db::DPoint &pt, bool emphasize)
|
||||
{
|
||||
m_mouse_cursor_markers.push_back (new MouseCursorViewObject (widget (), pt, emphasize));
|
||||
}
|
||||
|
||||
void
|
||||
EditorServiceBase::add_edge_marker (const db::DEdge &e, bool emphasize)
|
||||
{
|
||||
m_mouse_cursor_markers.push_back (new EdgeMarkerViewObject (widget (), e, emphasize));
|
||||
}
|
||||
|
||||
void
|
||||
EditorServiceBase::clear_mouse_cursors ()
|
||||
{
|
||||
for (std::vector<lay::ViewObject *>::iterator r = m_mouse_cursor_markers.begin (); r != m_mouse_cursor_markers.end (); ++r) {
|
||||
delete *r;
|
||||
}
|
||||
m_mouse_cursor_markers.clear ();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 Matthias Koefferlein
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_layEditorServiceBase
|
||||
#define HDR_layEditorServiceBase
|
||||
|
||||
#include "laybasicCommon.h"
|
||||
#include "layEditable.h"
|
||||
#include "layViewObject.h"
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief A generic base class for an editor service
|
||||
*
|
||||
* This class offers common services such as a mouse cursor.
|
||||
*/
|
||||
class LAYBASIC_PUBLIC EditorServiceBase
|
||||
: public lay::ViewService,
|
||||
public lay::Editable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
EditorServiceBase (lay::LayoutView *view);
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~EditorServiceBase ();
|
||||
|
||||
/**
|
||||
* @brief Adds a mouse cursor to the given point
|
||||
*/
|
||||
void add_mouse_cursor (const db::DPoint &pt, bool emphasize = false);
|
||||
|
||||
/**
|
||||
* @brief Adds an edge marker for the given edge
|
||||
*/
|
||||
void add_edge_marker (const db::DEdge &e, bool emphasize);
|
||||
|
||||
/**
|
||||
* @brief Resets the mouse cursor
|
||||
*/
|
||||
void clear_mouse_cursors ();
|
||||
|
||||
private:
|
||||
// The marker representing the mouse cursor
|
||||
std::vector<lay::ViewObject *> m_mouse_cursor_markers;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -118,6 +118,7 @@ SOURCES = \
|
|||
layEditorOptionsFrame.cc \
|
||||
layEditorOptionsPage.cc \
|
||||
layEditorOptionsPages.cc \
|
||||
layEditorServiceBase.cc \
|
||||
layFileDialog.cc \
|
||||
layFinder.cc \
|
||||
layFixedFont.cc \
|
||||
|
|
@ -222,6 +223,7 @@ HEADERS = \
|
|||
layEditorOptionsFrame.h \
|
||||
layEditorOptionsPage.h \
|
||||
layEditorOptionsPages.h \
|
||||
layEditorServiceBase.h \
|
||||
layFileDialog.h \
|
||||
layFinder.h \
|
||||
layFixedFont.h \
|
||||
|
|
|
|||
Loading…
Reference in New Issue