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_move_mode (MoveNone),
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -1809,9 +1819,36 @@ Service::mouse_double_click_event (const db::DPoint & /*p*/, unsigned int button
|
|||
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
|
||||
Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
||||
{
|
||||
hover_reset ();
|
||||
|
||||
if (prio && (buttons & lay::LeftButton) != 0) {
|
||||
|
||||
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) {
|
||||
|
||||
// for auto-metric we need some cutline constraint - any or global won't do.
|
||||
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);
|
||||
lay::TwoPointSnapToObjectResult ee = auto_measure (p, ac_from_buttons (buttons), tpl);
|
||||
if (ee.any) {
|
||||
|
||||
// begin the transaction
|
||||
|
|
@ -1968,21 +1985,33 @@ Service::create_measure_ruler (const db::DPoint &pt, lay::angle_constraint_type
|
|||
bool
|
||||
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) {
|
||||
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 ());
|
||||
}
|
||||
if (! m_drawing && m_mouse_in_window && view ()->transient_selection_mode ()) {
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -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
|
||||
Service::transient_select (const db::DPoint &pos)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#if defined (HAVE_QT)
|
||||
# include <QTimer>
|
||||
# include <QObject>
|
||||
#endif
|
||||
|
||||
namespace ant {
|
||||
|
||||
class LayoutViewBase;
|
||||
|
|
@ -177,12 +182,19 @@ private:
|
|||
|
||||
// -------------------------------------------------------------
|
||||
|
||||
class ANT_PUBLIC Service
|
||||
: public lay::EditorServiceBase,
|
||||
class ANT_PUBLIC Service :
|
||||
#if defined (HAVE_QT)
|
||||
public QObject,
|
||||
#endif
|
||||
public lay::EditorServiceBase,
|
||||
public lay::Drawing,
|
||||
public db::Object
|
||||
{
|
||||
public:
|
||||
#if defined (HAVE_QT)
|
||||
Q_OBJECT
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef lay::AnnotationShapes::iterator obj_iterator;
|
||||
|
||||
/**
|
||||
|
|
@ -341,6 +353,21 @@ public:
|
|||
*/
|
||||
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)
|
||||
*/
|
||||
|
|
@ -506,6 +533,11 @@ public:
|
|||
*/
|
||||
tl::Event annotation_selection_changed_event;
|
||||
|
||||
#if defined (HAVE_QT)
|
||||
public slots:
|
||||
void timeout ();
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Ruler display and snapping configuration
|
||||
tl::Color m_color;
|
||||
|
|
@ -551,10 +583,22 @@ private:
|
|||
std::vector<ant::Template> m_ruler_templates;
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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))) {
|
||||
|
||||
lay::SelectionService *selector = mp_view->selection_service ();
|
||||
if (selector) {
|
||||
selector->hover_reset ();
|
||||
}
|
||||
ui ()->hover_reset ();
|
||||
|
||||
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_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);
|
||||
|
||||
/**
|
||||
* @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 ();
|
||||
virtual void hover_reset ();
|
||||
|
||||
#if defined (HAVE_QT)
|
||||
public slots:
|
||||
|
|
|
|||
|
|
@ -1051,7 +1051,15 @@ ViewObjectUI::drag_cancel ()
|
|||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
void
|
||||
ViewObjectUI::hover_reset ()
|
||||
{
|
||||
for (service_iterator svc = begin_services (); svc != end_services (); ++svc) {
|
||||
(*svc)->hover_reset ();
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct z_order_compare_f
|
||||
{
|
||||
|
|
|
|||
|
|
@ -147,6 +147,17 @@ public:
|
|||
virtual bool drop_event (const db::DPoint & /*p*/, const DragDropDataBase * /*data*/) { return false; }
|
||||
#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
|
||||
*
|
||||
|
|
@ -605,6 +616,11 @@ public:
|
|||
*/
|
||||
void drag_cancel ();
|
||||
|
||||
/**
|
||||
* @brief Calls hover_reset on all services
|
||||
*/
|
||||
void hover_reset ();
|
||||
|
||||
/**
|
||||
* @brief CanvasPlane rendering
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue