mirror of https://github.com/KLayout/klayout.git
Transient mode for auto-measure ruler
This commit is contained in:
parent
4b7c117cfd
commit
9184bef6f8
|
|
@ -1056,8 +1056,18 @@ Service::Service (db::Manager *manager, lay::LayoutViewBase *view)
|
||||||
m_drawing (false), m_current (),
|
m_drawing (false), m_current (),
|
||||||
m_move_mode (MoveNone),
|
m_move_mode (MoveNone),
|
||||||
m_seg_index (0),
|
m_seg_index (0),
|
||||||
m_current_template (0)
|
m_current_template (0),
|
||||||
|
m_hover (false),
|
||||||
|
m_hover_wait (false),
|
||||||
|
m_hover_buttons (0),
|
||||||
|
m_mouse_in_window (false)
|
||||||
{
|
{
|
||||||
|
#if defined(HAVE_QT)
|
||||||
|
m_timer.setInterval (100 /*hover time*/);
|
||||||
|
m_timer.setSingleShot (true);
|
||||||
|
connect (&m_timer, SIGNAL (timeout ()), this, SLOT (timeout ()));
|
||||||
|
#endif
|
||||||
|
|
||||||
mp_view->annotations_changed_event.add (this, &Service::annotations_changed);
|
mp_view->annotations_changed_event.add (this, &Service::annotations_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1809,9 +1819,36 @@ Service::mouse_double_click_event (const db::DPoint & /*p*/, unsigned int button
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lay::TwoPointSnapToObjectResult
|
||||||
|
Service::auto_measure (const db::DPoint &p, lay::angle_constraint_type ac, const ant::Template &tpl)
|
||||||
|
{
|
||||||
|
// for auto-metric we need some cutline constraint - any or global won't do.
|
||||||
|
if (ac == lay::AC_Global) {
|
||||||
|
ac = tpl.angle_constraint ();
|
||||||
|
}
|
||||||
|
if (ac == lay::AC_Global) {
|
||||||
|
ac = m_snap_mode;
|
||||||
|
}
|
||||||
|
if (ac == lay::AC_Global) {
|
||||||
|
ac = lay::AC_Diagonal;
|
||||||
|
}
|
||||||
|
|
||||||
|
db::DVector g;
|
||||||
|
if (m_grid_snap) {
|
||||||
|
g = db::DVector (m_grid, m_grid);
|
||||||
|
}
|
||||||
|
|
||||||
|
double snap_range = ui ()->mouse_event_trans ().inverted ().ctrans (m_snap_range);
|
||||||
|
snap_range *= 0.5;
|
||||||
|
|
||||||
|
return lay::obj_snap2 (mp_view, p, g, ac, snap_range, snap_range * 1000.0);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
||||||
{
|
{
|
||||||
|
hover_reset ();
|
||||||
|
|
||||||
if (prio && (buttons & lay::LeftButton) != 0) {
|
if (prio && (buttons & lay::LeftButton) != 0) {
|
||||||
|
|
||||||
const ant::Template &tpl = current_template ();
|
const ant::Template &tpl = current_template ();
|
||||||
|
|
@ -1852,27 +1889,7 @@ Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio
|
||||||
|
|
||||||
} else if (tpl.mode () == ant::Template::RulerAutoMetric) {
|
} else if (tpl.mode () == ant::Template::RulerAutoMetric) {
|
||||||
|
|
||||||
// for auto-metric we need some cutline constraint - any or global won't do.
|
lay::TwoPointSnapToObjectResult ee = auto_measure (p, ac_from_buttons (buttons), tpl);
|
||||||
lay::angle_constraint_type ac = ac_from_buttons (buttons);
|
|
||||||
if (ac == lay::AC_Global) {
|
|
||||||
ac = tpl.angle_constraint ();
|
|
||||||
}
|
|
||||||
if (ac == lay::AC_Global) {
|
|
||||||
ac = m_snap_mode;
|
|
||||||
}
|
|
||||||
if (ac == lay::AC_Global) {
|
|
||||||
ac = lay::AC_Diagonal;
|
|
||||||
}
|
|
||||||
|
|
||||||
db::DVector g;
|
|
||||||
if (m_grid_snap) {
|
|
||||||
g = db::DVector (m_grid, m_grid);
|
|
||||||
}
|
|
||||||
|
|
||||||
double snap_range = ui ()->mouse_event_trans ().inverted ().ctrans (m_snap_range);
|
|
||||||
snap_range *= 0.5;
|
|
||||||
|
|
||||||
lay::TwoPointSnapToObjectResult ee = lay::obj_snap2 (mp_view, p, g, ac, snap_range, snap_range * 1000.0);
|
|
||||||
if (ee.any) {
|
if (ee.any) {
|
||||||
|
|
||||||
// begin the transaction
|
// begin the transaction
|
||||||
|
|
@ -1968,21 +1985,33 @@ Service::create_measure_ruler (const db::DPoint &pt, lay::angle_constraint_type
|
||||||
bool
|
bool
|
||||||
Service::mouse_move_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
Service::mouse_move_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
||||||
{
|
{
|
||||||
if (prio) {
|
if (! prio) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
lay::PointSnapToObjectResult snap_details;
|
if (! m_drawing && m_mouse_in_window && view ()->transient_selection_mode ()) {
|
||||||
if (m_drawing) {
|
|
||||||
snap_details = snap2_details (m_p1, p, mp_active_ruler->ruler (), ac_from_buttons (buttons));
|
|
||||||
} else {
|
|
||||||
const ant::Template &tpl = current_template ();
|
|
||||||
snap_details = snap1_details (p, m_obj_snap && tpl.snap ());
|
|
||||||
}
|
|
||||||
|
|
||||||
mouse_cursor_from_snap_details (snap_details);
|
// Restart hover timer
|
||||||
|
m_hover_wait = true;
|
||||||
|
#if defined(HAVE_QT)
|
||||||
|
m_timer.start ();
|
||||||
|
#endif
|
||||||
|
m_hover_point = p;
|
||||||
|
m_hover_buttons = buttons;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_drawing && prio) {
|
lay::PointSnapToObjectResult snap_details;
|
||||||
|
if (m_drawing) {
|
||||||
|
snap_details = snap2_details (m_p1, p, mp_active_ruler->ruler (), ac_from_buttons (buttons));
|
||||||
|
} else {
|
||||||
|
const ant::Template &tpl = current_template ();
|
||||||
|
snap_details = snap1_details (p, m_obj_snap && tpl.snap ());
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_cursor_from_snap_details (snap_details);
|
||||||
|
|
||||||
|
if (m_drawing) {
|
||||||
|
|
||||||
set_cursor (lay::Cursor::cross);
|
set_cursor (lay::Cursor::cross);
|
||||||
|
|
||||||
|
|
@ -2284,6 +2313,70 @@ Service::click_proximity (const db::DPoint &pos, lay::Editable::SelectionMode mo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Service::enter_event (bool /*prio*/)
|
||||||
|
{
|
||||||
|
m_mouse_in_window = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Service::leave_event (bool)
|
||||||
|
{
|
||||||
|
m_mouse_in_window = false;
|
||||||
|
hover_reset ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Service::hover_reset ()
|
||||||
|
{
|
||||||
|
if (m_hover_wait) {
|
||||||
|
#if defined(HAVE_QT)
|
||||||
|
m_timer.stop ();
|
||||||
|
#endif
|
||||||
|
m_hover_wait = false;
|
||||||
|
}
|
||||||
|
if (m_hover) {
|
||||||
|
// as we use the transient selection for the hover ruler, we have to remove it here
|
||||||
|
clear_transient_selection ();
|
||||||
|
m_hover = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_QT)
|
||||||
|
void
|
||||||
|
Service::timeout ()
|
||||||
|
{
|
||||||
|
m_hover_wait = false;
|
||||||
|
m_hover = true;
|
||||||
|
|
||||||
|
// as we use the transient selection for the hover ruler, we have to remove it here
|
||||||
|
clear_transient_selection ();
|
||||||
|
|
||||||
|
// transiently create an auto-metric ruler if requested
|
||||||
|
|
||||||
|
const ant::Template &tpl = current_template ();
|
||||||
|
if (tpl.mode () == ant::Template::RulerAutoMetric) {
|
||||||
|
|
||||||
|
lay::TwoPointSnapToObjectResult ee = auto_measure (m_hover_point, ac_from_buttons (m_hover_buttons), tpl);
|
||||||
|
if (ee.any) {
|
||||||
|
|
||||||
|
m_current = ant::Object (ee.first, ee.second, 0, tpl);
|
||||||
|
|
||||||
|
// HINT: there is no special style for "transient selection on rulers"
|
||||||
|
mp_transient_ruler = new ant::View (this, &m_current, true /*not selected*/);
|
||||||
|
|
||||||
|
if (! editables ()->has_selection ()) {
|
||||||
|
display_status (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Service::transient_select (const db::DPoint &pos)
|
Service::transient_select (const db::DPoint &pos)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,11 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#if defined (HAVE_QT)
|
||||||
|
# include <QTimer>
|
||||||
|
# include <QObject>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ant {
|
namespace ant {
|
||||||
|
|
||||||
class LayoutViewBase;
|
class LayoutViewBase;
|
||||||
|
|
@ -177,11 +182,18 @@ private:
|
||||||
|
|
||||||
// -------------------------------------------------------------
|
// -------------------------------------------------------------
|
||||||
|
|
||||||
class ANT_PUBLIC Service
|
class ANT_PUBLIC Service :
|
||||||
: public lay::EditorServiceBase,
|
#if defined (HAVE_QT)
|
||||||
|
public QObject,
|
||||||
|
#endif
|
||||||
|
public lay::EditorServiceBase,
|
||||||
public lay::Drawing,
|
public lay::Drawing,
|
||||||
public db::Object
|
public db::Object
|
||||||
{
|
{
|
||||||
|
#if defined (HAVE_QT)
|
||||||
|
Q_OBJECT
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef lay::AnnotationShapes::iterator obj_iterator;
|
typedef lay::AnnotationShapes::iterator obj_iterator;
|
||||||
|
|
||||||
|
|
@ -341,6 +353,21 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual db::DBox selection_bbox ();
|
virtual db::DBox selection_bbox ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation of the editables API
|
||||||
|
*/
|
||||||
|
virtual bool enter_event (bool);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation of the editables API
|
||||||
|
*/
|
||||||
|
virtual bool leave_event (bool);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation of the editables API
|
||||||
|
*/
|
||||||
|
virtual void hover_reset ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Transform the selection (reimplementation of lay::Editable interface)
|
* @brief Transform the selection (reimplementation of lay::Editable interface)
|
||||||
*/
|
*/
|
||||||
|
|
@ -506,6 +533,11 @@ public:
|
||||||
*/
|
*/
|
||||||
tl::Event annotation_selection_changed_event;
|
tl::Event annotation_selection_changed_event;
|
||||||
|
|
||||||
|
#if defined (HAVE_QT)
|
||||||
|
public slots:
|
||||||
|
void timeout ();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Ruler display and snapping configuration
|
// Ruler display and snapping configuration
|
||||||
tl::Color m_color;
|
tl::Color m_color;
|
||||||
|
|
@ -551,10 +583,22 @@ private:
|
||||||
std::vector<ant::Template> m_ruler_templates;
|
std::vector<ant::Template> m_ruler_templates;
|
||||||
unsigned int m_current_template;
|
unsigned int m_current_template;
|
||||||
|
|
||||||
|
// Hover detector
|
||||||
|
bool m_hover;
|
||||||
|
bool m_hover_wait;
|
||||||
|
db::DPoint m_hover_point;
|
||||||
|
unsigned int m_hover_buttons;
|
||||||
|
#if defined (HAVE_QT)
|
||||||
|
QTimer m_timer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool m_mouse_in_window;
|
||||||
|
|
||||||
std::pair<bool, db::DPoint> snap1 (const db::DPoint &p, bool obj_snap);
|
std::pair<bool, db::DPoint> snap1 (const db::DPoint &p, bool obj_snap);
|
||||||
lay::PointSnapToObjectResult snap1_details (const db::DPoint &p, bool obj_snap);
|
lay::PointSnapToObjectResult snap1_details (const db::DPoint &p, bool obj_snap);
|
||||||
std::pair<bool, db::DPoint> snap2 (const db::DPoint &p1, const db::DPoint &p2, const ant::Object *obj, lay::angle_constraint_type ac);
|
std::pair<bool, db::DPoint> snap2 (const db::DPoint &p1, const db::DPoint &p2, const ant::Object *obj, lay::angle_constraint_type ac);
|
||||||
lay::PointSnapToObjectResult snap2_details (const db::DPoint &p1, const db::DPoint &p2, const ant::Object *obj, lay::angle_constraint_type ac);
|
lay::PointSnapToObjectResult snap2_details (const db::DPoint &p1, const db::DPoint &p2, const ant::Object *obj, lay::angle_constraint_type ac);
|
||||||
|
lay::TwoPointSnapToObjectResult auto_measure (const db::DPoint &p, lay::angle_constraint_type ac, const ant::Template &tpl);
|
||||||
|
|
||||||
const ant::Template ¤t_template () const;
|
const ant::Template ¤t_template () const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -305,10 +305,7 @@ MoveService::handle_click (const db::DPoint &p, unsigned int buttons, bool drag_
|
||||||
|
|
||||||
if (mp_editables->begin_move (p, ac_from_buttons (buttons))) {
|
if (mp_editables->begin_move (p, ac_from_buttons (buttons))) {
|
||||||
|
|
||||||
lay::SelectionService *selector = mp_view->selection_service ();
|
ui ()->hover_reset ();
|
||||||
if (selector) {
|
|
||||||
selector->hover_reset ();
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_view->clear_transient_selection ();
|
mp_view->clear_transient_selection ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,14 +69,7 @@ public:
|
||||||
virtual bool mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
virtual bool mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||||
virtual bool mouse_double_click_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
virtual bool mouse_double_click_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||||
virtual bool wheel_event (int delta, bool horizontal, const db::DPoint &p, unsigned int buttons, bool prio);
|
virtual bool wheel_event (int delta, bool horizontal, const db::DPoint &p, unsigned int buttons, bool prio);
|
||||||
|
virtual void hover_reset ();
|
||||||
/**
|
|
||||||
* @brief Reset the hover timer for the transient selection
|
|
||||||
*
|
|
||||||
* This method may be used by other services (in particular Move) to avoid the transient to
|
|
||||||
* be triggered from a move operation.
|
|
||||||
*/
|
|
||||||
void hover_reset ();
|
|
||||||
|
|
||||||
#if defined (HAVE_QT)
|
#if defined (HAVE_QT)
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
||||||
|
|
@ -1051,6 +1051,14 @@ ViewObjectUI::drag_cancel ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ViewObjectUI::hover_reset ()
|
||||||
|
{
|
||||||
|
for (service_iterator svc = begin_services (); svc != end_services (); ++svc) {
|
||||||
|
(*svc)->hover_reset ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct z_order_compare_f
|
struct z_order_compare_f
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,17 @@ public:
|
||||||
virtual bool drop_event (const db::DPoint & /*p*/, const DragDropDataBase * /*data*/) { return false; }
|
virtual bool drop_event (const db::DPoint & /*p*/, const DragDropDataBase * /*data*/) { return false; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hover reset request
|
||||||
|
*
|
||||||
|
* This event is issued for services providing some "hover" mode - i.e. capture
|
||||||
|
* mouse move events and start a timer on them.
|
||||||
|
*
|
||||||
|
* The implementation of this event should cancel this timer and
|
||||||
|
* not raise a hover condition.
|
||||||
|
*/
|
||||||
|
virtual void hover_reset () { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Mouse press event handler
|
* @brief Mouse press event handler
|
||||||
*
|
*
|
||||||
|
|
@ -605,6 +616,11 @@ public:
|
||||||
*/
|
*/
|
||||||
void drag_cancel ();
|
void drag_cancel ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calls hover_reset on all services
|
||||||
|
*/
|
||||||
|
void hover_reset ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CanvasPlane rendering
|
* @brief CanvasPlane rendering
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue