mirror of https://github.com/KLayout/klayout.git
280 lines
6.4 KiB
C++
280 lines
6.4 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2016 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 "layMove.h"
|
|
#include "layEditable.h"
|
|
#include "layLayoutView.h"
|
|
#include "laySelector.h"
|
|
#include "laybasicConfig.h"
|
|
|
|
namespace lay
|
|
{
|
|
|
|
// -------------------------------------------------------------
|
|
// MoveService implementation
|
|
|
|
MoveService::MoveService (lay::LayoutView *view)
|
|
: QObject (),
|
|
lay::ViewService (view->view_object_widget ()),
|
|
m_dragging (false),
|
|
mp_editables (view),
|
|
mp_view (view),
|
|
m_global_grid (0.001)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
MoveService::~MoveService ()
|
|
{
|
|
drag_cancel ();
|
|
}
|
|
|
|
void
|
|
MoveService::deactivated ()
|
|
{
|
|
m_shift = db::DPoint ();
|
|
mp_view->clear_transient_selection ();
|
|
drag_cancel ();
|
|
}
|
|
|
|
lay::angle_constraint_type
|
|
ac_from_buttons (unsigned int buttons)
|
|
{
|
|
if ((buttons & lay::ShiftButton) != 0) {
|
|
if ((buttons & lay::ControlButton) != 0) {
|
|
return lay::AC_Any;
|
|
} else {
|
|
return lay::AC_Ortho;
|
|
}
|
|
} else {
|
|
if ((buttons & lay::ControlButton) != 0) {
|
|
return lay::AC_Diagonal;
|
|
} else {
|
|
return lay::AC_Global;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool
|
|
MoveService::configure (const std::string &name, const std::string &value)
|
|
{
|
|
if (name == cfg_grid) {
|
|
tl::from_string (value, m_global_grid);
|
|
}
|
|
return false; // not taken
|
|
}
|
|
|
|
bool
|
|
MoveService::key_event (unsigned int key, unsigned int /*buttons*/)
|
|
{
|
|
double dx = 0.0, dy = 0.0;
|
|
if (int (key) == Qt::Key_Down) {
|
|
dy = -1.0;
|
|
} else if (int (key) == Qt::Key_Up) {
|
|
dy = 1.0;
|
|
} else if (int (key) == Qt::Key_Left) {
|
|
dx = -1.0;
|
|
} else if (int (key) == Qt::Key_Right) {
|
|
dx = 1.0;
|
|
}
|
|
|
|
if (! m_dragging && fabs (dx + dy) > 0.0 && mp_editables->selection_size () > 0) {
|
|
|
|
// determine a shift distance which is 2, 5 or 10 times the grid and is more than 5 pixels
|
|
double dmin = double (5 /*pixels min shift*/) / widget ()->mouse_event_trans ().mag ();
|
|
double d = m_global_grid;
|
|
while (d < dmin) {
|
|
d *= 2.0;
|
|
if (d < dmin) {
|
|
d *= 2.5;
|
|
if (d < dmin) {
|
|
d *= 2.0;
|
|
}
|
|
}
|
|
}
|
|
|
|
db::DVector s = db::DVector (dx * d, dy * d);
|
|
m_shift += s;
|
|
|
|
std::string pos = std::string ("dx: ") + tl::micron_to_string (m_shift.x ()) + " dy: " + tl::micron_to_string (m_shift.y ());
|
|
mp_view->message (pos);
|
|
|
|
mp_editables->transform (db::DCplxTrans (s));
|
|
|
|
return true;
|
|
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool
|
|
MoveService::mouse_move_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
|
{
|
|
bool ret = false;
|
|
|
|
if (m_dragging) {
|
|
|
|
set_cursor (lay::Cursor::size_all);
|
|
mp_editables->move (p, ac_from_buttons (buttons));
|
|
|
|
} else if (prio) {
|
|
|
|
lay::SelectionService *selector = mp_view->selection_service ();
|
|
if (selector) {
|
|
ret = selector->mouse_move_event (p, buttons, prio);
|
|
}
|
|
|
|
}
|
|
|
|
return ret; // not taken to allow the mouse tracker to receive events as well
|
|
}
|
|
|
|
bool
|
|
MoveService::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
|
{
|
|
if (prio && (buttons & lay::RightButton) != 0 && m_dragging) {
|
|
if ((buttons & lay::ShiftButton) != 0) {
|
|
mp_editables->move_transform (p, db::DFTrans (db::DFTrans::m90), ac_from_buttons (buttons));
|
|
} else {
|
|
mp_editables->move_transform (p, db::DFTrans (db::DFTrans::r90), ac_from_buttons (buttons));
|
|
}
|
|
return true;
|
|
}
|
|
if (prio && (buttons & lay::LeftButton) != 0) {
|
|
if (handle_dragging (p, buttons)) {
|
|
return true;
|
|
}
|
|
}
|
|
if (prio) {
|
|
lay::SelectionService *selector = mp_view->selection_service ();
|
|
if (selector) {
|
|
return selector->mouse_click_event (p, buttons, prio);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
MoveService::mouse_double_click_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
|
{
|
|
if (prio) {
|
|
lay::SelectionService *selector = mp_view->selection_service ();
|
|
if (selector) {
|
|
return selector->mouse_double_click_event (p, buttons, prio);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
MoveService::mouse_release_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
|
{
|
|
if (prio) {
|
|
lay::SelectionService *selector = mp_view->selection_service ();
|
|
if (selector) {
|
|
return selector->mouse_release_event (p, buttons, prio);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
MoveService::wheel_event (int delta, bool horizontal, const db::DPoint &p, unsigned int buttons, bool prio)
|
|
{
|
|
if (prio) {
|
|
lay::SelectionService *selector = mp_view->selection_service ();
|
|
if (selector) {
|
|
return selector->wheel_event (delta, horizontal, p, buttons, prio);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
MoveService::mouse_press_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
|
{
|
|
if (prio && (buttons & lay::LeftButton) != 0) {
|
|
if (handle_dragging (p, buttons)) {
|
|
return true;
|
|
}
|
|
}
|
|
if (prio) {
|
|
lay::SelectionService *selector = mp_view->selection_service ();
|
|
if (selector) {
|
|
return selector->mouse_press_event (p, buttons, prio);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool
|
|
MoveService::handle_dragging (const db::DPoint &p, unsigned int buttons)
|
|
{
|
|
if (! m_dragging) {
|
|
|
|
if (mp_editables->begin_move (p, ac_from_buttons (buttons))) {
|
|
|
|
lay::SelectionService *selector = mp_view->selection_service ();
|
|
if (selector) {
|
|
selector->hover_reset ();
|
|
}
|
|
|
|
mp_view->clear_transient_selection ();
|
|
|
|
m_dragging = true;
|
|
widget ()->grab_mouse (this, false);
|
|
|
|
m_shift = db::DPoint ();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
m_dragging = false;
|
|
widget ()->ungrab_mouse (this);
|
|
mp_editables->end_move (p, ac_from_buttons (buttons));
|
|
return true;
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void
|
|
MoveService::drag_cancel ()
|
|
{
|
|
m_shift = db::DPoint ();
|
|
if (m_dragging) {
|
|
mp_editables->edit_cancel ();
|
|
widget ()->ungrab_mouse (this);
|
|
m_dragging = false;
|
|
}
|
|
}
|
|
|
|
}
|
|
|