mirror of
https://github.com/KLayout/klayout.git
synced 2026-09-01 10:27:53 +02:00
WIP: preparing integration of editor options pages and config pages into plugin API
This commit is contained in:
@@ -24,38 +24,180 @@
|
||||
#include "gsiDecl.h"
|
||||
#include "gsiDeclBasic.h"
|
||||
#include "layPlugin.h"
|
||||
#include "layPluginConfigPage.h"
|
||||
#include "layEditorOptionsPage.h"
|
||||
#include "layEditorOptionsPages.h"
|
||||
#include "layViewObject.h"
|
||||
#include "layLayoutViewBase.h"
|
||||
#include "layCursor.h"
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
class PluginFactoryBase;
|
||||
class PluginBase;
|
||||
|
||||
// TODO: these static variables are a bad hack!
|
||||
// However it's not easy to pass parameters to a C++ classes constructor in Ruby without
|
||||
// compromising the capability to derive from that class (at least I have not learned how
|
||||
// to create a "new" in the super class *and* allow a "new" of the derived class). Anyway,
|
||||
// since PluginBase object are only allowed to be created inside the create_plugin method
|
||||
// of the factory, this hack is a quick but dirty workaround.
|
||||
class PluginFactoryBase;
|
||||
class PluginBase;
|
||||
|
||||
#if defined(HAVE_QTBINDINGS)
|
||||
class EditorOptionsPageImpl
|
||||
: public lay::EditorOptionsPage
|
||||
{
|
||||
public:
|
||||
EditorOptionsPageImpl (const std::string &title, int index)
|
||||
: lay::EditorOptionsPage (), m_title (title), m_index (index)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual std::string title () const
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
||||
virtual int order () const
|
||||
{
|
||||
return m_index;
|
||||
}
|
||||
|
||||
void apply_impl (lay::Dispatcher *root)
|
||||
{
|
||||
lay::EditorOptionsPage::apply (root);
|
||||
}
|
||||
|
||||
virtual void apply (lay::Dispatcher *root)
|
||||
{
|
||||
if (f_apply.can_issue ()) {
|
||||
f_apply.issue<EditorOptionsPageImpl, lay::Dispatcher *> (&EditorOptionsPageImpl::apply_impl, root);
|
||||
} else {
|
||||
EditorOptionsPageImpl::apply_impl (root);
|
||||
}
|
||||
}
|
||||
|
||||
void setup_impl (lay::Dispatcher *root)
|
||||
{
|
||||
lay::EditorOptionsPage::setup (root);
|
||||
}
|
||||
|
||||
virtual void setup (lay::Dispatcher *root)
|
||||
{
|
||||
if (f_setup.can_issue ()) {
|
||||
f_setup.issue<EditorOptionsPageImpl, lay::Dispatcher *> (&EditorOptionsPageImpl::setup_impl, root);
|
||||
} else {
|
||||
EditorOptionsPageImpl::setup_impl (root);
|
||||
}
|
||||
}
|
||||
|
||||
gsi::Callback f_apply;
|
||||
gsi::Callback f_setup;
|
||||
|
||||
private:
|
||||
tl::weak_ptr<lay::LayoutViewBase> mp_view;
|
||||
tl::weak_ptr<lay::Dispatcher> mp_dispatcher;
|
||||
std::string m_title;
|
||||
int m_index;
|
||||
};
|
||||
|
||||
EditorOptionsPageImpl *new_editor_options_page (const std::string &title, int index)
|
||||
{
|
||||
return new EditorOptionsPageImpl (title, index);
|
||||
}
|
||||
|
||||
// @@@ methods:
|
||||
// constructor new_editor_options_page
|
||||
// view()
|
||||
// edited()
|
||||
// callback apply(dispatcher)
|
||||
// callback setup(dispatcher)
|
||||
// base: QWidget
|
||||
|
||||
class ConfigPageImpl
|
||||
: public lay::ConfigPage
|
||||
{
|
||||
public:
|
||||
ConfigPageImpl (const std::string &title)
|
||||
: lay::ConfigPage (0), m_title (title)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual std::string title () const
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
||||
void commit_impl (lay::Dispatcher *root)
|
||||
{
|
||||
lay::ConfigPage::commit (root);
|
||||
}
|
||||
|
||||
virtual void commit (lay::Dispatcher *root)
|
||||
{
|
||||
if (f_commit.can_issue ()) {
|
||||
f_commit.issue<ConfigPageImpl, lay::Dispatcher *> (&ConfigPageImpl::commit_impl, root);
|
||||
} else {
|
||||
ConfigPageImpl::commit_impl (root);
|
||||
}
|
||||
}
|
||||
|
||||
void setup_impl (lay::Dispatcher *root)
|
||||
{
|
||||
lay::ConfigPage::setup (root);
|
||||
}
|
||||
|
||||
virtual void setup (lay::Dispatcher *root)
|
||||
{
|
||||
if (f_setup.can_issue ()) {
|
||||
f_setup.issue<ConfigPageImpl, lay::Dispatcher *> (&ConfigPageImpl::setup_impl, root);
|
||||
} else {
|
||||
ConfigPageImpl::setup_impl (root);
|
||||
}
|
||||
}
|
||||
|
||||
gsi::Callback f_commit;
|
||||
gsi::Callback f_setup;
|
||||
|
||||
private:
|
||||
tl::weak_ptr<lay::LayoutViewBase> mp_view;
|
||||
tl::weak_ptr<lay::Dispatcher> mp_dispatcher;
|
||||
std::string m_title;
|
||||
std::string m_index;
|
||||
};
|
||||
|
||||
ConfigPageImpl *new_config_page (const std::string &title)
|
||||
{
|
||||
return new ConfigPageImpl (title);
|
||||
}
|
||||
|
||||
// @@@ methods:
|
||||
// constructor new_config_page
|
||||
// callback apply(dispatcher) = commit
|
||||
// callback setup(dispatcher)
|
||||
// base: QFrame
|
||||
#endif
|
||||
|
||||
// HACK: used to track if we're inside a create_plugin method and can be sure that "init" is called
|
||||
static bool s_in_create_plugin = false;
|
||||
static lay::LayoutViewBase *sp_view = 0;
|
||||
static lay::Dispatcher *sp_dispatcher = 0;
|
||||
|
||||
class PluginBase
|
||||
: public lay::Plugin, public lay::ViewService
|
||||
{
|
||||
public:
|
||||
PluginBase ()
|
||||
: lay::Plugin (sp_dispatcher), lay::ViewService (sp_view ? sp_view->canvas () : 0),
|
||||
mp_view (sp_view), mp_dispatcher (sp_dispatcher)
|
||||
: lay::Plugin (), lay::ViewService (),
|
||||
mp_view (0), mp_dispatcher (0)
|
||||
{
|
||||
if (! s_in_create_plugin) {
|
||||
throw tl::Exception (tl::to_string (tr ("A PluginBase object can only be created in the PluginFactory's create_plugin method")));
|
||||
}
|
||||
}
|
||||
|
||||
void init (lay::LayoutViewBase *view, lay::Dispatcher *dispatcher)
|
||||
{
|
||||
mp_view = view;
|
||||
mp_dispatcher = dispatcher;
|
||||
lay::Plugin::init (dispatcher);
|
||||
lay::ViewService::init (view ? view->canvas () : 0);
|
||||
}
|
||||
|
||||
void grab_mouse ()
|
||||
{
|
||||
if (ui ()) {
|
||||
@@ -282,6 +424,18 @@ public:
|
||||
return mp_dispatcher.get ();
|
||||
}
|
||||
|
||||
#if defined(HAVE_QTBINDINGS)
|
||||
std::vector<lay::EditorOptionsPage *> editor_option_pages ()
|
||||
{
|
||||
lay::EditorOptionsPages *eo_pages = view ()->editor_options_pages ();
|
||||
if (!eo_pages) {
|
||||
return std::vector<lay::EditorOptionsPage *> ();
|
||||
} else {
|
||||
return eo_pages->pages ();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
gsi::Callback f_menu_activated;
|
||||
gsi::Callback f_configure;
|
||||
gsi::Callback f_config_finalize;
|
||||
@@ -416,8 +570,79 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_QTBINDINGS)
|
||||
std::vector<EditorOptionsPageImpl *> get_editor_options_pages_impl () const
|
||||
{
|
||||
return std::vector<EditorOptionsPageImpl *> ();
|
||||
}
|
||||
|
||||
virtual void get_editor_options_pages (std::vector<lay::EditorOptionsPage *> &pages_out, lay::LayoutViewBase *view, lay::Dispatcher *dispatcher) const
|
||||
{
|
||||
try {
|
||||
|
||||
std::vector<EditorOptionsPageImpl *> pages;
|
||||
if (f_get_editor_options_pages.can_issue ()) {
|
||||
pages = f_get_editor_options_pages.issue<PluginFactoryBase, std::vector<EditorOptionsPageImpl *> > (&PluginFactoryBase::get_editor_options_pages_impl);
|
||||
} else {
|
||||
pages = get_editor_options_pages_impl ();
|
||||
}
|
||||
|
||||
pages_out.clear ();
|
||||
for (auto i = pages.begin (); i != pages.end (); ++i) {
|
||||
if (*i) {
|
||||
(*i)->init (view, dispatcher);
|
||||
pages_out.push_back (*i);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
tl::error << ex.msg ();
|
||||
} catch (std::exception &ex) {
|
||||
tl::error << ex.what ();
|
||||
} catch (...) {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<ConfigPageImpl *> get_config_pages_impl () const
|
||||
{
|
||||
return std::vector<ConfigPageImpl *> ();
|
||||
}
|
||||
|
||||
virtual std::vector<std::pair <std::string, lay::ConfigPage *> > config_pages (QWidget *parent) const
|
||||
{
|
||||
std::vector<std::pair <std::string, lay::ConfigPage *> > pages_out;
|
||||
|
||||
try {
|
||||
|
||||
std::vector<ConfigPageImpl *> pages;
|
||||
|
||||
if (f_config_pages.can_issue ()) {
|
||||
pages = f_config_pages.issue<PluginFactoryBase, std::vector<ConfigPageImpl *> > (&PluginFactoryBase::get_config_pages_impl);
|
||||
} else {
|
||||
pages = get_config_pages_impl ();
|
||||
}
|
||||
|
||||
pages_out.clear ();
|
||||
for (auto i = pages.begin (); i != pages.end (); ++i) {
|
||||
if (*i) {
|
||||
(*i)->setParent (parent);
|
||||
pages_out.push_back (std::make_pair ((*i)->title (), *i));
|
||||
}
|
||||
}
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
tl::error << ex.msg ();
|
||||
} catch (std::exception &ex) {
|
||||
tl::error << ex.what ();
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
return pages_out;
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual lay::Plugin *create_plugin (db::Manager *manager, lay::Dispatcher *root, lay::LayoutViewBase *view) const
|
||||
{
|
||||
{
|
||||
if (f_create_plugin.can_issue ()) {
|
||||
return create_plugin_gsi (manager, root, view);
|
||||
} else {
|
||||
@@ -427,22 +652,25 @@ public:
|
||||
|
||||
virtual gsi::PluginBase *create_plugin_gsi (db::Manager *manager, lay::Dispatcher *root, lay::LayoutViewBase *view) const
|
||||
{
|
||||
// TODO: this is a hack. See notes above at s_in_create_plugin
|
||||
s_in_create_plugin = true;
|
||||
sp_view = view;
|
||||
sp_dispatcher = root;
|
||||
|
||||
gsi::PluginBase *ret = 0;
|
||||
try {
|
||||
|
||||
ret = f_create_plugin.issue<PluginFactoryBase, gsi::PluginBase *, db::Manager *, lay::Dispatcher *, lay::LayoutViewBase *> (&PluginFactoryBase::create_plugin_gsi, manager, root, view);
|
||||
s_in_create_plugin = false;
|
||||
sp_view = 0;
|
||||
sp_dispatcher = 0;
|
||||
if (ret) {
|
||||
ret->init (view, root);
|
||||
}
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
tl::error << ex.msg ();
|
||||
} catch (std::exception &ex) {
|
||||
tl::error << ex.what ();
|
||||
} catch (...) {
|
||||
s_in_create_plugin = false;
|
||||
sp_view = 0;
|
||||
sp_dispatcher = 0;
|
||||
}
|
||||
|
||||
s_in_create_plugin = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -512,6 +740,8 @@ public:
|
||||
gsi::Callback f_configure;
|
||||
gsi::Callback f_config_finalize;
|
||||
gsi::Callback f_menu_activated;
|
||||
gsi::Callback f_get_editor_options_pages;
|
||||
gsi::Callback f_config_pages;
|
||||
|
||||
private:
|
||||
std::vector<std::pair<std::string, std::string> > m_options;
|
||||
@@ -521,6 +751,12 @@ private:
|
||||
tl::RegisteredClass <lay::PluginDeclaration> *mp_registration;
|
||||
};
|
||||
|
||||
// @@@
|
||||
#if defined(HAVE_QTBINDINGS)
|
||||
// get_editor_options_pages -> "create_editor_option_pages"
|
||||
// config_pages -> "create_config_pages"
|
||||
#endif
|
||||
|
||||
Class<gsi::PluginFactoryBase> decl_PluginFactory ("lay", "PluginFactory",
|
||||
method ("register", &PluginFactoryBase::register_gsi, gsi::arg ("position"), gsi::arg ("name"), gsi::arg ("title"),
|
||||
"@brief Registers the plugin factory\n"
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2025 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
|
||||
|
||||
*/
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
|
||||
#include "tlInternational.h"
|
||||
#include "layEditorOptionsPage.h"
|
||||
#include "layEditorOptionsPages.h"
|
||||
#include "layLayoutViewBase.h"
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// EditorOptionsPage implementation
|
||||
|
||||
EditorOptionsPage::EditorOptionsPage (lay::LayoutViewBase *view, lay::Dispatcher *dispatcher)
|
||||
: QWidget (0), mp_owner (0), m_active (true), mp_plugin_declaration (0), mp_dispatcher (dispatcher), mp_view (view)
|
||||
{
|
||||
attach_events ();
|
||||
}
|
||||
|
||||
EditorOptionsPage::EditorOptionsPage ()
|
||||
: QWidget (0), mp_owner (0), m_active (true), mp_plugin_declaration (0), mp_dispatcher (0), mp_view (0)
|
||||
{
|
||||
// .. nothing here -> call init to set view and dispatcher
|
||||
}
|
||||
|
||||
void
|
||||
EditorOptionsPage::init (lay::LayoutViewBase *view, lay::Dispatcher *dispatcher)
|
||||
{
|
||||
mp_view = view;
|
||||
mp_dispatcher = dispatcher;
|
||||
attach_events ();
|
||||
}
|
||||
|
||||
EditorOptionsPage::~EditorOptionsPage ()
|
||||
{
|
||||
set_owner (0);
|
||||
}
|
||||
|
||||
void
|
||||
EditorOptionsPage::attach_events ()
|
||||
{
|
||||
detach_from_all_events ();
|
||||
view ()->active_cellview_changed_event.add (this, &EditorOptionsPage::on_active_cellview_changed);
|
||||
int cv_index = view ()->active_cellview_index ();
|
||||
if (cv_index >= 0) {
|
||||
view ()->cellview (cv_index)->technology_changed_event.add (this, &EditorOptionsPage::on_technology_changed);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EditorOptionsPage::on_active_cellview_changed ()
|
||||
{
|
||||
active_cellview_changed ();
|
||||
attach_events ();
|
||||
}
|
||||
|
||||
void
|
||||
EditorOptionsPage::on_technology_changed ()
|
||||
{
|
||||
technology_changed (view ()->active_cellview_ref ()->tech_name ());
|
||||
}
|
||||
|
||||
void
|
||||
EditorOptionsPage::set_owner (EditorOptionsPages *owner)
|
||||
{
|
||||
if (mp_owner) {
|
||||
mp_owner->unregister_page (this);
|
||||
}
|
||||
mp_owner = owner;
|
||||
}
|
||||
|
||||
void
|
||||
EditorOptionsPage::activate (bool active)
|
||||
{
|
||||
if (m_active != active) {
|
||||
m_active = active;
|
||||
if (mp_owner) {
|
||||
mp_owner->activate_page (this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,108 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2025 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
|
||||
|
||||
*/
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
|
||||
#ifndef HDR_layEditorOptionsPage
|
||||
#define HDR_layEditorOptionsPage
|
||||
|
||||
#include "laybasicCommon.h"
|
||||
|
||||
#include "tlObject.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
class PluginDeclaration;
|
||||
class Dispatcher;
|
||||
class LayoutViewBase;
|
||||
class Plugin;
|
||||
class CellView;
|
||||
class EditorOptionsPages;
|
||||
|
||||
/**
|
||||
* @brief The base class for a object properties page
|
||||
*/
|
||||
class LAYBASIC_PUBLIC EditorOptionsPage
|
||||
: public QWidget, public tl::Object
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EditorOptionsPage (lay::LayoutViewBase *view, lay::Dispatcher *dispatcher);
|
||||
EditorOptionsPage ();
|
||||
virtual ~EditorOptionsPage ();
|
||||
|
||||
virtual std::string title () const = 0;
|
||||
virtual int order () const = 0;
|
||||
virtual void apply (lay::Dispatcher * /*root*/) { }
|
||||
virtual void setup (lay::Dispatcher * /*root*/) { }
|
||||
virtual void commit_recent (lay::Dispatcher * /*root*/) { }
|
||||
|
||||
bool active () const { return m_active; }
|
||||
void activate (bool active);
|
||||
void set_owner (EditorOptionsPages *owner);
|
||||
|
||||
const lay::PluginDeclaration *plugin_declaration () const { return mp_plugin_declaration; }
|
||||
void set_plugin_declaration (const lay::PluginDeclaration *pd) { mp_plugin_declaration = pd; }
|
||||
|
||||
void init (lay::LayoutViewBase *view, lay::Dispatcher *dispatcher);
|
||||
|
||||
lay::Dispatcher *dispatcher () const
|
||||
{
|
||||
return mp_dispatcher;
|
||||
}
|
||||
|
||||
lay::LayoutViewBase *view () const
|
||||
{
|
||||
return mp_view;
|
||||
}
|
||||
|
||||
protected slots:
|
||||
void edited ()
|
||||
{
|
||||
apply (dispatcher ());
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void active_cellview_changed () { }
|
||||
virtual void technology_changed (const std::string & /*tech*/) { }
|
||||
|
||||
private:
|
||||
EditorOptionsPages *mp_owner;
|
||||
bool m_active;
|
||||
const lay::PluginDeclaration *mp_plugin_declaration;
|
||||
lay::Dispatcher *mp_dispatcher;
|
||||
lay::LayoutViewBase *mp_view;
|
||||
|
||||
void on_active_cellview_changed ();
|
||||
void on_technology_changed ();
|
||||
void attach_events ();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // defined(HAVE_QT)
|
||||
@@ -0,0 +1,201 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2025 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
|
||||
|
||||
*/
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
|
||||
#include "tlInternational.h"
|
||||
#include "layEditorOptionsPages.h"
|
||||
#include "tlExceptions.h"
|
||||
#include "layPlugin.h"
|
||||
#include "layLayoutViewBase.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QTabWidget>
|
||||
#include <QToolButton>
|
||||
#include <QCompleter>
|
||||
#include <QLineEdit>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// EditorOptionsPages implementation
|
||||
|
||||
struct EOPCompareOp
|
||||
{
|
||||
bool operator() (lay::EditorOptionsPage *a, lay::EditorOptionsPage *b) const
|
||||
{
|
||||
return a->order () < b->order ();
|
||||
}
|
||||
};
|
||||
|
||||
EditorOptionsPages::EditorOptionsPages (QWidget *parent, const std::vector<lay::EditorOptionsPage *> &pages, lay::Dispatcher *dispatcher)
|
||||
: QFrame (parent), mp_dispatcher (dispatcher)
|
||||
{
|
||||
QVBoxLayout *ly1 = new QVBoxLayout (this);
|
||||
ly1->setContentsMargins (0, 0, 0, 0);
|
||||
|
||||
mp_pages = new QTabWidget (this);
|
||||
mp_pages->setSizePolicy (QSizePolicy (QSizePolicy::Ignored, QSizePolicy::Ignored));
|
||||
ly1->addWidget (mp_pages);
|
||||
|
||||
m_pages = pages;
|
||||
for (std::vector <lay::EditorOptionsPage *>::const_iterator p = m_pages.begin (); p != m_pages.end (); ++p) {
|
||||
(*p)->set_owner (this);
|
||||
}
|
||||
|
||||
update (0);
|
||||
setup ();
|
||||
}
|
||||
|
||||
EditorOptionsPages::~EditorOptionsPages ()
|
||||
{
|
||||
while (m_pages.size () > 0) {
|
||||
delete m_pages.front ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
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
|
||||
EditorOptionsPages::unregister_page (lay::EditorOptionsPage *page)
|
||||
{
|
||||
std::vector <lay::EditorOptionsPage *> pages;
|
||||
for (std::vector <lay::EditorOptionsPage *>::const_iterator p = m_pages.begin (); p != m_pages.end (); ++p) {
|
||||
if (*p != page) {
|
||||
pages.push_back (*p);
|
||||
}
|
||||
}
|
||||
m_pages = pages;
|
||||
update (0);
|
||||
}
|
||||
|
||||
void
|
||||
EditorOptionsPages::activate_page (lay::EditorOptionsPage *page)
|
||||
{
|
||||
try {
|
||||
if (page->active ()) {
|
||||
page->setup (mp_dispatcher);
|
||||
}
|
||||
} catch (...) {
|
||||
// catch any errors related to configuration file errors etc.
|
||||
}
|
||||
|
||||
update (page);
|
||||
}
|
||||
|
||||
void
|
||||
EditorOptionsPages::update (lay::EditorOptionsPage *page)
|
||||
{
|
||||
std::vector <lay::EditorOptionsPage *> sorted_pages = m_pages;
|
||||
std::sort (sorted_pages.begin (), sorted_pages.end (), EOPCompareOp ());
|
||||
|
||||
if (! page && m_pages.size () > 0) {
|
||||
page = m_pages.back ();
|
||||
}
|
||||
|
||||
while (mp_pages->count () > 0) {
|
||||
mp_pages->removeTab (0);
|
||||
}
|
||||
int index = -1;
|
||||
for (std::vector <lay::EditorOptionsPage *>::iterator p = sorted_pages.begin (); p != sorted_pages.end (); ++p) {
|
||||
if ((*p)->active ()) {
|
||||
if ((*p) == page) {
|
||||
index = mp_pages->count ();
|
||||
}
|
||||
mp_pages->addTab (*p, tl::to_qstring ((*p)->title ()));
|
||||
} else {
|
||||
(*p)->setParent (0);
|
||||
}
|
||||
}
|
||||
if (index < 0) {
|
||||
index = mp_pages->currentIndex ();
|
||||
}
|
||||
if (index >= int (mp_pages->count ())) {
|
||||
index = mp_pages->count () - 1;
|
||||
}
|
||||
mp_pages->setCurrentIndex (index);
|
||||
|
||||
setVisible (mp_pages->count () > 0);
|
||||
}
|
||||
|
||||
void
|
||||
EditorOptionsPages::setup ()
|
||||
{
|
||||
try {
|
||||
|
||||
for (std::vector <lay::EditorOptionsPage *>::iterator p = m_pages.begin (); p != m_pages.end (); ++p) {
|
||||
if ((*p)->active ()) {
|
||||
(*p)->setup (mp_dispatcher);
|
||||
}
|
||||
}
|
||||
|
||||
// make the display consistent with the status (this is important for
|
||||
// PCell parameters where the PCell may be asked to modify the parameters)
|
||||
do_apply ();
|
||||
|
||||
} catch (...) {
|
||||
// catch any errors related to configuration file errors etc.
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EditorOptionsPages::do_apply ()
|
||||
{
|
||||
for (std::vector <lay::EditorOptionsPage *>::iterator p = m_pages.begin (); p != m_pages.end (); ++p) {
|
||||
if ((*p)->active ()) {
|
||||
// NOTE: we apply to the root dispatcher, so other dispatchers (views) get informed too.
|
||||
(*p)->apply (mp_dispatcher->dispatcher ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EditorOptionsPages::apply ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
do_apply ();
|
||||
END_PROTECTED_W (this)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2025 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
|
||||
|
||||
*/
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
|
||||
#ifndef HDR_layEditorOptionsPages
|
||||
#define HDR_layEditorOptionsPages
|
||||
|
||||
#include "laybasicCommon.h"
|
||||
#include "layEditorOptionsPage.h"
|
||||
|
||||
#include <tlVariant.h>
|
||||
|
||||
#include <QFrame>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class QTabWidget;
|
||||
class QLabel;
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
class PluginDeclaration;
|
||||
class Dispatcher;
|
||||
class Plugin;
|
||||
|
||||
/**
|
||||
* @brief The object properties dialog
|
||||
*/
|
||||
class LAYBASIC_PUBLIC EditorOptionsPages
|
||||
: public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EditorOptionsPages (QWidget *parent, const std::vector<lay::EditorOptionsPage *> &pages, lay::Dispatcher *root);
|
||||
~EditorOptionsPages ();
|
||||
|
||||
void unregister_page (lay::EditorOptionsPage *page);
|
||||
void activate_page (lay::EditorOptionsPage *page);
|
||||
void focusInEvent (QFocusEvent *event);
|
||||
|
||||
const std::vector <lay::EditorOptionsPage *> &pages () const
|
||||
{
|
||||
return m_pages;
|
||||
}
|
||||
|
||||
bool has_content () const;
|
||||
|
||||
public slots:
|
||||
void apply ();
|
||||
void setup ();
|
||||
|
||||
private:
|
||||
std::vector <lay::EditorOptionsPage *> m_pages;
|
||||
lay::Dispatcher *mp_dispatcher;
|
||||
QTabWidget *mp_pages;
|
||||
|
||||
void update (lay::EditorOptionsPage *page);
|
||||
void do_apply ();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // defined(HAVE_QT)
|
||||
@@ -308,8 +308,23 @@ PluginDeclaration::register_plugin ()
|
||||
// Plugin implementation
|
||||
|
||||
Plugin::Plugin (Plugin *parent, bool standalone)
|
||||
: mp_parent (parent), mp_plugin_declaration (0), dm_finalize_config (this, &lay::Plugin::config_end), m_standalone (standalone)
|
||||
: mp_parent (0), mp_plugin_declaration (0), dm_finalize_config (this, &lay::Plugin::config_end), m_standalone (false)
|
||||
{
|
||||
init (parent, standalone);
|
||||
}
|
||||
|
||||
Plugin::Plugin ()
|
||||
: mp_parent (0), mp_plugin_declaration (0), dm_finalize_config (this, &lay::Plugin::config_end), m_standalone (false)
|
||||
{
|
||||
// .. nothing yet (waiting for init) ..
|
||||
}
|
||||
|
||||
void
|
||||
Plugin::init (Plugin *parent, bool standalone)
|
||||
{
|
||||
mp_parent = parent;
|
||||
m_standalone = standalone;
|
||||
|
||||
if (! parent) {
|
||||
if (! standalone) {
|
||||
// load the root with the default configuration
|
||||
@@ -324,6 +339,7 @@ Plugin::Plugin (Plugin *parent, bool standalone)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Plugin::~Plugin ()
|
||||
{
|
||||
if (mp_parent) {
|
||||
|
||||
@@ -504,6 +504,18 @@ public:
|
||||
*/
|
||||
Plugin (Plugin *parent, bool standalone = false);
|
||||
|
||||
/**
|
||||
* @brief The default constructor
|
||||
*
|
||||
* This constructor needs to be followed by init()
|
||||
*/
|
||||
Plugin ();
|
||||
|
||||
/**
|
||||
* @brief Initialization, following the default constructor
|
||||
*/
|
||||
void init (Plugin *parent, bool standalone = false);
|
||||
|
||||
/**
|
||||
* @brief The destructor
|
||||
*/
|
||||
|
||||
@@ -191,8 +191,15 @@ ViewObject::freeze ()
|
||||
// ViewService implementation
|
||||
|
||||
ViewService::ViewService (ViewObjectUI *widget)
|
||||
: mp_widget (widget), m_abs_grab (false), m_enabled (true)
|
||||
: mp_widget (0), m_abs_grab (false), m_enabled (true)
|
||||
{
|
||||
init (widget);
|
||||
}
|
||||
|
||||
void
|
||||
ViewService::init (ViewObjectUI *widget)
|
||||
{
|
||||
mp_widget = widget;
|
||||
if (widget) {
|
||||
widget->register_service (this);
|
||||
}
|
||||
|
||||
@@ -104,6 +104,11 @@ public:
|
||||
*/
|
||||
ViewService (ViewObjectUI *widget = 0);
|
||||
|
||||
/**
|
||||
* @brief Initialization, can follow default constructor
|
||||
*/
|
||||
void init (ViewObjectUI *widget);
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
|
||||
@@ -35,6 +35,8 @@ SOURCES += \
|
||||
gsiDeclLayTlAdded.cc \
|
||||
gsiDeclLayRdbAdded.cc \
|
||||
layAbstractMenu.cc \
|
||||
layEditorOptionsPage.cc \
|
||||
layEditorOptionsPages.cc \
|
||||
layLayoutViewConfig.cc \
|
||||
layMargin.cc \
|
||||
laybasicForceLink.cc \
|
||||
@@ -87,6 +89,8 @@ SOURCES += \
|
||||
layUtils.cc \
|
||||
|
||||
HEADERS += \
|
||||
layEditorOptionsPage.h \
|
||||
layEditorOptionsPages.h \
|
||||
layMargin.h \
|
||||
laybasicConfig.h \
|
||||
laybasicForceLink.h \
|
||||
|
||||
Reference in New Issue
Block a user