WIP: further reworking.

This commit is contained in:
Matthias Koefferlein 2020-09-06 21:10:26 +02:00
parent 46b5b87eaf
commit a9a9f88f92
17 changed files with 259 additions and 184 deletions

View File

@ -59,7 +59,6 @@ MainService::MainService (db::Manager *manager, lay::LayoutView *view, lay::Disp
: lay::Plugin (view),
lay::Editable (view),
db::Object (manager),
dm_setup_pages (this, &MainService::do_setup_pages),
mp_view (view),
mp_root (root),
m_needs_update (false),
@ -2357,20 +2356,6 @@ private:
db::cell_index_type m_topcell;
};
void
MainService::config_finalize ()
{
// It's important that the editor option pages are updated last - because the
// configuration change may trigger other configuration changes
dm_setup_pages ();
}
void
MainService::do_setup_pages ()
{
setup_pages (view ());
}
void
MainService::paste ()
{

View File

@ -194,16 +194,7 @@ public:
*/
virtual void paste ();
/**
* @brief Implementation of "config_finalize"
* This implementation will update the editor option page's parameters.
*/
virtual void config_finalize ();
private:
// The deferred execution handler for the config_finalize event
tl::DeferredMethod<edt::MainService> dm_setup_pages;
// The layout view that this service is attached to
lay::LayoutView *mp_view;
lay::Dispatcher *mp_root;
@ -245,7 +236,6 @@ private:
lay::FlattenInstOptionsDialog *flatten_inst_options_dialog ();
edt::MakeCellOptionsDialog *make_cell_options_dialog ();
edt::MakeArrayOptionsDialog *make_array_options_dialog ();
void do_setup_pages ();
};
}

View File

@ -1062,25 +1062,15 @@ PartialService::move_ac () const
void
PartialService::deactivated ()
{
// make all editor option pages visible
activate_service (view (), plugin_declaration (), false);
// clear selection when this mode is left
partial_select (db::DBox (), lay::Editable::Reset);
clear_partial_transient_selection ();
remove_editor_options_page (view ());
}
void
PartialService::activated ()
{
if (view ()->is_editable ()) {
// Show editor options panel
show_editor_options_page (view ());
}
// make all editor option pages visible
activate_service (view (), plugin_declaration (), true);
// .. nothing yet ..
}
void

View File

@ -319,12 +319,19 @@ public:
{
return false;
}
virtual bool implements_mouse_mode (std::string & /*title*/) const
{
return false;
}
virtual void get_editor_options_pages (std::vector<lay::EditorOptionsPage *> &pages, lay::LayoutView * /*view*/, lay::Dispatcher *dispatcher) const
{
// NOTE: we do not set plugin_declaration which makes the page unspecific
EditorOptionsGeneric *generic_opt = new EditorOptionsGeneric (dispatcher);
pages.push_back (generic_opt);
}
virtual void initialize (lay::Dispatcher *root)
{
lay::Dispatcher *mp = lay::Dispatcher::instance ();
@ -403,94 +410,10 @@ private:
static tl::RegisteredClass<lay::PluginDeclaration> config_decl_main (new edt::MainPluginDeclaration (tl::to_string (QObject::tr ("Instances and shapes"))), 4000, "edt::MainService");
void
show_editor_options_page (lay::LayoutView *view)
{
if (! view->editor_options_frame ()) {
return;
}
std::vector<lay::EditorOptionsPage *> prop_dialog_pages;
EditorOptionsGeneric *generic_opt = new EditorOptionsGeneric (view->dispatcher ());
prop_dialog_pages.push_back (generic_opt);
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
const PluginDeclarationBase *pd_base = dynamic_cast<const PluginDeclarationBase *> (&*cls);
if (pd_base) {
pd_base->get_editor_options_pages (prop_dialog_pages, view, view->dispatcher ());
}
}
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = prop_dialog_pages.begin (); op != prop_dialog_pages.end (); ++op) {
(*op)->activate (false);
}
remove_editor_options_page (view);
lay::EditorOptionsPages *pages = new lay::EditorOptionsPages (view->editor_options_frame (), prop_dialog_pages, view);
view->editor_options_frame ()->layout ()->addWidget (pages);
view->editor_options_frame ()->setFocusProxy (pages);
}
void
remove_editor_options_page (lay::LayoutView *view)
{
if (! view->editor_options_frame ()) {
return;
}
QObjectList children = view->editor_options_frame ()->children ();
for (QObjectList::iterator c = children.begin (); c != children.end (); ++c) {
if (dynamic_cast<QWidget *> (*c)) {
delete *c;
}
}
}
static
lay::EditorOptionsPages *get_pages_widget (lay::LayoutView *view)
{
// TODO: is there a better way to find the editor options pages?
lay::EditorOptionsPages *eo_pages = 0;
QObjectList children = view->editor_options_frame ()->children ();
for (QObjectList::iterator c = children.begin (); c != children.end () && !eo_pages; ++c) {
eo_pages = dynamic_cast<lay::EditorOptionsPages *> (*c);
}
return eo_pages;
}
void
activate_service (lay::LayoutView *view, const lay::PluginDeclaration *pd, bool active)
{
lay::EditorOptionsPages *eo_pages = get_pages_widget (view);
if (!eo_pages) {
return;
}
// TODO: this is very inefficient as each "activate" will regenerate the tabs
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) {
(*op)->activate (((*op)->plugin_declaration () == pd || ! (*op)->plugin_declaration ()) && active);
}
}
void
setup_pages (lay::LayoutView *view)
{
lay::EditorOptionsPages *eo_pages = get_pages_widget (view);
if (!eo_pages) {
return;
}
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) {
(*op)->setup (view);
}
}
void
commit_recent (lay::LayoutView *view)
{
lay::EditorOptionsPages *eo_pages = get_pages_widget (view);
lay::EditorOptionsPages *eo_pages = view->editor_options_pages ();;
if (!eo_pages) {
return;
}

View File

@ -42,32 +42,9 @@ namespace edt
class PluginDeclarationBase
: public lay::PluginDeclaration
{
public:
virtual void get_editor_options_pages (std::vector<lay::EditorOptionsPage *> &, lay::LayoutView *, lay::Dispatcher *) const = 0;
// .. nothing yet ..
};
/**
* @brief Creates an editor options page and installs it inside the view
*/
void show_editor_options_page (lay::LayoutView *view);
/**
* @brief Removes the editor options page from the view
*/
void remove_editor_options_page (lay::LayoutView *view);
/**
* @brief Activate or deactivate a certain service
*
* This will show or hide the editor properties pages for the respective service.
*/
void activate_service (lay::LayoutView *view, const lay::PluginDeclaration *pd, bool active);
/**
* @brief Setup the editor option pages for the given view
*/
void setup_pages (lay::LayoutView *view);
/**
* @brief Commits the current configuration for the recently used configuration list
*/

View File

@ -875,13 +875,7 @@ Service::activated ()
m_immediate = do_activated ();
m_editing = false;
// Show editor options panel
show_editor_options_page (view ());
}
// make all editor option pages visible
activate_service (view (), plugin_declaration (), true);
}
void
@ -889,13 +883,8 @@ Service::deactivated ()
{
reset_mouse_cursor ();
// make all editor option pages visible
activate_service (view (), plugin_declaration (), false);
edit_cancel ();
remove_editor_options_page (view ());
m_immediate = false;
}

View File

@ -92,6 +92,7 @@
#include "layHelpAboutDialog.h"
#include "layControlWidgetStack.h"
#include "layViewWidgetStack.h"
#include "layEditorOptionsPages.h"
#include "layInit.h"
#include "antObject.h"
#include "antService.h"
@ -1681,12 +1682,14 @@ MainWindow::select_mode (int m)
}
bool eo_visible = false;
if (pd_sel) {
if (mp_eo_stack && pd_sel) {
eo_visible = pd_sel->editable_enabled ();
}
if (eo_visible && (!mp_eo_stack->currentWidget () || !mp_eo_stack->currentWidget ()->findChild<QWidget *> ())) {
//
eo_visible = false;
if (mp_eo_stack && eo_visible) {
lay::EditorOptionsPages *eo_pages = dynamic_cast<lay::EditorOptionsPages *> (mp_eo_stack->currentWidget ());
if (! eo_pages || ! eo_pages->has_content ()) {
eo_visible = false;
}
}
if (eo_visible != m_eo_visible) {

View File

@ -0,0 +1,70 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 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 "layEditorOptionsFrame.h"
#include "layEditorOptionsPage.h"
#include "layEditorOptionsPages.h"
#include "layPlugin.h"
#include "layLayoutView.h"
#include <QVBoxLayout>
namespace lay
{
EditorOptionsFrame::EditorOptionsFrame (QWidget *parent)
: QFrame (parent), mp_pages (0)
{
setObjectName (QString::fromUtf8 ("editor_options_frame"));
QVBoxLayout *left_frame_ly = new QVBoxLayout (this);
left_frame_ly->setMargin (0);
left_frame_ly->setSpacing (0);
}
EditorOptionsFrame::~EditorOptionsFrame ()
{
// .. nothing yet ..
}
void
EditorOptionsFrame::populate (LayoutView *view)
{
std::vector<lay::EditorOptionsPage *> prop_dialog_pages;
for (tl::Registrar<lay::PluginDeclaration>::iterator cls = tl::Registrar<lay::PluginDeclaration>::begin (); cls != tl::Registrar<lay::PluginDeclaration>::end (); ++cls) {
cls->get_editor_options_pages (prop_dialog_pages, view, view->dispatcher ());
}
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = prop_dialog_pages.begin (); op != prop_dialog_pages.end (); ++op) {
(*op)->activate (false);
}
if (mp_pages) {
delete mp_pages;
}
mp_pages = new lay::EditorOptionsPages (this, prop_dialog_pages, view);
layout ()->addWidget (mp_pages);
setFocusProxy (mp_pages);
}
}

View File

@ -0,0 +1,55 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2020 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
*/
#ifndef HDR_layEditorOptionsFrame
#define HDR_layEditorOptionsFrame
#include "laybasicCommon.h"
#include <QFrame>
namespace lay
{
class EditorOptionsPages;
class LayoutView;
class LAYBASIC_PUBLIC EditorOptionsFrame
: public QFrame
{
public:
EditorOptionsFrame (QWidget *parent);
virtual ~EditorOptionsFrame ();
void populate (LayoutView *view);
EditorOptionsPages *pages_widget () const
{
return mp_pages;
}
public:
EditorOptionsPages *mp_pages;
};
}
#endif

View File

@ -23,6 +23,8 @@
#ifndef HDR_layEditorOptionsPage
#define HDR_layEditorOptionsPage
#include "laybasicCommon.h"
#include <QWidget>
namespace lay
@ -36,7 +38,7 @@ class EditorOptionsPages;
/**
* @brief The base class for a object properties page
*/
class EditorOptionsPage
class LAYBASIC_PUBLIC EditorOptionsPage
: public QWidget
{
Q_OBJECT

View File

@ -80,7 +80,18 @@ EditorOptionsPages::focusInEvent (QFocusEvent * /*event*/)
// Sends the focus to the current page's last focus owner
if (mp_pages->currentWidget () && mp_pages->currentWidget ()->focusWidget ()) {
mp_pages->currentWidget ()->focusWidget ()->setFocus ();
}
}
bool EditorOptionsPages::has_content () const
{
for (std::vector <lay::EditorOptionsPage *>::const_iterator p = m_pages.begin (); p != m_pages.end (); ++p) {
// NOTE: we ignore unspecific pages because they are always visible and don't contribute specific content
if ((*p)->active () && (*p)->plugin_declaration () != 0) {
return true;
}
}
return false;
}
void

View File

@ -24,6 +24,7 @@
#ifndef HDR_layEditorOptionsPages
#define HDR_layEditorOptionsPages
#include "laybasicCommon.h"
#include "layEditorOptionsPage.h"
#include <tlVariant.h>
@ -45,7 +46,7 @@ class Plugin;
/**
* @brief The object properties dialog
*/
class EditorOptionsPages
class LAYBASIC_PUBLIC EditorOptionsPages
: public QFrame
{
Q_OBJECT
@ -63,6 +64,8 @@ public:
return m_pages;
}
bool has_content () const;
public slots:
void apply ();
void setup ();

View File

@ -66,6 +66,8 @@
#include "layBookmarkManagementForm.h"
#include "layNetlistBrowserDialog.h"
#include "layBookmarksView.h"
#include "layEditorOptionsFrame.h"
#include "layEditorOptionsPages.h"
#include "dbClipboard.h"
#include "dbLayout.h"
#include "dbLayoutUtils.h"
@ -254,7 +256,8 @@ LayoutView::LayoutView (db::Manager *manager, bool editable, lay::Plugin *plugin
m_editable (editable),
m_options (options),
m_annotation_shapes (manager),
dm_prop_changed (this, &LayoutView::do_prop_changed)
dm_prop_changed (this, &LayoutView::do_prop_changed),
dm_setup_editor_option_pages (this, &LayoutView::do_setup_editor_options_pages)
{
// either it's us or the parent has a dispatcher
tl_assert (dispatcher () != 0);
@ -272,7 +275,8 @@ LayoutView::LayoutView (lay::LayoutView *source, db::Manager *manager, bool edit
m_editable (editable),
m_options (options),
m_annotation_shapes (manager),
dm_prop_changed (this, &LayoutView::do_prop_changed)
dm_prop_changed (this, &LayoutView::do_prop_changed),
dm_setup_editor_option_pages (this, &LayoutView::do_setup_editor_options_pages)
{
// either it's us or the parent has a dispatcher
tl_assert (dispatcher () != 0);
@ -559,12 +563,8 @@ LayoutView::init (db::Manager *mgr, QWidget * /*parent*/)
if ((m_options & LV_NoEditorOptionsPanel) == 0 && (m_options & LV_Naked) == 0) {
mp_editor_options_frame = new QFrame (0);
mp_editor_options_frame->setObjectName (QString::fromUtf8 ("editor_options_frame"));
QVBoxLayout *left_frame_ly = new QVBoxLayout (mp_editor_options_frame);
left_frame_ly->setMargin (0);
left_frame_ly->setSpacing (0);
mp_editor_options_frame = new lay::EditorOptionsFrame (0);
mp_editor_options_frame->populate (this);
connect (mp_editor_options_frame, SIGNAL (destroyed ()), this, SLOT (side_panel_destroyed ()));
@ -717,6 +717,26 @@ QWidget *LayoutView::menu_parent_widget ()
return this;
}
lay::EditorOptionsPages *LayoutView::editor_options_pages ()
{
if (! mp_editor_options_frame) {
return 0;
} else {
return mp_editor_options_frame->pages_widget ();
}
}
void LayoutView::do_setup_editor_options_pages ()
{
// intialize the editor option pages
lay::EditorOptionsPages *eo_pages = editor_options_pages ();
if (eo_pages) {
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) {
(*op)->setup (this);
}
}
}
void LayoutView::side_panel_destroyed ()
{
if (sender () == mp_control_frame) {
@ -868,6 +888,8 @@ void LayoutView::create_plugins (const lay::PluginDeclaration *except_this)
}
dm_setup_editor_option_pages ();
mode (default_mode ());
}
@ -1645,6 +1667,14 @@ LayoutView::configure (const std::string &name, const std::string &value)
}
}
void
LayoutView::config_finalize ()
{
// It's important that the editor option pages are updated last - because the
// configuration change may trigger other configuration changes
dm_setup_editor_option_pages ();
}
void
LayoutView::enable_edits (bool enable)
{
@ -5525,11 +5555,13 @@ LayoutView::mode (int m)
if (m != m_mode) {
m_mode = m;
lay::Plugin *active_plugin = 0;
if (m > 0) {
for (std::vector<lay::Plugin *>::iterator p = mp_plugins.begin (); p != mp_plugins.end (); ++p) {
if ((*p)->plugin_declaration ()->id () == m) {
active_plugin = *p;
mp_canvas->activate ((*p)->view_service_interface ());
break;
}
@ -5541,6 +5573,22 @@ LayoutView::mode (int m)
mp_canvas->activate (mp_move_service);
}
lay::EditorOptionsPages *eo_pages = editor_options_pages ();
if (eo_pages) {
// TODO: this is very inefficient as each "activate" will regenerate the tabs
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) {
bool is_active = false;
if ((*op)->plugin_declaration () == 0) {
is_active = true;
} else if (active_plugin && active_plugin->plugin_declaration () == (*op)->plugin_declaration ()) {
is_active = true;
}
(*op)->activate (is_active);
}
}
}
}

View File

@ -50,6 +50,7 @@
#include "layPlugin.h"
#include "layDisplayState.h"
#include "layBookmarkList.h"
#include "layEditorOptionsFrame.h"
#include "gsi.h"
#include "tlException.h"
#include "tlEvents.h"
@ -82,6 +83,7 @@ class MoveService;
class Browser;
class ColorButton;
class ConfigureAction;
class EditorOptionsPages;
/**
* @brief Stores a layer reference to create layers which have been added by some action
@ -269,6 +271,14 @@ public:
return mp_libraries_frame;
}
/**
* @brief Gets the container with the bookmarks view
*/
QWidget *bookmarks_frame ()
{
return mp_bookmarks_frame;
}
/**
* @brief Gets the container with the editor options
*/
@ -278,12 +288,9 @@ public:
}
/**
* @brief Gets the container with the bookmarks view
* @brief Gets the editor options pages widget
*/
QWidget *bookmarks_frame ()
{
return mp_bookmarks_frame;
}
lay::EditorOptionsPages *editor_options_pages ();
/**
* @brief Pastes from clipboard
@ -2733,7 +2740,8 @@ private:
lay::HierarchyControlPanel *mp_hierarchy_panel;
lay::LibrariesView *mp_libraries_view;
lay::BookmarksView *mp_bookmarks_view;
QWidget *mp_control_frame, *mp_hierarchy_frame, *mp_libraries_frame, *mp_editor_options_frame, *mp_bookmarks_frame;
QWidget *mp_control_frame, *mp_hierarchy_frame, *mp_libraries_frame, *mp_bookmarks_frame;
lay::EditorOptionsFrame *mp_editor_options_frame;
QSpinBox *mp_min_hier_spbx;
QSpinBox *mp_max_hier_spbx;
std::list <CellView> m_cellviews;
@ -2846,6 +2854,8 @@ private:
bool m_active_cellview_changed_event_enabled;
tl::DeferredMethod<lay::LayoutView> dm_prop_changed;
tl::DeferredMethod<lay::LayoutView> dm_setup_editor_option_pages;
void init (db::Manager *mgr, QWidget *parent);
void init_menu ();
@ -2867,11 +2877,14 @@ private:
int max_hier_level () const;
bool set_hier_levels_basic (std::pair<int, int> l);
void do_setup_editor_options_pages ();
void update_event_handlers ();
void viewport_changed ();
void cellview_changed (unsigned int index);
bool configure (const std::string &name, const std::string &value);
void config_finalize ();
void do_load_layer_props (const std::string &fn, bool map_cv, int cv_index, bool add_default);
void finish_cellviews_changed ();

View File

@ -54,6 +54,7 @@ class ViewService;
class Editable;
class Drawing;
class TechnologyComponentProvider;
class EditorOptionsPage;
/**
* @brief The base class for configuration pages
@ -234,7 +235,7 @@ public:
{
return std::vector<std::pair <std::string, ConfigPage *> > ();
}
/**
* @brief The global configuration
*
@ -317,7 +318,7 @@ public:
}
/**
* @brief Fetch the menu objects for this plugin
* @brief Fetches the menu objects for this plugin
*
* The implementation of this method is supposed to call the base
* class'es "get_menu_entries" method and add it's own entries.
@ -328,7 +329,7 @@ public:
}
/**
* @brief Create a plugin object of the respective kind
* @brief Creates a plugin object of the respective kind
*
* This method may return 0 for "dummy" plugins that just register menu entries
* or configuration options.
@ -339,7 +340,7 @@ public:
}
/**
* @brief Tell if the plugin implements the "lay::Editable" interface
* @brief Tells if the plugin implements the "lay::Editable" interface
*
* This method is supposed to return true if the plugin implements the
* lay::Editable interface and wants to be listed as an "edit" mode in the
@ -350,9 +351,22 @@ public:
{
return false;
}
/**
* @brief Tell if the plugin implements a "lay::ViewService" active mouse mode
* @brief Gets the editor options pages
*
* Editor options pages are shown in the editor options dockable tool widget. Each plugin can create such pages
* and these will be shown in tabs inside this widget.
*
* The new pages are returned in the "pages" vector. The layout view will take ownership of these pages.
*/
virtual void get_editor_options_pages (std::vector<lay::EditorOptionsPage *> & /*pages*/, lay::LayoutView * /*view*/, lay::Dispatcher * /*dispatcher*/) const
{
// .. no pages in the default implementation ..
}
/**
* @brief Tells if the plugin implements a "lay::ViewService" active mouse mode
*
* This method is supposed to return true if the plugin implements the
* lay::ViewService interface and wants to be listed as an mouse mode in the

View File

@ -74,7 +74,7 @@ LAYBASIC_PUBLIC void register_help_handler (QObject *object, const char *slot, c
* and the exception's text will be used as tooltip. Use this function with
* a null ex pointer to clear the error condition.
*/
void indicate_error (QWidget *le, const tl::Exception *ex);
LAYBASIC_PUBLIC void indicate_error (QWidget *le, const tl::Exception *ex);
} // namespace lay

View File

@ -115,6 +115,7 @@ SOURCES = \
layEditable.cc \
layEditStipplesForm.cc \
layEditStippleWidget.cc \
layEditorOptionsFrame.cc \
layEditorOptionsPage.cc \
layEditorOptionsPages.cc \
layFileDialog.cc \
@ -218,6 +219,7 @@ HEADERS = \
layEditable.h \
layEditStipplesForm.h \
layEditStippleWidget.h \
layEditorOptionsFrame.h \
layEditorOptionsPage.h \
layEditorOptionsPages.h \
layFileDialog.h \