mirror of https://github.com/KLayout/klayout.git
Enhancement of the "interactive" (infix) modes
1.) Copy & Cut will now take the selection from
the transient selection if no real selection is present
2.) Hence, Copy & Cut are always enabled
3.) The same if true for duplicate
4.) Move interactive will also act immediately on the transient
selection.
This commit is contained in:
parent
2fa545d80b
commit
717470a389
|
|
@ -901,11 +901,6 @@ Service::drag_cancel ()
|
|||
delete mp_active_ruler;
|
||||
mp_active_ruler = 0;
|
||||
}
|
||||
|
||||
if (mp_transient_ruler) {
|
||||
delete mp_transient_ruler;
|
||||
mp_transient_ruler = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -1030,6 +1025,8 @@ Service::begin_move (lay::Editable::MoveMode mode, const db::DPoint &p, lay::ang
|
|||
// cancel any pending move or drag operations, reset mp_active_ruler
|
||||
widget ()->drag_cancel (); // KLUDGE: every service does this to the same service manager
|
||||
|
||||
clear_transient_selection ();
|
||||
|
||||
// choose move mode
|
||||
if (mode == lay::Editable::Selected) {
|
||||
|
||||
|
|
@ -1486,6 +1483,7 @@ Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio
|
|||
|
||||
// stop dragging
|
||||
drag_cancel ();
|
||||
clear_transient_selection ();
|
||||
|
||||
// end the transaction
|
||||
manager ()->commit ();
|
||||
|
|
@ -1535,6 +1533,7 @@ void
|
|||
Service::deactivated ()
|
||||
{
|
||||
drag_cancel ();
|
||||
clear_transient_selection ();
|
||||
}
|
||||
|
||||
std::pair<bool, db::DPoint>
|
||||
|
|
@ -1576,6 +1575,8 @@ struct RulerIdComp
|
|||
void
|
||||
Service::reduce_rulers (int num)
|
||||
{
|
||||
clear_transient_selection ();
|
||||
|
||||
lay::AnnotationShapes::iterator rfrom = mp_view->annotation_shapes ().begin ();
|
||||
lay::AnnotationShapes::iterator rto = mp_view->annotation_shapes ().end ();
|
||||
|
||||
|
|
@ -1921,6 +1922,21 @@ Service::clear_transient_selection ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Service::transient_to_selection ()
|
||||
{
|
||||
if (mp_transient_ruler) {
|
||||
for (lay::AnnotationShapes::iterator r = mp_view->annotation_shapes ().begin (); r != mp_view->annotation_shapes ().end (); ++r) {
|
||||
const ant::Object *robj = dynamic_cast <const ant::Object *> (r->ptr ());
|
||||
if (robj == mp_transient_ruler->ruler ()) {
|
||||
m_selected.insert (std::make_pair (r, 0));
|
||||
selection_to_view ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Service::clear_previous_selection ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -284,6 +284,11 @@ public:
|
|||
*/
|
||||
virtual void clear_previous_selection ();
|
||||
|
||||
/**
|
||||
* @brief Turns the transient selection to the selection
|
||||
*/
|
||||
virtual void transient_to_selection ();
|
||||
|
||||
/**
|
||||
* @brief Establish a transient selection
|
||||
*/
|
||||
|
|
@ -548,7 +553,7 @@ private:
|
|||
bool select (obj_iterator obj, lay::Editable::SelectionMode mode);
|
||||
|
||||
/**
|
||||
* @brief Clear the selection
|
||||
* @brief Clears the selection
|
||||
*/
|
||||
void clear_selection ();
|
||||
|
||||
|
|
|
|||
|
|
@ -357,6 +357,9 @@ Service::begin_move (lay::Editable::MoveMode mode, const db::DPoint &p, lay::ang
|
|||
{
|
||||
if (view ()->is_editable () && mode == lay::Editable::Selected) {
|
||||
|
||||
// flush any pending updates of the markers
|
||||
dm_selection_to_view.execute ();
|
||||
|
||||
m_move_start = p;
|
||||
m_move_trans = db::DTrans ();
|
||||
m_move_sel = true; // TODO: there is no "false". Remove this.
|
||||
|
|
@ -1187,6 +1190,15 @@ Service::selection_applies (const lay::ObjectInstPath & /*sel*/) const
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Service::transient_to_selection ()
|
||||
{
|
||||
if (! m_transient_selection.empty ()) {
|
||||
m_selection.insert (m_transient_selection.begin (), m_transient_selection.end ());
|
||||
selection_to_view ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Service::clear_previous_selection ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -184,11 +184,6 @@ public:
|
|||
*/
|
||||
virtual bool select (const db::DBox &box, lay::Editable::SelectionMode mode);
|
||||
|
||||
/**
|
||||
* @brief Clears the previous selection
|
||||
*/
|
||||
virtual void clear_previous_selection ();
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the given selected object is handled by this service
|
||||
*/
|
||||
|
|
@ -269,11 +264,21 @@ public:
|
|||
*/
|
||||
bool select (const lay::ObjectInstPath &obj, lay::Editable::SelectionMode mode);
|
||||
|
||||
/**
|
||||
* @brief Clears the previous selection
|
||||
*/
|
||||
void clear_previous_selection ();
|
||||
|
||||
/**
|
||||
* @brief Establish a transient selection
|
||||
*/
|
||||
bool transient_select (const db::DPoint &pos);
|
||||
|
||||
/**
|
||||
* @brief Turns the transient selection to the selection
|
||||
*/
|
||||
virtual void transient_to_selection ();
|
||||
|
||||
/**
|
||||
* @brief Clear the transient selection
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1063,6 +1063,15 @@ Service::clear_previous_selection ()
|
|||
m_previous_selection.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
Service::transient_to_selection ()
|
||||
{
|
||||
if (mp_transient_view) {
|
||||
m_selected.insert (std::make_pair (mp_transient_view->image_ref (), 0));
|
||||
selection_to_view ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Service::select (obj_iterator obj, lay::Editable::SelectionMode mode)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -304,6 +304,11 @@ public:
|
|||
*/
|
||||
virtual bool transient_select (const db::DPoint &pos);
|
||||
|
||||
/**
|
||||
* @brief Turns the transient selection to the selection
|
||||
*/
|
||||
virtual void transient_to_selection ();
|
||||
|
||||
/**
|
||||
* @brief Clear the transient selection
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2275,7 +2275,7 @@ MainWindow::do_cm_duplicate (bool interactive)
|
|||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
if (current_view () && current_view ()->has_selection ()) {
|
||||
if (current_view ()) {
|
||||
|
||||
// Do duplicate simply by concatenating copy & paste currently.
|
||||
// Save the clipboard state before in order to preserve the current content
|
||||
|
|
@ -2327,7 +2327,7 @@ MainWindow::cm_copy ()
|
|||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
if (current_view () && current_view ()->has_selection ()) {
|
||||
if (current_view ()) {
|
||||
current_view ()->copy ();
|
||||
current_view ()->clear_selection ();
|
||||
}
|
||||
|
|
@ -2370,7 +2370,7 @@ MainWindow::cm_cut ()
|
|||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
if (current_view () && current_view ()->has_selection ()) {
|
||||
if (current_view ()) {
|
||||
current_view ()->cut ();
|
||||
current_view ()->cancel (); // see del() for reason why cancel is after cut
|
||||
current_view ()->clear_selection ();
|
||||
|
|
@ -2766,21 +2766,6 @@ MainWindow::update_action_states ()
|
|||
|
||||
}
|
||||
|
||||
if (mp_menu->is_valid ("edit_menu.copy")) {
|
||||
Action copy_action = mp_menu->action ("edit_menu.copy");
|
||||
copy_action.set_enabled (current_view () && current_view ()->has_selection () && edits_enabled ());
|
||||
}
|
||||
|
||||
if (mp_menu->is_valid ("edit_menu.duplicate")) {
|
||||
Action copy_action = mp_menu->action ("edit_menu.duplicate");
|
||||
copy_action.set_enabled (current_view () && current_view ()->has_selection () && edits_enabled ());
|
||||
}
|
||||
|
||||
if (mp_menu->is_valid ("edit_menu.cut")) {
|
||||
Action cut_action = mp_menu->action ("edit_menu.cut");
|
||||
cut_action.set_enabled (current_view () && current_view ()->has_selection () && edits_enabled ());
|
||||
}
|
||||
|
||||
if (mp_menu->is_valid ("edit_menu.paste")) {
|
||||
Action paste_action = mp_menu->action ("edit_menu.paste");
|
||||
paste_action.set_enabled (! db::Clipboard::instance ().empty () && edits_enabled ());
|
||||
|
|
|
|||
|
|
@ -821,6 +821,29 @@ Class<lay::LayoutView> decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou
|
|||
"selection. Calling this method is useful to ensure there are no potential interactions with the script's "
|
||||
"functionality.\n"
|
||||
) +
|
||||
gsi::method ("clear_selection", &lay::LayoutView::clear_selection,
|
||||
"@brief Clears the selection of all objects (shapes, annotations, images ...)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.2\n"
|
||||
) +
|
||||
gsi::method ("clear_transient_selection", &lay::LayoutView::clear_transient_selection,
|
||||
"@brief Clears the transient selection (mouse-over hightlights) of all objects (shapes, annotations, images ...)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.2\n"
|
||||
) +
|
||||
gsi::method ("transient_to_selection", &lay::LayoutView::transient_to_selection,
|
||||
"@brief Turns the transient selection into the actual selection\n"
|
||||
"\n"
|
||||
"The current selection is cleared before. All highlighted objects under the mouse will become selected. "
|
||||
"This applies to all types of objects (rulers, shapes, images ...).\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.2\n"
|
||||
) +
|
||||
gsi::method ("selection_bbox", &lay::LayoutView::selection_bbox,
|
||||
"@brief Returns the bounding box of the current selection\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.2\n"
|
||||
) +
|
||||
gsi::method ("stop", &lay::LayoutView::stop,
|
||||
"@brief Stops redraw thread and close any browsers\n"
|
||||
"This method usually does not need to be called explicitly. The redraw thread is stopped automatically."
|
||||
|
|
@ -1077,7 +1100,6 @@ Class<lay::LayoutView> decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou
|
|||
) +
|
||||
gsi::method_ext ("delete_layers", &delete_layers1, gsi::arg ("iterators"),
|
||||
"@brief Deletes the layer properties nodes specified by the iterator\n"
|
||||
"@args iterators\n"
|
||||
"\n"
|
||||
"This method deletes the nodes specifies by the iterators. This method is the most convenient way to "
|
||||
"delete multiple entries.\n"
|
||||
|
|
@ -1837,9 +1859,8 @@ static void cv_show_all_cells (lay::CellViewRef *cv)
|
|||
}
|
||||
|
||||
Class<lay::CellViewRef> decl_CellView ("lay", "CellView",
|
||||
method ("==", static_cast<bool (lay::CellViewRef::*) (const lay::CellViewRef &) const> (&lay::CellViewRef::operator==),
|
||||
method ("==", static_cast<bool (lay::CellViewRef::*) (const lay::CellViewRef &) const> (&lay::CellViewRef::operator==), gsi::arg ("other"),
|
||||
"@brief Equality: indicates whether the cellviews refer to the same one\n"
|
||||
"@args other\n"
|
||||
"In version 0.25, the definition of the equality operator has been changed to reflect identity of the "
|
||||
"cellview. Before that version, identity of the cell shown was implied."
|
||||
) +
|
||||
|
|
@ -1868,32 +1889,28 @@ Class<lay::CellViewRef> decl_CellView ("lay", "CellView",
|
|||
"@brief Returns true, if the cellview is valid\n"
|
||||
"A cellview may become invalid if the corresponding tab is closed for example."
|
||||
) +
|
||||
method ("path=|set_path", &lay::CellViewRef::set_unspecific_path,
|
||||
method ("path=|set_path", &lay::CellViewRef::set_unspecific_path, gsi::arg ("path"),
|
||||
"@brief Sets the unspecific part of the path explicitly\n"
|
||||
"@args path\n"
|
||||
"\n"
|
||||
"Setting the unspecific part of the path will clear the context path component and\n"
|
||||
"update the context and target cell.\n"
|
||||
) +
|
||||
method ("context_path=|set_context_path", &lay::CellViewRef::set_specific_path,
|
||||
method ("context_path=|set_context_path", &lay::CellViewRef::set_specific_path, gsi::arg ("path"),
|
||||
"@brief Sets the context path explicitly\n"
|
||||
"@args path\n"
|
||||
"\n"
|
||||
"This method assumes that the unspecific part of the path \n"
|
||||
"is established already and that the context path starts\n"
|
||||
"from the context cell.\n"
|
||||
) +
|
||||
method ("cell_index=|set_cell", (void (lay::CellViewRef::*) (lay::CellViewRef::cell_index_type)) &lay::CellViewRef::set_cell,
|
||||
method ("cell_index=|set_cell", (void (lay::CellViewRef::*) (lay::CellViewRef::cell_index_type)) &lay::CellViewRef::set_cell, gsi::arg ("cell_index"),
|
||||
"@brief Sets the path to the given cell\n"
|
||||
"@args cell_index\n"
|
||||
"\n"
|
||||
"This method will construct any path to this cell, not a \n"
|
||||
"particular one. It will clear the context path\n"
|
||||
"and update the context and target cell. Note that the cell is specified by it's index.\n"
|
||||
) +
|
||||
method ("cell_name=|set_cell_name", (void (lay::CellViewRef::*) (const std::string &)) &lay::CellViewRef::set_cell,
|
||||
method ("cell_name=|set_cell_name", (void (lay::CellViewRef::*) (const std::string &)) &lay::CellViewRef::set_cell, gsi::arg ("cell_name"),
|
||||
"@brief Sets the cell by name\n"
|
||||
"@args cell_name\n"
|
||||
"\n"
|
||||
"If the name is not a valid one, the cellview will become\n"
|
||||
"invalid.\n"
|
||||
|
|
@ -1901,9 +1918,8 @@ Class<lay::CellViewRef> decl_CellView ("lay", "CellView",
|
|||
"particular one. It will clear the context path\n"
|
||||
"and update the context and target cell.\n"
|
||||
) +
|
||||
method_ext ("cell=", set_cell,
|
||||
method_ext ("cell=", set_cell, gsi::arg ("cell"),
|
||||
"@brief Sets the cell by reference to a Cell object\n"
|
||||
"@args cell\n"
|
||||
"Setting the cell reference to nil invalidates the cellview. "
|
||||
"This method will construct any path to this cell, not a \n"
|
||||
"particular one. It will clear the context path\n"
|
||||
|
|
@ -1961,9 +1977,8 @@ Class<lay::CellViewRef> decl_CellView ("lay", "CellView",
|
|||
"@brief Returns the technology name for the layout behind the given cell view\n"
|
||||
"This method has been added in version 0.23.\n"
|
||||
) +
|
||||
method_ext ("technology=", &apply_technology,
|
||||
method_ext ("technology=", &apply_technology, gsi::arg ("tech_name"),
|
||||
"@brief Sets the technology for the layout behind the given cell view\n"
|
||||
"@args tech_name\n"
|
||||
"According to the specification of the technology, new layer properties may be loaded "
|
||||
"or the net tracer may be reconfigured. If the layout is shown in multiple views, the "
|
||||
"technology is updated for all views.\n"
|
||||
|
|
@ -1972,9 +1987,8 @@ Class<lay::CellViewRef> decl_CellView ("lay", "CellView",
|
|||
method_ext ("layout", &get_layout,
|
||||
"@brief Gets the reference to the layout object addressed by this view\n"
|
||||
) +
|
||||
method_ext ("descend", &cv_descend,
|
||||
method_ext ("descend", &cv_descend, gsi::arg ("path"),
|
||||
"@brief Descends further into the hierarchy.\n"
|
||||
"@args path\n"
|
||||
"Adds the given path (given as an array of InstElement objects) to the specific path of the "
|
||||
"cellview with the given index. In effect, the cell addressed by the terminal of the new path "
|
||||
"components can be shown in the context of the upper cells, if the minimum hierarchy level is "
|
||||
|
|
|
|||
|
|
@ -301,6 +301,22 @@ Editables::clear_transient_selection ()
|
|||
signal_transient_selection_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
Editables::transient_to_selection ()
|
||||
{
|
||||
cancel_edits ();
|
||||
for (iterator e = begin (); e != end (); ++e) {
|
||||
e->select (db::DBox (), lay::Editable::Reset); // clear selection
|
||||
e->clear_previous_selection ();
|
||||
e->transient_to_selection ();
|
||||
e->clear_transient_selection ();
|
||||
}
|
||||
|
||||
// send a signal to the observers
|
||||
signal_transient_selection_changed ();
|
||||
signal_selection_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
Editables::clear_selection ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -182,6 +182,14 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns the transient selection to the selection
|
||||
*/
|
||||
virtual void transient_to_selection ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the transient selection
|
||||
*
|
||||
|
|
@ -418,7 +426,7 @@ public:
|
|||
* or must be given in micron units.
|
||||
*/
|
||||
db::DBox selection_bbox ();
|
||||
|
||||
|
||||
/**
|
||||
* @brief transform the selection
|
||||
*
|
||||
|
|
@ -457,6 +465,11 @@ public:
|
|||
*/
|
||||
void clear_transient_selection ();
|
||||
|
||||
/**
|
||||
* @brief Turns the transient selection to the selection
|
||||
*/
|
||||
void transient_to_selection ();
|
||||
|
||||
/**
|
||||
* @brief Clear the previous selection
|
||||
*
|
||||
|
|
|
|||
|
|
@ -5154,7 +5154,7 @@ LayoutView::paste_interactive ()
|
|||
// operations.
|
||||
trans->close ();
|
||||
|
||||
if (mp_move_service->begin_move (trans.release ())) {
|
||||
if (mp_move_service->begin_move (trans.release (), false)) {
|
||||
switch_mode (-1); // move mode
|
||||
}
|
||||
}
|
||||
|
|
@ -5167,7 +5167,14 @@ LayoutView::copy ()
|
|||
} else if (mp_control_panel && mp_control_panel->has_focus ()) {
|
||||
mp_control_panel->copy ();
|
||||
} else {
|
||||
|
||||
if (lay::Editables::selection_size () == 0) {
|
||||
// try to use the transient selection for the real one
|
||||
lay::Editables::transient_to_selection ();
|
||||
}
|
||||
|
||||
lay::Editables::copy ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5182,8 +5189,15 @@ LayoutView::cut ()
|
|||
db::Transaction trans (manager (), tl::to_string (QObject::tr ("Cut Layers")));
|
||||
mp_control_panel->cut ();
|
||||
} else {
|
||||
|
||||
if (lay::Editables::selection_size () == 0) {
|
||||
// try to use the transient selection for the real one
|
||||
lay::Editables::transient_to_selection ();
|
||||
}
|
||||
|
||||
db::Transaction trans (manager (), tl::to_string (QObject::tr ("Cut")));
|
||||
lay::Editables::cut ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ MoveService::MoveService (lay::LayoutView *view)
|
|||
: QObject (),
|
||||
lay::ViewService (view->view_object_widget ()),
|
||||
m_dragging (false),
|
||||
m_dragging_transient (false),
|
||||
mp_editables (view),
|
||||
mp_view (view),
|
||||
m_global_grid (0.001)
|
||||
|
|
@ -148,6 +149,9 @@ MoveService::mouse_move_event (const db::DPoint &p, unsigned int buttons, bool p
|
|||
|
||||
}
|
||||
|
||||
// track mouse position for the infix move initiation
|
||||
m_mouse_pos = p;
|
||||
|
||||
return ret; // not taken to allow the mouse tracker to receive events as well
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +167,7 @@ MoveService::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool
|
|||
return true;
|
||||
}
|
||||
if (prio && (buttons & lay::LeftButton) != 0) {
|
||||
if (handle_dragging (p, buttons, 0)) {
|
||||
if (handle_dragging (p, buttons, false, 0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -216,7 +220,7 @@ 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, 0)) {
|
||||
if (handle_dragging (p, buttons, false, 0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -230,26 +234,50 @@ MoveService::mouse_press_event (const db::DPoint &p, unsigned int buttons, bool
|
|||
}
|
||||
|
||||
bool
|
||||
MoveService::begin_move (db::Transaction *transaction)
|
||||
MoveService::begin_move (db::Transaction *transaction, bool selected_after_move)
|
||||
{
|
||||
if (m_dragging) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::auto_ptr<db::Transaction> trans_holder (transaction);
|
||||
|
||||
drag_cancel ();
|
||||
bool drag_transient = ! selected_after_move;
|
||||
if (mp_editables->selection_size () == 0) {
|
||||
// try to use the transient selection for the real one
|
||||
mp_editables->transient_to_selection ();
|
||||
drag_transient = true;
|
||||
}
|
||||
|
||||
if (mp_editables->selection_size () == 0) {
|
||||
// still nothing selected
|
||||
return false;
|
||||
}
|
||||
|
||||
db::DBox bbox = mp_editables->selection_bbox ();
|
||||
if (bbox.empty ()) {
|
||||
// nothing selected
|
||||
// nothing (useful) selected
|
||||
return false;
|
||||
}
|
||||
|
||||
set_cursor (lay::Cursor::size_all);
|
||||
|
||||
// emulate a "begin move" at the center of the selection bbox - this will become the reference point
|
||||
return handle_dragging (bbox.center (), 0, trans_holder.release ());
|
||||
// emulate a "begin move" at the current mouse position if inside the box or the closest point
|
||||
// of the box.
|
||||
|
||||
db::DPoint pstart = m_mouse_pos;
|
||||
if (! bbox.contains (pstart)) {
|
||||
pstart.set_x (std::max (pstart.x (), bbox.p1 ().x ()));
|
||||
pstart.set_x (std::min (pstart.x (), bbox.p2 ().x ()));
|
||||
pstart.set_y (std::max (pstart.y (), bbox.p1 ().y ()));
|
||||
pstart.set_y (std::min (pstart.y (), bbox.p2 ().y ()));
|
||||
}
|
||||
|
||||
return handle_dragging (pstart, 0, drag_transient, trans_holder.release ());
|
||||
}
|
||||
|
||||
bool
|
||||
MoveService::handle_dragging (const db::DPoint &p, unsigned int buttons, db::Transaction *transaction)
|
||||
MoveService::handle_dragging (const db::DPoint &p, unsigned int buttons, bool drag_transient, db::Transaction *transaction)
|
||||
{
|
||||
std::auto_ptr<db::Transaction> trans_holder (transaction);
|
||||
|
||||
|
|
@ -267,6 +295,7 @@ MoveService::handle_dragging (const db::DPoint &p, unsigned int buttons, db::Tra
|
|||
mp_view->clear_transient_selection ();
|
||||
|
||||
m_dragging = true;
|
||||
m_dragging_transient = drag_transient;
|
||||
widget ()->grab_mouse (this, false);
|
||||
|
||||
m_shift = db::DPoint ();
|
||||
|
|
@ -278,8 +307,14 @@ MoveService::handle_dragging (const db::DPoint &p, unsigned int buttons, db::Tra
|
|||
} else {
|
||||
|
||||
m_dragging = false;
|
||||
|
||||
widget ()->ungrab_mouse (this);
|
||||
mp_editables->end_move (p, ac_from_buttons (buttons), mp_transaction.release ());
|
||||
|
||||
if (m_dragging_transient) {
|
||||
mp_editables->clear_selection ();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public:
|
|||
~MoveService ();
|
||||
|
||||
virtual bool configure (const std::string &name, const std::string &value);
|
||||
bool begin_move (db::Transaction *transaction = 0);
|
||||
bool begin_move (db::Transaction *transaction = 0, bool selected_after_move = true);
|
||||
|
||||
private:
|
||||
virtual bool mouse_press_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||
|
|
@ -62,13 +62,15 @@ private:
|
|||
virtual void drag_cancel ();
|
||||
virtual void deactivated ();
|
||||
|
||||
bool handle_dragging (const db::DPoint &p, unsigned int buttons, db::Transaction *transaction);
|
||||
bool handle_dragging (const db::DPoint &p, unsigned int buttons, bool drag_transient, db::Transaction *transaction);
|
||||
|
||||
bool m_dragging;
|
||||
bool m_dragging_transient;
|
||||
lay::Editables *mp_editables;
|
||||
lay::LayoutView *mp_view;
|
||||
double m_global_grid;
|
||||
db::DPoint m_shift;
|
||||
db::DPoint m_mouse_pos;
|
||||
std::auto_ptr<db::Transaction> mp_transaction;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue