From be6bf6a2595347739ca6138c3a5e718ab6578779 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 2 Sep 2017 20:51:07 +0200 Subject: [PATCH] Display state navigation enhanced * Some bug fixes (for example, drag moves were resolved into many tiny state changes) * New buttons for navigation in toolbar (like web browser) * Hierarchy level changes are included in navigation states too --- src/lay/lay/gsiDeclLayMainWindow.cc | 4 +- src/lay/lay/layMainWindow.cc | 55 ++++++++++++++++-------- src/lay/lay/layMainWindow.h | 4 +- src/laybasic/laybasic/layAbstractMenu.cc | 6 ++- src/laybasic/laybasic/layLayoutView.cc | 54 ++++++++++++++++++++--- src/laybasic/laybasic/layLayoutView.h | 22 ++++++++-- src/laybasic/laybasic/layZoomBox.cc | 18 +++++--- 7 files changed, 124 insertions(+), 39 deletions(-) diff --git a/src/lay/lay/gsiDeclLayMainWindow.cc b/src/lay/lay/gsiDeclLayMainWindow.cc index 77c8eb45e..dc3ddfdd7 100644 --- a/src/lay/lay/gsiDeclLayMainWindow.cc +++ b/src/lay/lay/gsiDeclLayMainWindow.cc @@ -476,8 +476,8 @@ Class decl_MainWindow (QT_EXTERNAL_BASE (QMainWindow) "MainWind gsi::method ("cm_max_hier_1", &lay::MainWindow::cm_max_hier_1, "@brief 'cm_max_hier_1' action (bound to a menu)" ) + - gsi::method ("cm_last_display_state", &lay::MainWindow::cm_last_display_state, - "@brief 'cm_last_display_state' action (bound to a menu)" + gsi::method ("cm_prev_display_state|#cm_last_display_state", &lay::MainWindow::cm_prev_display_state, + "@brief 'cm_prev_display_state' action (bound to a menu)" ) + gsi::method ("cm_next_display_state", &lay::MainWindow::cm_next_display_state, "@brief 'cm_next_display_state' action (bound to a menu)" diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index df4d4eda8..9fbc123d5 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -904,8 +904,8 @@ MainWindow::init_menu () MenuLayoutEntry::separator ("redraw_group"), MenuLayoutEntry ("redraw", tl::to_string (QObject::tr ("Redraw")), SLOT (cm_redraw ())), MenuLayoutEntry::separator ("state_group"), - MenuLayoutEntry ("last_display_state", tl::to_string (QObject::tr ("Previous State(Shift+Tab)")), SLOT (cm_last_display_state ())), - MenuLayoutEntry ("next_display_state", tl::to_string (QObject::tr ("Next State(Tab)")), SLOT (cm_next_display_state ())), + MenuLayoutEntry ("prev_display_state", tl::to_string (QObject::tr ("Back(Shift+Tab)<:/back.png>")), SLOT (cm_prev_display_state ())), + MenuLayoutEntry ("next_display_state", tl::to_string (QObject::tr ("Forward(Tab)<:/forward.png>")), SLOT (cm_next_display_state ())), MenuLayoutEntry::separator ("select_group"), MenuLayoutEntry ("select_cell:edit", tl::to_string (QObject::tr ("Select Cell")), SLOT (cm_select_cell ())), MenuLayoutEntry ("select_current_cell", tl::to_string (QObject::tr ("Show As New Top(Ctrl+S)")), SLOT (cm_select_current_cell ())), @@ -943,6 +943,13 @@ MainWindow::init_menu () MenuLayoutEntry::last () }; + MenuLayoutEntry toolbar_entries [] = { + MenuLayoutEntry ("prev_display_state", "-", SLOT (cm_prev_display_state ())), + MenuLayoutEntry ("next_display_state", "-", SLOT (cm_next_display_state ())), + MenuLayoutEntry::separator ("toolbar_post_navigation_group"), + MenuLayoutEntry::last () + }; + MenuLayoutEntry main_menu [] = { MenuLayoutEntry ("file_menu", tl::to_string (QObject::tr ("&File")), file_menu), MenuLayoutEntry ("edit_menu", tl::to_string (QObject::tr ("&Edit")), edit_menu), @@ -953,7 +960,7 @@ MainWindow::init_menu () MenuLayoutEntry ("macros_menu", tl::to_string (QObject::tr ("&Macros")), macros_menu), MenuLayoutEntry::separator ("help_group"), MenuLayoutEntry ("help_menu", tl::to_string (QObject::tr ("&Help")), help_menu), - MenuLayoutEntry ("@toolbar", "", empty_menu), + MenuLayoutEntry ("@toolbar", "", toolbar_entries), MenuLayoutEntry::last () }; @@ -2643,9 +2650,9 @@ MainWindow::update_action_states () next_display_state_action.set_enabled (has_next_display_state ()); } - if (mp_menu->is_valid ("zoom_menu.last_display_state")) { - Action last_display_state_action = mp_menu->action ("zoom_menu.last_display_state"); - last_display_state_action.set_enabled (has_last_display_state ()); + if (mp_menu->is_valid ("zoom_menu.prev_display_state")) { + Action prev_display_state_action = mp_menu->action ("zoom_menu.prev_display_state"); + prev_display_state_action.set_enabled (has_prev_display_state ()); } } catch (...) { @@ -3370,8 +3377,7 @@ MainWindow::cm_new_layout () db::cell_index_type new_ci = cellview->layout ().add_cell (m_new_cell_cell_name.empty () ? 0 : m_new_cell_cell_name.c_str ()); cellview.set_cell (new_ci); - current_view ()->zoom_box (db::DBox (-0.5 * m_new_cell_window_size, -0.5 * m_new_cell_window_size, 0.5 * m_new_cell_window_size, 0.5 * m_new_cell_window_size)); - current_view ()->set_hier_levels (std::make_pair (0, 1)); + current_view ()->zoom_box_and_set_hier_levels (db::DBox (-0.5 * m_new_cell_window_size, -0.5 * m_new_cell_window_size, 0.5 * m_new_cell_window_size, 0.5 * m_new_cell_window_size), std::make_pair (0, 1)); } @@ -3416,10 +3422,12 @@ MainWindow::cm_new_cell () db::cell_index_type new_ci = curr->new_cell (curr->active_cellview_index (), m_new_cell_cell_name.c_str ()); curr->select_cell (new_ci, curr->active_cellview_index ()); - curr->zoom_box (db::DBox (-0.5 * m_new_cell_window_size, -0.5 * m_new_cell_window_size, 0.5 * m_new_cell_window_size, 0.5 * m_new_cell_window_size)); + db::DBox zoom_box = db::DBox (-0.5 * m_new_cell_window_size, -0.5 * m_new_cell_window_size, 0.5 * m_new_cell_window_size, 0.5 * m_new_cell_window_size); if (curr->get_max_hier_levels () < 1 || curr->get_min_hier_levels () > 0) { - curr->set_hier_levels (std::make_pair (0, 1)); + curr->zoom_box_and_set_hier_levels (zoom_box, std::make_pair (0, 1)); + } else { + curr->zoom_box (zoom_box); } } @@ -3629,10 +3637,15 @@ MainWindow::clone_current_view () // select the current mode and select the enabled editables view->mode (m_mode); + // copy the state lay::DisplayState state; current_view ()->save_view (state); view->goto_view (state); + // initialize the state stack + view->clear_states (); + view->store_state (); + view->update_content (); mp_views.back ()->set_current (); @@ -4239,6 +4252,10 @@ MainWindow::do_create_view () // select the current mode and select the enabled editables view->mode (m_mode); + // initialize the state stack + view->clear_states (); + view->store_state (); + return int (mp_views.size () - 1); } @@ -4290,6 +4307,8 @@ MainWindow::create_or_load_layout (const std::string *filename, const db::LoadLa int tl = 0; config_get (cfg_initial_hier_depth, tl); vw->set_hier_levels (std::make_pair (0, tl)); + vw->clear_states (); + vw->store_state (); } } @@ -4474,10 +4493,8 @@ MainWindow::cm_max_hier_1 () void MainWindow::set_hier_levels (std::pair l) { - if (l != get_hier_levels ()) { - if (current_view ()) { - current_view ()->set_hier_levels (l); - } + if (current_view () && l != get_hier_levels ()) { + current_view ()->set_hier_levels (l); } } @@ -4494,22 +4511,22 @@ MainWindow::get_hier_levels () const } void -MainWindow::cm_last_display_state () +MainWindow::cm_prev_display_state () { BEGIN_PROTECTED - if (has_last_display_state ()) { - current_view ()->last_display_state (); + if (has_prev_display_state ()) { + current_view ()->prev_display_state (); } END_PROTECTED } bool -MainWindow::has_last_display_state () +MainWindow::has_prev_display_state () { if (current_view ()) { - return current_view ()->has_last_display_state (); + return current_view ()->has_prev_display_state (); } else { return false; } diff --git a/src/lay/lay/layMainWindow.h b/src/lay/lay/layMainWindow.h index f969c43ff..d34cba0b8 100644 --- a/src/lay/lay/layMainWindow.h +++ b/src/lay/lay/layMainWindow.h @@ -349,7 +349,7 @@ public: /** * @brief Return true, if there is a "last" display state */ - bool has_last_display_state (); + bool has_prev_display_state (); /** * @brief Return true, if there is a "next" display state @@ -696,7 +696,7 @@ public slots: void cm_max_hier (); void cm_max_hier_0 (); void cm_max_hier_1 (); - void cm_last_display_state (); + void cm_prev_display_state (); void cm_next_display_state (); void cm_cancel (); void cm_redraw (); diff --git a/src/laybasic/laybasic/layAbstractMenu.cc b/src/laybasic/laybasic/layAbstractMenu.cc index 6e5fd7c32..8f7b9b838 100644 --- a/src/laybasic/laybasic/layAbstractMenu.cc +++ b/src/laybasic/laybasic/layAbstractMenu.cc @@ -1198,7 +1198,11 @@ AbstractMenu::transfer (const MenuLayoutEntry *layout, AbstractMenuItem &item) a = lay::Action (new ActionHandle (mp_provider->menu_parent_widget ())); } - if (! layout->title.empty ()) { + if (layout->title == "-") { + + // reuse title from other entry + + } else if (! layout->title.empty ()) { std::string title; std::string shortcut; diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index 308b121e7..2834f28f1 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -2371,8 +2371,7 @@ LayoutView::set_layout (const lay::CellView &cv, unsigned int cvindex) *cellview_iter (cvindex) = cv; // clear the history, store path and zoom box - m_display_states.clear (); - m_display_state_ptr = 0; + clear_states (); finish_cellviews_changed (); @@ -3312,6 +3311,22 @@ LayoutView::merge_layer_props (const std::vector &prop } } +void +LayoutView::pop_state () +{ + if (m_display_state_ptr > 0) { + m_display_states.erase (m_display_states.begin () + m_display_state_ptr, m_display_states.end ()); + --m_display_state_ptr; + } +} + +void +LayoutView::clear_states () +{ + m_display_states.clear (); + m_display_state_ptr = 0; +} + void LayoutView::store_state () { @@ -3441,6 +3456,14 @@ LayoutView::ensure_visible (const db::DBox &bbox) store_state (); } +void +LayoutView::zoom_box_and_set_hier_levels (const db::DBox &bbox, const std::pair &levels) +{ + mp_canvas->zoom_box (bbox); + set_hier_levels_basic (levels); + store_state (); +} + void LayoutView::zoom_box (const db::DBox &bbox) { @@ -3631,7 +3654,7 @@ LayoutView::goto_view (const DisplayState &state) select_cellviews (cellviews); if (state.min_hier () <= state.max_hier ()) { - set_hier_levels (std::make_pair (state.min_hier (), state.max_hier ())); + set_hier_levels_basic (std::make_pair (state.min_hier (), state.max_hier ())); } update_content (); @@ -4078,18 +4101,23 @@ LayoutView::cell_box_text_font (unsigned int f) } } -void -LayoutView::set_hier_levels (std::pair l) +bool +LayoutView::set_hier_levels_basic (std::pair l) { if (l != get_hier_levels ()) { if (mp_min_hier_spbx) { + mp_min_hier_spbx->blockSignals (true); mp_min_hier_spbx->setValue (l.first); mp_min_hier_spbx->setMaximum (l.second); + mp_min_hier_spbx->blockSignals (false); } + if (mp_max_hier_spbx) { + mp_max_hier_spbx->blockSignals (true); mp_max_hier_spbx->setValue (l.second); mp_max_hier_spbx->setMinimum (l.first); + mp_max_hier_spbx->blockSignals (false); } m_from_level = l.first; @@ -4100,6 +4128,18 @@ LayoutView::set_hier_levels (std::pair l) redraw (); + return true; + + } else { + return false; + } +} + +void +LayoutView::set_hier_levels (std::pair l) +{ + if (set_hier_levels_basic (l)) { + store_state (); } } @@ -5893,7 +5933,7 @@ LayoutView::remove_unused_layers () } void -LayoutView::last_display_state () +LayoutView::prev_display_state () { if (m_display_state_ptr > 0) { m_display_state_ptr--; @@ -5902,7 +5942,7 @@ LayoutView::last_display_state () } bool -LayoutView::has_last_display_state () +LayoutView::has_prev_display_state () { return m_display_state_ptr > 0; } diff --git a/src/laybasic/laybasic/layLayoutView.h b/src/laybasic/laybasic/layLayoutView.h index 20479e56c..e17097c91 100644 --- a/src/laybasic/laybasic/layLayoutView.h +++ b/src/laybasic/laybasic/layLayoutView.h @@ -909,7 +909,7 @@ public: /** * @brief Return true, if there is a "last" display state */ - bool has_last_display_state (); + bool has_prev_display_state (); /** * @brief Return true, if there is a "next" display state @@ -2301,11 +2301,26 @@ public: return mp_canvas->global_trans (); } + /** + * @brief Removes the previous state from the stack + */ + void pop_state (); + + /** + * @brief Clears the state stack + */ + void clear_states (); + /** * @brief Zoom the given box into view */ void zoom_box (const db::DBox &b); + /** + * @brief Zoom the given box into view and select hierarchy levels + */ + void zoom_box_and_set_hier_levels (const db::DBox &b, const std::pair &levels); + /** * @brief Specify the transformation explicitly */ @@ -2341,7 +2356,7 @@ public: public slots: /** - * @brief Store the current state on the "last states" stack + * @brief Store the current state on the "previous states" stack */ void store_state (); @@ -2373,7 +2388,7 @@ public slots: /** * @brief Select last display state */ - void last_display_state (); + void prev_display_state (); /** * @brief Select next display state @@ -2715,6 +2730,7 @@ private: void abstract_mode_enabled (bool e); bool has_max_hier () const; int max_hier_level () const; + bool set_hier_levels_basic (std::pair l); void update_event_handlers (); void viewport_changed (); diff --git a/src/laybasic/laybasic/layZoomBox.cc b/src/laybasic/laybasic/layZoomBox.cc index 38e9c3bb2..b3a7efeca 100644 --- a/src/laybasic/laybasic/layZoomBox.cc +++ b/src/laybasic/laybasic/layZoomBox.cc @@ -68,14 +68,19 @@ ZoomService::mouse_move_event (const db::DPoint &p, unsigned int /*buttons*/, bo if (prio) { if (mp_box) { + m_p2 = p; mp_box->set_points (m_p1, m_p2); - } else if (mp_view) { - m_vp.move (m_p1 - p); - mp_view->zoom_box (m_vp); - } - mp_view->message ("w: " + tl::micron_to_string (fabs (m_p2.x () - m_p1.x ())) + " h: " + tl::micron_to_string (fabs (m_p2.y () - m_p1.y ()))); + mp_view->message ("w: " + tl::micron_to_string (fabs (m_p2.x () - m_p1.x ())) + " h: " + tl::micron_to_string (fabs (m_p2.y () - m_p1.y ()))); + + } else if (mp_view) { + + m_vp.move (m_p1 - p); + mp_view->pop_state (); // we will overwrite the previous state so we don't collect tiny move events + mp_view->zoom_box (m_vp); + + } return true; @@ -257,6 +262,9 @@ ZoomService::begin_pan (const db::DPoint &pos) m_p1 = pos; m_vp = widget ()->mouse_event_viewport (); + // store one state which we are going to update + mp_view->zoom_box (m_vp); + widget ()->grab_mouse (this, true); }