mirror of https://github.com/KLayout/klayout.git
First draft
This commit is contained in:
parent
7e8ce51da2
commit
b4d1a4a954
|
|
@ -59,9 +59,21 @@ public:
|
||||||
return sp_instance;
|
return sp_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_editor_hook (EditorHooks *hook)
|
void register_editor_hooks (EditorHooks *hooks, const std::string &name)
|
||||||
{
|
{
|
||||||
m_hooks.push_back (hook);
|
// needed, so we do not loose the object in case we erase it:
|
||||||
|
tl::shared_ptr<EditorHooks> tmp (hooks);
|
||||||
|
|
||||||
|
// remove other hooks with the same name or with an identical address
|
||||||
|
for (auto h = m_hooks.begin (); h != m_hooks.end (); ) {
|
||||||
|
auto hh = h++;
|
||||||
|
if (hh.operator-> () && (hh.operator-> () == hooks || hh->name () == name)) {
|
||||||
|
m_hooks.erase (hh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hooks->set_name (name);
|
||||||
|
m_hooks.push_back (hooks);
|
||||||
}
|
}
|
||||||
|
|
||||||
tl::weak_collection<EditorHooks>
|
tl::weak_collection<EditorHooks>
|
||||||
|
|
@ -69,7 +81,7 @@ public:
|
||||||
{
|
{
|
||||||
tl::weak_collection<EditorHooks> res;
|
tl::weak_collection<EditorHooks> res;
|
||||||
for (auto h = m_hooks.begin (); h != m_hooks.end (); ++h) {
|
for (auto h = m_hooks.begin (); h != m_hooks.end (); ++h) {
|
||||||
if (! h->for_technologies () || h->is_for_technology (for_technology)) {
|
if (h.operator-> () && (! h->for_technologies () || h->is_for_technology (for_technology))) {
|
||||||
res.push_back (h.operator-> ());
|
res.push_back (h.operator-> ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -128,11 +140,11 @@ EditorHooks::add_technology (const std::string &tech)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
EditorHooks::register_editor_hook (EditorHooks *hook)
|
EditorHooks::register_editor_hooks (EditorHooks *hooks, const std::string &name)
|
||||||
{
|
{
|
||||||
if (EditorHooksManager::instance ()) {
|
if (EditorHooksManager::instance ()) {
|
||||||
hook->keep ();
|
hooks->keep ();
|
||||||
EditorHooksManager::instance ()->register_editor_hook (hook);
|
EditorHooksManager::instance ()->register_editor_hooks (hooks, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "dbTrans.h"
|
#include "dbTrans.h"
|
||||||
#include "gsiObject.h"
|
#include "gsiObject.h"
|
||||||
#include "tlExceptions.h"
|
#include "tlExceptions.h"
|
||||||
|
#include "tlLog.h"
|
||||||
#include "tlObjectCollection.h"
|
#include "tlObjectCollection.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
@ -36,7 +37,7 @@
|
||||||
|
|
||||||
namespace lay
|
namespace lay
|
||||||
{
|
{
|
||||||
class LayoutView;
|
class LayoutViewBase;
|
||||||
class ObjectInstPath;
|
class ObjectInstPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,6 +73,10 @@ class EDT_PUBLIC EditorHooks
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief Constructor
|
||||||
|
*
|
||||||
|
* The name is arbitrary, but should be unique, as hooks with the
|
||||||
|
* same name replace each other. This is a debugging aid for GSI as we can
|
||||||
|
* re-register hooks while we keep them in the system.
|
||||||
*/
|
*/
|
||||||
EditorHooks ();
|
EditorHooks ();
|
||||||
|
|
||||||
|
|
@ -81,29 +86,45 @@ public:
|
||||||
virtual ~EditorHooks ();
|
virtual ~EditorHooks ();
|
||||||
|
|
||||||
// creation protocol
|
// creation protocol
|
||||||
virtual void begin_create (lay::LayoutView * /*view*/) { }
|
virtual void begin_create (lay::LayoutViewBase * /*view*/) { }
|
||||||
virtual void begin_new_objects () { }
|
virtual void begin_new_objects () { }
|
||||||
virtual void create (const lay::ObjectInstPath & /*object*/, double /*dbu*/) { }
|
virtual void create (const lay::ObjectInstPath & /*object*/, const db::CplxTrans & /*view_trans*/) { }
|
||||||
virtual void end_new_objects () { }
|
virtual void end_new_objects () { }
|
||||||
virtual void commit_create () { }
|
virtual void commit_create () { }
|
||||||
virtual void end_create () { }
|
virtual void end_create () { }
|
||||||
|
|
||||||
// modification protocol
|
// modification protocol
|
||||||
virtual void begin_modify (lay::LayoutView * /*view*/) { }
|
virtual void begin_modify (lay::LayoutViewBase * /*view*/) { }
|
||||||
virtual void begin_modifications () { }
|
virtual void begin_modifications () { }
|
||||||
virtual void modified (const lay::ObjectInstPath & /*object*/, double /*dbu*/) { }
|
virtual void modified (const lay::ObjectInstPath & /*object*/, const db::CplxTrans & /*view_trans*/) { }
|
||||||
virtual void end_modifications () { }
|
virtual void end_modifications () { }
|
||||||
virtual void commit_modify () { }
|
virtual void commit_modify () { }
|
||||||
virtual void end_modify () { }
|
virtual void end_modify () { }
|
||||||
|
|
||||||
// editing protocol
|
// editing protocol
|
||||||
virtual void begin_edit (lay::LayoutView * /*view*/) { }
|
virtual void begin_edit (lay::LayoutViewBase * /*view*/) { }
|
||||||
virtual void begin_edits () { }
|
virtual void begin_edits () { }
|
||||||
virtual void transformed (const lay::ObjectInstPath & /*object*/, const db::DCplxTrans & /*trans*/, double /*dbu*/) { }
|
virtual void transformed (const lay::ObjectInstPath & /*object*/, const db::ICplxTrans & /*applied*/, const db::CplxTrans & /*view_trans*/) { }
|
||||||
virtual void end_edits () { }
|
virtual void end_edits () { }
|
||||||
virtual void commit_edit () { }
|
virtual void commit_edit () { }
|
||||||
virtual void end_edit () { }
|
virtual void end_edit () { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the name
|
||||||
|
*/
|
||||||
|
const std::string &name () const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the name
|
||||||
|
*/
|
||||||
|
void set_name (const std::string &name)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the technology name this hook is associated with
|
* @brief Gets the technology name this hook is associated with
|
||||||
*
|
*
|
||||||
|
|
@ -146,7 +167,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Registers the editor hook
|
* @brief Registers the editor hook
|
||||||
*/
|
*/
|
||||||
static void register_editor_hook (EditorHooks *hook);
|
static void register_editor_hooks (EditorHooks *hooks, const std::string &name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the editor hooks for a given technology
|
* @brief Gets the editor hooks for a given technology
|
||||||
|
|
@ -157,6 +178,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::set<std::string> m_technologies;
|
std::set<std::string> m_technologies;
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
// no copying.
|
// no copying.
|
||||||
EditorHooks &operator= (const EditorHooks &);
|
EditorHooks &operator= (const EditorHooks &);
|
||||||
|
|
@ -171,15 +193,17 @@ inline
|
||||||
void call_editor_hooks (const tl::weak_collection<EditorHooks> &hooks, void (EditorHooks::*meth) ())
|
void call_editor_hooks (const tl::weak_collection<EditorHooks> &hooks, void (EditorHooks::*meth) ())
|
||||||
{
|
{
|
||||||
for (auto h = hooks.begin (); h != hooks.end (); ++h) {
|
for (auto h = hooks.begin (); h != hooks.end (); ++h) {
|
||||||
BEGIN_PROTECTED
|
|
||||||
try {
|
try {
|
||||||
if (h.operator-> ()) {
|
if (h.operator-> ()) {
|
||||||
(const_cast<EditorHooks *> (h.operator-> ())->*meth) ();
|
(const_cast<EditorHooks *> (h.operator-> ())->*meth) ();
|
||||||
}
|
}
|
||||||
} catch (tl::CancelException &) {
|
} catch (tl::CancelException &) {
|
||||||
return;
|
return;
|
||||||
|
} catch (tl::Exception &ex) {
|
||||||
|
tl::error << ex.msg ();
|
||||||
|
} catch (std::exception &ex) {
|
||||||
|
tl::error << ex.what ();
|
||||||
}
|
}
|
||||||
END_PROTECTED
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,15 +218,17 @@ inline
|
||||||
void call_editor_hooks (const tl::weak_collection<EditorHooks> &hooks, void (EditorHooks::*meth) (A1), A1 a1)
|
void call_editor_hooks (const tl::weak_collection<EditorHooks> &hooks, void (EditorHooks::*meth) (A1), A1 a1)
|
||||||
{
|
{
|
||||||
for (auto h = hooks.begin (); h != hooks.end (); ++h) {
|
for (auto h = hooks.begin (); h != hooks.end (); ++h) {
|
||||||
BEGIN_PROTECTED
|
|
||||||
try {
|
try {
|
||||||
if (h.operator-> ()) {
|
if (h.operator-> ()) {
|
||||||
(const_cast<EditorHooks *> (h.operator-> ())->*meth) (a1);
|
(const_cast<EditorHooks *> (h.operator-> ())->*meth) (a1);
|
||||||
}
|
}
|
||||||
} catch (tl::CancelException &) {
|
} catch (tl::CancelException &) {
|
||||||
return;
|
return;
|
||||||
|
} catch (tl::Exception &ex) {
|
||||||
|
tl::error << ex.msg ();
|
||||||
|
} catch (std::exception &ex) {
|
||||||
|
tl::error << ex.what ();
|
||||||
}
|
}
|
||||||
END_PROTECTED
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,15 +243,17 @@ inline
|
||||||
void call_editor_hooks (const tl::weak_collection<EditorHooks> &hooks, void (EditorHooks::*meth) (A1, A2), A1 a1, A2 a2)
|
void call_editor_hooks (const tl::weak_collection<EditorHooks> &hooks, void (EditorHooks::*meth) (A1, A2), A1 a1, A2 a2)
|
||||||
{
|
{
|
||||||
for (auto h = hooks.begin (); h != hooks.end (); ++h) {
|
for (auto h = hooks.begin (); h != hooks.end (); ++h) {
|
||||||
BEGIN_PROTECTED
|
|
||||||
try {
|
try {
|
||||||
if (h.operator-> ()) {
|
if (h.operator-> ()) {
|
||||||
(const_cast<EditorHooks *> (h.operator-> ())->*meth) (a1, a2);
|
(const_cast<EditorHooks *> (h.operator-> ())->*meth) (a1, a2);
|
||||||
}
|
}
|
||||||
} catch (tl::CancelException &) {
|
} catch (tl::CancelException &) {
|
||||||
return;
|
return;
|
||||||
|
} catch (tl::Exception &ex) {
|
||||||
|
tl::error << ex.msg ();
|
||||||
|
} catch (std::exception &ex) {
|
||||||
|
tl::error << ex.what ();
|
||||||
}
|
}
|
||||||
END_PROTECTED
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,15 +268,17 @@ inline
|
||||||
void call_editor_hooks (const tl::weak_collection<EditorHooks> &hooks, void (EditorHooks::*meth) (A1, A2), A1 a1, A2 a2, A3 a3)
|
void call_editor_hooks (const tl::weak_collection<EditorHooks> &hooks, void (EditorHooks::*meth) (A1, A2), A1 a1, A2 a2, A3 a3)
|
||||||
{
|
{
|
||||||
for (auto h = hooks.begin (); h != hooks.end (); ++h) {
|
for (auto h = hooks.begin (); h != hooks.end (); ++h) {
|
||||||
BEGIN_PROTECTED
|
|
||||||
try {
|
try {
|
||||||
if (h.operator-> ()) {
|
if (h.operator-> ()) {
|
||||||
(const_cast<EditorHooks *> (h.operator-> ())->*meth) (a1, a2, a3);
|
(const_cast<EditorHooks *> (h.operator-> ())->*meth) (a1, a2, a3);
|
||||||
}
|
}
|
||||||
} catch (tl::CancelException &) {
|
} catch (tl::CancelException &) {
|
||||||
return;
|
return;
|
||||||
|
} catch (tl::Exception &ex) {
|
||||||
|
tl::error << ex.msg ();
|
||||||
|
} catch (std::exception &ex) {
|
||||||
|
tl::error << ex.what ();
|
||||||
}
|
}
|
||||||
END_PROTECTED
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ ShapeEditService::get_edit_layer ()
|
||||||
m_cv_index = (unsigned int) cv_index;
|
m_cv_index = (unsigned int) cv_index;
|
||||||
m_trans = (cl->trans ().front () * db::CplxTrans (cv->layout ().dbu ()) * cv.context_trans ()).inverted ();
|
m_trans = (cl->trans ().front () * db::CplxTrans (cv->layout ().dbu ()) * cv.context_trans ()).inverted ();
|
||||||
mp_layout = &(cv->layout ());
|
mp_layout = &(cv->layout ());
|
||||||
mp_cell = &(mp_layout->cell (cv.cell_index ()));
|
mp_cell = cv.cell ();
|
||||||
|
|
||||||
if (mp_cell->is_proxy ()) {
|
if (mp_cell->is_proxy ()) {
|
||||||
throw tl::Exception (tl::to_string (tr ("Cannot put a shape into a PCell or library cell")));
|
throw tl::Exception (tl::to_string (tr ("Cannot put a shape into a PCell or library cell")));
|
||||||
|
|
@ -157,7 +157,7 @@ ShapeEditService::update_edit_layer (const lay::LayerPropertiesConstIterator &cl
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cv->layout ().cell (cv.cell_index ()).is_proxy ()) {
|
if (cv.cell ()->is_proxy ()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,7 +198,7 @@ ShapeEditService::update_edit_layer (const lay::LayerPropertiesConstIterator &cl
|
||||||
m_cv_index = (unsigned int) cv_index;
|
m_cv_index = (unsigned int) cv_index;
|
||||||
m_trans = (cl->trans ().front () * db::CplxTrans (cv->layout ().dbu ()) * cv.context_trans ()).inverted ();
|
m_trans = (cl->trans ().front () * db::CplxTrans (cv->layout ().dbu ()) * cv.context_trans ()).inverted ();
|
||||||
mp_layout = &(cv->layout ());
|
mp_layout = &(cv->layout ());
|
||||||
mp_cell = &(mp_layout->cell (cv.cell_index ()));
|
mp_cell = cv.cell ();
|
||||||
|
|
||||||
current_layer_changed ();
|
current_layer_changed ();
|
||||||
}
|
}
|
||||||
|
|
@ -400,6 +400,62 @@ ShapeEditService::deliver_shape (const db::Point &point)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShapeEditService::open_editor_hooks ()
|
||||||
|
{
|
||||||
|
std::string technology;
|
||||||
|
if (mp_layout && mp_layout->technology ()) {
|
||||||
|
technology = mp_layout->technology ()->name ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: this is a kind of hack - as we want to present the new shape in some
|
||||||
|
// natural habitat (aka Shapes), we create an artificial Shapes container for holding the
|
||||||
|
// temporary object.
|
||||||
|
m_tmp_shapes.reset (new db::Shapes (0, mp_cell, true));
|
||||||
|
|
||||||
|
m_editor_hooks = edt::EditorHooks::get_editor_hooks (technology);
|
||||||
|
call_editor_hooks (m_editor_hooks, &edt::EditorHooks::begin_create, view ());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShapeEditService::close_editor_hooks (bool with_commit)
|
||||||
|
{
|
||||||
|
if (with_commit) {
|
||||||
|
call_editor_hooks (m_editor_hooks, &edt::EditorHooks::commit_create);
|
||||||
|
}
|
||||||
|
call_editor_hooks (m_editor_hooks, &edt::EditorHooks::end_create);
|
||||||
|
|
||||||
|
m_editor_hooks.clear ();
|
||||||
|
m_tmp_shapes.reset (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Shape>
|
||||||
|
void
|
||||||
|
ShapeEditService::deliver_shape_to_hooks (const Shape &shape)
|
||||||
|
{
|
||||||
|
if (! mp_cell || ! m_tmp_shapes.get ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_tmp_shapes->clear ();
|
||||||
|
db::Shape s = m_tmp_shapes->insert (shape);
|
||||||
|
|
||||||
|
lay::ObjectInstPath path;
|
||||||
|
path.set_cv_index (m_cv_index);
|
||||||
|
path.set_layer (m_layer);
|
||||||
|
path.set_topcell (mp_cell->cell_index ());
|
||||||
|
path.set_shape (s);
|
||||||
|
|
||||||
|
call_editor_hooks<const lay::ObjectInstPath &, const db::CplxTrans &> (m_editor_hooks, &edt::EditorHooks::create, path, trans ().inverted ());
|
||||||
|
}
|
||||||
|
|
||||||
|
// explicit instantiations
|
||||||
|
template void ShapeEditService::deliver_shape_to_hooks<db::Polygon> (const db::Polygon &);
|
||||||
|
template void ShapeEditService::deliver_shape_to_hooks<db::Path> (const db::Path &);
|
||||||
|
template void ShapeEditService::deliver_shape_to_hooks<db::Box> (const db::Box &);
|
||||||
|
template void ShapeEditService::deliver_shape_to_hooks<db::Point> (const db::Point &);
|
||||||
|
template void ShapeEditService::deliver_shape_to_hooks<db::Text> (const db::Text &);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// PolygonService implementation
|
// PolygonService implementation
|
||||||
|
|
||||||
|
|
@ -433,6 +489,8 @@ PolygonService::do_begin_edit (const db::DPoint &p)
|
||||||
m_points.push_back (pp);
|
m_points.push_back (pp);
|
||||||
m_closure_set = false;
|
m_closure_set = false;
|
||||||
|
|
||||||
|
open_editor_hooks ();
|
||||||
|
|
||||||
update_marker ();
|
update_marker ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -503,26 +561,30 @@ PolygonService::do_mouse_click (const db::DPoint &p)
|
||||||
void
|
void
|
||||||
PolygonService::do_finish_edit ()
|
PolygonService::do_finish_edit ()
|
||||||
{
|
{
|
||||||
deliver_shape (get_polygon ());
|
deliver_shape (get_polygon (false));
|
||||||
commit_recent (view ());
|
commit_recent (view ());
|
||||||
|
close_editor_hooks (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
db::Polygon
|
db::Polygon
|
||||||
PolygonService::get_polygon () const
|
PolygonService::get_polygon (bool all_points) const
|
||||||
{
|
{
|
||||||
db::Polygon poly;
|
db::Polygon poly;
|
||||||
|
|
||||||
if (m_points.size () < 4) {
|
if (m_points.size () + (m_closure_set ? 1 : 0) < (all_points ? 3 : 4)) {
|
||||||
throw tl::Exception (tl::to_string (tr ("A polygon must have at least 3 points")));
|
throw tl::Exception (tl::to_string (tr ("A polygon must have at least 3 points")));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<db::Point> points_dbu;
|
std::vector<db::Point> points_dbu;
|
||||||
points_dbu.reserve (m_points.size ());
|
points_dbu.reserve (m_points.size () + 1);
|
||||||
|
|
||||||
// one point is reserved for the current one
|
// one point is reserved for the current one
|
||||||
for (std::vector<db::DPoint>::const_iterator p = m_points.begin (); p + 1 != m_points.end (); ++p) {
|
for (std::vector<db::DPoint>::const_iterator p = m_points.begin (); p + 1 != m_points.end (); ++p) {
|
||||||
points_dbu.push_back (trans () * *p);
|
points_dbu.push_back (trans () * *p);
|
||||||
}
|
}
|
||||||
|
if (all_points) {
|
||||||
|
points_dbu.push_back (trans () * m_points.back ());
|
||||||
|
}
|
||||||
if (m_closure_set) {
|
if (m_closure_set) {
|
||||||
points_dbu.push_back (trans () * m_closure);
|
points_dbu.push_back (trans () * m_closure);
|
||||||
}
|
}
|
||||||
|
|
@ -539,7 +601,7 @@ PolygonService::get_polygon () const
|
||||||
void
|
void
|
||||||
PolygonService::do_cancel_edit ()
|
PolygonService::do_cancel_edit ()
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
close_editor_hooks (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -732,6 +794,17 @@ PolygonService::update_marker ()
|
||||||
std::string (" l: ") +
|
std::string (" l: ") +
|
||||||
tl::micron_to_string (m_points.back ().distance (m_points.end () [-2])));
|
tl::micron_to_string (m_points.back ().distance (m_points.end () [-2])));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call hooks with new shape
|
||||||
|
if (! editor_hooks ().empty ()) {
|
||||||
|
call_editor_hooks (editor_hooks (), &edt::EditorHooks::begin_new_objects);
|
||||||
|
try {
|
||||||
|
deliver_shape_to_hooks (get_polygon (true));
|
||||||
|
} catch (...) {
|
||||||
|
// ignore exceptions
|
||||||
|
}
|
||||||
|
call_editor_hooks (editor_hooks (), &edt::EditorHooks::end_new_objects);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
@ -761,6 +834,8 @@ BoxService::do_begin_edit (const db::DPoint &p)
|
||||||
db::DPoint pp = snap2 (p);
|
db::DPoint pp = snap2 (p);
|
||||||
m_p1 = m_p2 = pp;
|
m_p1 = m_p2 = pp;
|
||||||
|
|
||||||
|
open_editor_hooks ();
|
||||||
|
|
||||||
set_edit_marker (new lay::Marker (view (), cv_index ()));
|
set_edit_marker (new lay::Marker (view (), cv_index ()));
|
||||||
update_marker ();
|
update_marker ();
|
||||||
}
|
}
|
||||||
|
|
@ -785,6 +860,17 @@ BoxService::update_marker ()
|
||||||
tl::micron_to_string (m_p2.y () - m_p1.y ()));
|
tl::micron_to_string (m_p2.y () - m_p1.y ()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call hooks with new shape
|
||||||
|
if (! editor_hooks ().empty ()) {
|
||||||
|
call_editor_hooks (editor_hooks (), &edt::EditorHooks::begin_new_objects);
|
||||||
|
try {
|
||||||
|
deliver_shape_to_hooks (get_box ());
|
||||||
|
} catch (...) {
|
||||||
|
// ignore exceptions
|
||||||
|
}
|
||||||
|
call_editor_hooks (editor_hooks (), &edt::EditorHooks::end_new_objects);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -816,12 +902,13 @@ BoxService::do_finish_edit ()
|
||||||
{
|
{
|
||||||
deliver_shape (get_box ());
|
deliver_shape (get_box ());
|
||||||
commit_recent (view ());
|
commit_recent (view ());
|
||||||
|
close_editor_hooks (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BoxService::do_cancel_edit ()
|
BoxService::do_cancel_edit ()
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
close_editor_hooks (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -857,6 +944,8 @@ PointService::do_begin_edit (const db::DPoint &p)
|
||||||
db::DPoint pp = snap2 (p);
|
db::DPoint pp = snap2 (p);
|
||||||
m_p = pp;
|
m_p = pp;
|
||||||
|
|
||||||
|
open_editor_hooks ();
|
||||||
|
|
||||||
set_edit_marker (new lay::Marker (view (), cv_index ()));
|
set_edit_marker (new lay::Marker (view (), cv_index ()));
|
||||||
update_marker ();
|
update_marker ();
|
||||||
}
|
}
|
||||||
|
|
@ -882,6 +971,17 @@ PointService::update_marker ()
|
||||||
tl::micron_to_string (m_p.y ()));
|
tl::micron_to_string (m_p.y ()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call hooks with new shape
|
||||||
|
if (! editor_hooks ().empty ()) {
|
||||||
|
call_editor_hooks (editor_hooks (), &edt::EditorHooks::begin_new_objects);
|
||||||
|
try {
|
||||||
|
deliver_shape_to_hooks (get_point ());
|
||||||
|
} catch (...) {
|
||||||
|
// ignore exceptions
|
||||||
|
}
|
||||||
|
call_editor_hooks (editor_hooks (), &edt::EditorHooks::end_new_objects);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -913,12 +1013,13 @@ PointService::do_finish_edit ()
|
||||||
{
|
{
|
||||||
deliver_shape (get_point ());
|
deliver_shape (get_point ());
|
||||||
commit_recent (view ());
|
commit_recent (view ());
|
||||||
|
close_editor_hooks (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PointService::do_cancel_edit ()
|
PointService::do_cancel_edit ()
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
close_editor_hooks (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -959,6 +1060,8 @@ TextService::do_begin_edit (const db::DPoint &p)
|
||||||
|
|
||||||
m_text.trans (db::DTrans (m_rot, snap2 (p) - db::DPoint ()));
|
m_text.trans (db::DTrans (m_rot, snap2 (p) - db::DPoint ()));
|
||||||
|
|
||||||
|
open_editor_hooks ();
|
||||||
|
|
||||||
lay::DMarker *marker = new lay::DMarker (view ());
|
lay::DMarker *marker = new lay::DMarker (view ());
|
||||||
marker->set_vertex_shape (lay::ViewOp::Cross);
|
marker->set_vertex_shape (lay::ViewOp::Cross);
|
||||||
marker->set_vertex_size (9 /*cross vertex size*/);
|
marker->set_vertex_size (9 /*cross vertex size*/);
|
||||||
|
|
@ -985,6 +1088,17 @@ TextService::update_marker ()
|
||||||
view ()->message (pos);
|
view ()->message (pos);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call hooks with new shape
|
||||||
|
if (! editor_hooks ().empty ()) {
|
||||||
|
call_editor_hooks (editor_hooks (), &edt::EditorHooks::begin_new_objects);
|
||||||
|
try {
|
||||||
|
deliver_shape_to_hooks (get_text ());
|
||||||
|
} catch (...) {
|
||||||
|
// ignore exceptions
|
||||||
|
}
|
||||||
|
call_editor_hooks (editor_hooks (), &edt::EditorHooks::end_new_objects);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -1065,12 +1179,14 @@ TextService::do_finish_edit ()
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
close_editor_hooks (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TextService::do_cancel_edit ()
|
TextService::do_cancel_edit ()
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
close_editor_hooks (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -1166,6 +1282,8 @@ PathService::do_begin_edit (const db::DPoint &p)
|
||||||
m_points.push_back (pp);
|
m_points.push_back (pp);
|
||||||
m_points.push_back (pp);
|
m_points.push_back (pp);
|
||||||
|
|
||||||
|
open_editor_hooks ();
|
||||||
|
|
||||||
set_edit_marker (new lay::Marker (view (), cv_index ()));
|
set_edit_marker (new lay::Marker (view (), cv_index ()));
|
||||||
update_marker ();
|
update_marker ();
|
||||||
}
|
}
|
||||||
|
|
@ -1250,6 +1368,8 @@ PathService::do_finish_edit ()
|
||||||
deliver_shape (get_path ());
|
deliver_shape (get_path ());
|
||||||
|
|
||||||
commit_recent (view ());
|
commit_recent (view ());
|
||||||
|
|
||||||
|
close_editor_hooks (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1271,6 +1391,17 @@ PathService::update_marker ()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call hooks with new shape
|
||||||
|
if (! editor_hooks ().empty ()) {
|
||||||
|
call_editor_hooks (editor_hooks (), &edt::EditorHooks::begin_new_objects);
|
||||||
|
try {
|
||||||
|
deliver_shape_to_hooks (get_path ());
|
||||||
|
} catch (...) {
|
||||||
|
// ignore exceptions
|
||||||
|
}
|
||||||
|
call_editor_hooks (editor_hooks (), &edt::EditorHooks::end_new_objects);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
db::Path
|
db::Path
|
||||||
|
|
@ -1305,7 +1436,7 @@ PathService::get_path () const
|
||||||
void
|
void
|
||||||
PathService::do_cancel_edit ()
|
PathService::do_cancel_edit ()
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
close_editor_hooks (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -1582,6 +1713,8 @@ InstService::do_begin_edit (const db::DPoint &p)
|
||||||
m_trans = db::VCplxTrans (1.0 / cv->layout ().dbu ()) * tv [0] * db::CplxTrans (cv->layout ().dbu ()) * cv.context_trans ();
|
m_trans = db::VCplxTrans (1.0 / cv->layout ().dbu ()) * tv [0] * db::CplxTrans (cv->layout ().dbu ()) * cv.context_trans ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open_editor_hooks ();
|
||||||
|
|
||||||
update_marker ();
|
update_marker ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1756,7 +1889,7 @@ InstService::do_finish_edit ()
|
||||||
|
|
||||||
cv->layout ().cell (inst.object ().cell_index ()).collect_called_cells (called);
|
cv->layout ().cell (inst.object ().cell_index ()).collect_called_cells (called);
|
||||||
called.insert (inst.object ().cell_index ());
|
called.insert (inst.object ().cell_index ());
|
||||||
cv->layout ().cell (cv.cell_index ()).collect_caller_cells (callers);
|
cv.cell ()->collect_caller_cells (callers);
|
||||||
callers.insert (cv.cell_index ());
|
callers.insert (cv.cell_index ());
|
||||||
|
|
||||||
std::vector <db::cell_index_type> intersection;
|
std::vector <db::cell_index_type> intersection;
|
||||||
|
|
@ -1769,7 +1902,7 @@ InstService::do_finish_edit ()
|
||||||
manager ()->transaction (tl::to_string (tr ("Create instance")), m_reference_transaction_id);
|
manager ()->transaction (tl::to_string (tr ("Create instance")), m_reference_transaction_id);
|
||||||
}
|
}
|
||||||
m_reference_transaction_id = 0;
|
m_reference_transaction_id = 0;
|
||||||
db::Instance i = cv->layout ().cell (cv.cell_index ()).insert (inst);
|
db::Instance i = cv.cell ()->insert (inst);
|
||||||
cv->layout ().cleanup ();
|
cv->layout ().cleanup ();
|
||||||
if (manager ()) {
|
if (manager ()) {
|
||||||
manager ()->commit ();
|
manager ()->commit ();
|
||||||
|
|
@ -1792,10 +1925,12 @@ InstService::do_finish_edit ()
|
||||||
|
|
||||||
m_has_valid_cell = false;
|
m_has_valid_cell = false;
|
||||||
m_in_drag_drop = false;
|
m_in_drag_drop = false;
|
||||||
|
close_editor_hooks (true);
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
m_has_valid_cell = false;
|
m_has_valid_cell = false;
|
||||||
m_in_drag_drop = false;
|
m_in_drag_drop = false;
|
||||||
|
close_editor_hooks (false);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1819,6 +1954,8 @@ InstService::do_cancel_edit ()
|
||||||
if (cv.is_valid ()) {
|
if (cv.is_valid ()) {
|
||||||
cv->layout ().cleanup ();
|
cv->layout ().cleanup ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close_editor_hooks (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -2128,6 +2265,41 @@ InstService::update_marker ()
|
||||||
} else {
|
} else {
|
||||||
set_edit_marker (0);
|
set_edit_marker (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call hooks with new shape
|
||||||
|
if (! editor_hooks ().empty ()) {
|
||||||
|
|
||||||
|
call_editor_hooks (editor_hooks (), &edt::EditorHooks::begin_new_objects);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
const lay::CellView &cv = view ()->cellview (m_cv_index);
|
||||||
|
|
||||||
|
db::CellInstArray inst;
|
||||||
|
if (cv.is_valid () && get_inst (inst)) {
|
||||||
|
|
||||||
|
// Note: we create a temporary instance collection and a temporary
|
||||||
|
// ObjectInstPath object there, so
|
||||||
|
db::Instances instances (cv.cell ());
|
||||||
|
|
||||||
|
lay::ObjectInstPath path;
|
||||||
|
path.set_cv_index (m_cv_index);
|
||||||
|
path.set_topcell (cv.cell_index ());
|
||||||
|
path.add_path (db::InstElement (instances.insert (inst)));
|
||||||
|
|
||||||
|
db::CplxTrans view_trans = db::CplxTrans (cv->layout ().dbu ()) * m_trans;
|
||||||
|
|
||||||
|
call_editor_hooks<const lay::ObjectInstPath &, const db::CplxTrans &> (m_editor_hooks, &edt::EditorHooks::create, path, view_trans);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (...) {
|
||||||
|
// ignore exceptions
|
||||||
|
}
|
||||||
|
|
||||||
|
call_editor_hooks (editor_hooks (), &edt::EditorHooks::end_new_objects);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -2159,6 +2331,34 @@ InstService::get_inst (db::CellInstArray &inst)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InstService::open_editor_hooks ()
|
||||||
|
{
|
||||||
|
const lay::CellView &cv = view ()->cellview (m_cv_index);
|
||||||
|
if (! cv.is_valid ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string technology;
|
||||||
|
if (cv->layout ().technology ()) {
|
||||||
|
technology = cv->layout ().technology ()->name ();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_editor_hooks = edt::EditorHooks::get_editor_hooks (technology);
|
||||||
|
call_editor_hooks (m_editor_hooks, &edt::EditorHooks::begin_create, view ());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InstService::close_editor_hooks (bool with_commit)
|
||||||
|
{
|
||||||
|
if (with_commit) {
|
||||||
|
call_editor_hooks (m_editor_hooks, &edt::EditorHooks::commit_create);
|
||||||
|
}
|
||||||
|
call_editor_hooks (m_editor_hooks, &edt::EditorHooks::end_create);
|
||||||
|
|
||||||
|
m_editor_hooks.clear ();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace edt
|
} // namespace edt
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include "edtService.h"
|
#include "edtService.h"
|
||||||
#include "edtConfig.h"
|
#include "edtConfig.h"
|
||||||
|
#include "edtEditorHooks.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|
@ -68,6 +69,16 @@ protected:
|
||||||
void deliver_shape (const db::Path &path);
|
void deliver_shape (const db::Path &path);
|
||||||
void deliver_shape (const db::Box &box);
|
void deliver_shape (const db::Box &box);
|
||||||
void deliver_shape (const db::Point &point);
|
void deliver_shape (const db::Point &point);
|
||||||
|
void open_editor_hooks ();
|
||||||
|
template <class Shape>
|
||||||
|
void deliver_shape_to_hooks (const Shape &shape);
|
||||||
|
void close_editor_hooks (bool with_commit);
|
||||||
|
|
||||||
|
const tl::weak_collection<edt::EditorHooks> &editor_hooks ()
|
||||||
|
{
|
||||||
|
return m_editor_hooks;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void current_layer_changed () { }
|
virtual void current_layer_changed () { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -77,6 +88,8 @@ private:
|
||||||
db::Cell *mp_cell;
|
db::Cell *mp_cell;
|
||||||
db::Layout *mp_layout;
|
db::Layout *mp_layout;
|
||||||
combine_mode_type m_combine_mode;
|
combine_mode_type m_combine_mode;
|
||||||
|
tl::weak_collection<edt::EditorHooks> m_editor_hooks;
|
||||||
|
std::unique_ptr<db::Shapes> m_tmp_shapes;
|
||||||
|
|
||||||
void update_edit_layer (const lay::LayerPropertiesConstIterator &iter);
|
void update_edit_layer (const lay::LayerPropertiesConstIterator &iter);
|
||||||
};
|
};
|
||||||
|
|
@ -109,7 +122,7 @@ private:
|
||||||
db::DPoint m_last;
|
db::DPoint m_last;
|
||||||
|
|
||||||
void update_marker ();
|
void update_marker ();
|
||||||
db::Polygon get_polygon () const;
|
db::Polygon get_polygon (bool all_points) const;
|
||||||
void add_closure ();
|
void add_closure ();
|
||||||
void set_last_point (const db::DPoint &p);
|
void set_last_point (const db::DPoint &p);
|
||||||
};
|
};
|
||||||
|
|
@ -298,6 +311,7 @@ private:
|
||||||
const db::PCellDeclaration *mp_pcell_decl;
|
const db::PCellDeclaration *mp_pcell_decl;
|
||||||
int m_cv_index;
|
int m_cv_index;
|
||||||
db::ICplxTrans m_trans;
|
db::ICplxTrans m_trans;
|
||||||
|
tl::weak_collection<edt::EditorHooks> m_editor_hooks;
|
||||||
|
|
||||||
void update_marker ();
|
void update_marker ();
|
||||||
bool get_inst (db::CellInstArray &inst);
|
bool get_inst (db::CellInstArray &inst);
|
||||||
|
|
@ -305,6 +319,13 @@ private:
|
||||||
tl::Variant get_default_layer_for_pcell ();
|
tl::Variant get_default_layer_for_pcell ();
|
||||||
void sync_to_config ();
|
void sync_to_config ();
|
||||||
void switch_cell_or_pcell (bool switch_parameters);
|
void switch_cell_or_pcell (bool switch_parameters);
|
||||||
|
void open_editor_hooks ();
|
||||||
|
void close_editor_hooks (bool with_commit);
|
||||||
|
|
||||||
|
const tl::weak_collection<edt::EditorHooks> &editor_hooks ()
|
||||||
|
{
|
||||||
|
return m_editor_hooks;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,143 +28,21 @@
|
||||||
|
|
||||||
namespace gsi
|
namespace gsi
|
||||||
{
|
{
|
||||||
gsi::Class<edt::EditorHooks> decl_EditorHooksBase ("lay", "EditorHooksBase",
|
|
||||||
gsi::method ("begin_create", &edt::EditorHooks::begin_create, gsi::arg ("view"),
|
|
||||||
"@brief Creation protocol - begin session\n"
|
|
||||||
"This method is called to initiate an object creation session. The session is ended with "
|
|
||||||
"\\end_create. Between these calls, new objects are announced with \\begin_new_objects, "
|
|
||||||
"\\create and \\end_new_objects calls. These calls are repeated to indicate changes in the objects "
|
|
||||||
"created.\n"
|
|
||||||
"\n"
|
|
||||||
"\\commit_create is called once before \\end_create to indicate that the last set of "
|
|
||||||
"objects are committed to the database."
|
|
||||||
) +
|
|
||||||
gsi::method ("begin_new_objects", &edt::EditorHooks::begin_new_objects,
|
|
||||||
"@brief Creation protocol - begin new objects\n"
|
|
||||||
"See \\begin_create for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("create", &edt::EditorHooks::create, gsi::arg ("object"), gsi::arg ("dbu"),
|
|
||||||
"@brief Creation protocol - indicate a new object\n"
|
|
||||||
"See \\begin_create for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("end_new_objects", &edt::EditorHooks::end_new_objects,
|
|
||||||
"@brief Creation protocol - finish list of new objects\n"
|
|
||||||
"See \\begin_create for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("commit_create", &edt::EditorHooks::commit_create,
|
|
||||||
"@brief Creation protocol - commit new objects\n"
|
|
||||||
"See \\begin_create for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("end_create", &edt::EditorHooks::end_create,
|
|
||||||
"@brief Creation protocol - finish session\n"
|
|
||||||
"See \\begin_create for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("begin_modify", &edt::EditorHooks::begin_modify, gsi::arg ("view"),
|
|
||||||
"@brief Modification protocol - begin session\n"
|
|
||||||
"This method is called to initiate an object modification session. The session is ended with "
|
|
||||||
"\\end_modify. Between these calls, modified objects are announced with \\begin_modifications, "
|
|
||||||
"\\modified and \\end_modifications calls. These calls are repeated to indicate changes in the objects "
|
|
||||||
"modified while moving the mouse for example.\n"
|
|
||||||
"\n"
|
|
||||||
"\\commit_modify is called once before \\end_modify to indicate that the last set of "
|
|
||||||
"objects are committed to the database."
|
|
||||||
) +
|
|
||||||
gsi::method ("begin_modifications", &edt::EditorHooks::begin_modifications,
|
|
||||||
"@brief Modification protocol - begin modifications\n"
|
|
||||||
"See \\begin_modify for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("modified", &edt::EditorHooks::modified, gsi::arg ("object"), gsi::arg ("dbu"),
|
|
||||||
"@brief Modification protocol - indicate a modified object\n"
|
|
||||||
"See \\begin_modify for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("end_modifications", &edt::EditorHooks::end_modifications,
|
|
||||||
"@brief Modification protocol - finish list of modifications\n"
|
|
||||||
"See \\begin_modify for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("commit_modify", &edt::EditorHooks::commit_modify,
|
|
||||||
"@brief Modification protocol - commit new objects\n"
|
|
||||||
"See \\begin_modify for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("end_modify", &edt::EditorHooks::end_modify,
|
|
||||||
"@brief Modification protocol - finish session\n"
|
|
||||||
"See \\begin_modify for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("begin_edit", &edt::EditorHooks::begin_edit, gsi::arg ("view"),
|
|
||||||
"@brief Editing protocol - begin session\n"
|
|
||||||
"This method is called to initiate an object editing session. The session is ended with "
|
|
||||||
"\\end_edit. Between these calls, edits are announced with \\begin_edits, "
|
|
||||||
"\\transformed and \\end_edits calls. These calls are repeated to indicate changes in the objects "
|
|
||||||
"modified while moving the mouse for example.\n"
|
|
||||||
"\n"
|
|
||||||
"\\commit_edit is called once before \\end_edit to indicate that the last set of "
|
|
||||||
"objects are committed to the database."
|
|
||||||
) +
|
|
||||||
gsi::method ("begin_edits", &edt::EditorHooks::begin_edits,
|
|
||||||
"@brief Editing protocol - begin edits\n"
|
|
||||||
"See \\begin_edit for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("transformed", &edt::EditorHooks::transformed, gsi::arg ("object"), gsi::arg ("trans"), gsi::arg ("dbu"),
|
|
||||||
"@brief Editing protocol - indicate an object transformation\n"
|
|
||||||
"See \\begin_edit for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("end_edits", &edt::EditorHooks::end_edits,
|
|
||||||
"@brief Editing protocol - finish list of edits\n"
|
|
||||||
"See \\begin_edit for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("commit_edit", &edt::EditorHooks::commit_edit,
|
|
||||||
"@brief Editing protocol - commit new objects\n"
|
|
||||||
"See \\begin_edit for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("end_edit", &edt::EditorHooks::end_edit,
|
|
||||||
"@brief Editing protocol - finish session\n"
|
|
||||||
"See \\begin_edit for a description of the protocol."
|
|
||||||
) +
|
|
||||||
gsi::method ("technology=", &edt::EditorHooks::set_technology, gsi::arg ("technology"),
|
|
||||||
"@brief sets the name of the technology the hooks are associated with\n"
|
|
||||||
"This will clear all technology associations and associate the hooks with that technology only.\n"
|
|
||||||
) +
|
|
||||||
gsi::method ("clear_technologies", &edt::EditorHooks::clear_technologies,
|
|
||||||
"@brief Clears the list of technologies the hooks are associated with.\n"
|
|
||||||
"See also \\add_technology.\n"
|
|
||||||
) +
|
|
||||||
gsi::method ("add_technology", &edt::EditorHooks::add_technology, gsi::arg ("tech"),
|
|
||||||
"@brief Additionally associates the hooks with the given technology.\n"
|
|
||||||
"See also \\clear_technologies.\n"
|
|
||||||
) +
|
|
||||||
gsi::method ("is_for_technology", &edt::EditorHooks::is_for_technology, gsi::arg ("tech"),
|
|
||||||
"@brief Returns a value indicating whether the hooks are associated with the given technology.\n"
|
|
||||||
) +
|
|
||||||
gsi::method ("for_technologies", &edt::EditorHooks::for_technologies,
|
|
||||||
"@brief Returns a value indicating whether the hooks are associated with any technology.\n"
|
|
||||||
"The method is equivalent to checking whether the \\technologies list is empty.\n"
|
|
||||||
) +
|
|
||||||
gsi::method ("technologies", &edt::EditorHooks::get_technologies,
|
|
||||||
"@brief Gets the list of technologies these hooks are associated with.\n"
|
|
||||||
) +
|
|
||||||
gsi::method ("register", &edt::EditorHooks::register_editor_hook, gsi::arg ("hooks"),
|
|
||||||
"@brief Registers the hooks in the system.\n"
|
|
||||||
"The hooks will not be active before they are registered in the system. Registration will "
|
|
||||||
"also transfer object ownership to the system."
|
|
||||||
),
|
|
||||||
"@brief The base class for editor hooks\n"
|
|
||||||
"Editor hooks allow implementing technology-specific callbacks into the editor "
|
|
||||||
"for example to implement visual feedback about DRC rules.\n"
|
|
||||||
"\n"
|
|
||||||
"This class provides the basic interface. To implement callbacks, use the \\EditorHooks class."
|
|
||||||
"\n"
|
|
||||||
"The EditorHooksBase class has been introduced in version 0.29."
|
|
||||||
);
|
|
||||||
|
|
||||||
class EditorHooksImpl
|
class EditorHooksImpl
|
||||||
: public edt::EditorHooks
|
: public edt::EditorHooks
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EditorHooksImpl () { }
|
EditorHooksImpl ()
|
||||||
|
: edt::EditorHooks ()
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
virtual void begin_create (lay::LayoutView *view)
|
virtual void begin_create (lay::LayoutViewBase *view)
|
||||||
{
|
{
|
||||||
if (f_begin_create.can_issue ()) {
|
if (f_begin_create.can_issue ()) {
|
||||||
f_begin_create.issue<edt::EditorHooks, lay::LayoutView *> (&edt::EditorHooks::begin_create, view);
|
f_begin_create.issue<edt::EditorHooks, lay::LayoutViewBase *> (&edt::EditorHooks::begin_create, view);
|
||||||
} else {
|
} else {
|
||||||
edt::EditorHooks::begin_create (view);
|
edt::EditorHooks::begin_create (view);
|
||||||
}
|
}
|
||||||
|
|
@ -179,12 +57,12 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void create (const lay::ObjectInstPath &object, double dbu)
|
virtual void create (const lay::ObjectInstPath &object, const db::CplxTrans &view_trans)
|
||||||
{
|
{
|
||||||
if (f_create.can_issue ()) {
|
if (f_create.can_issue ()) {
|
||||||
f_create.issue<edt::EditorHooks, const lay::ObjectInstPath &, double> (&edt::EditorHooks::create, object, dbu);
|
f_create.issue<edt::EditorHooks, const lay::ObjectInstPath &, const db::CplxTrans &> (&edt::EditorHooks::create, object, view_trans);
|
||||||
} else {
|
} else {
|
||||||
edt::EditorHooks::create (object, dbu);
|
edt::EditorHooks::create (object, view_trans);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,10 +93,10 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void begin_modify (lay::LayoutView *view)
|
virtual void begin_modify (lay::LayoutViewBase *view)
|
||||||
{
|
{
|
||||||
if (f_begin_modify.can_issue ()) {
|
if (f_begin_modify.can_issue ()) {
|
||||||
f_begin_modify.issue<edt::EditorHooks, lay::LayoutView *> (&edt::EditorHooks::begin_modify, view);
|
f_begin_modify.issue<edt::EditorHooks, lay::LayoutViewBase *> (&edt::EditorHooks::begin_modify, view);
|
||||||
} else {
|
} else {
|
||||||
edt::EditorHooks::begin_modify (view);
|
edt::EditorHooks::begin_modify (view);
|
||||||
}
|
}
|
||||||
|
|
@ -233,12 +111,12 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void modified (const lay::ObjectInstPath &object, double dbu)
|
virtual void modified (const lay::ObjectInstPath &object, const db::CplxTrans &view_trans)
|
||||||
{
|
{
|
||||||
if (f_modified.can_issue ()) {
|
if (f_modified.can_issue ()) {
|
||||||
f_modified.issue<edt::EditorHooks, const lay::ObjectInstPath &, double> (&edt::EditorHooks::modified, object, dbu);
|
f_modified.issue<edt::EditorHooks, const lay::ObjectInstPath &, const db::CplxTrans &> (&edt::EditorHooks::modified, object, view_trans);
|
||||||
} else {
|
} else {
|
||||||
edt::EditorHooks::modified (object, dbu);
|
edt::EditorHooks::modified (object, view_trans);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -269,10 +147,10 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void begin_edit (lay::LayoutView *view)
|
virtual void begin_edit (lay::LayoutViewBase *view)
|
||||||
{
|
{
|
||||||
if (f_begin_edit.can_issue ()) {
|
if (f_begin_edit.can_issue ()) {
|
||||||
f_begin_edit.issue<edt::EditorHooks, lay::LayoutView *> (&edt::EditorHooks::begin_edit, view);
|
f_begin_edit.issue<edt::EditorHooks, lay::LayoutViewBase *> (&edt::EditorHooks::begin_edit, view);
|
||||||
} else {
|
} else {
|
||||||
edt::EditorHooks::begin_edit (view);
|
edt::EditorHooks::begin_edit (view);
|
||||||
}
|
}
|
||||||
|
|
@ -287,12 +165,12 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void transformed (const lay::ObjectInstPath &object, const db::DCplxTrans &trans, double dbu)
|
virtual void transformed (const lay::ObjectInstPath &object, const db::ICplxTrans &applied_trans, const db::CplxTrans &view_trans)
|
||||||
{
|
{
|
||||||
if (f_transformed.can_issue ()) {
|
if (f_transformed.can_issue ()) {
|
||||||
f_transformed.issue<edt::EditorHooks, const lay::ObjectInstPath &, const db::DCplxTrans &, double> (&edt::EditorHooks::transformed, object, trans, dbu);
|
f_transformed.issue<edt::EditorHooks, const lay::ObjectInstPath &, const db::ICplxTrans &, const db::CplxTrans &> (&edt::EditorHooks::transformed, object, applied_trans, view_trans);
|
||||||
} else {
|
} else {
|
||||||
edt::EditorHooks::transformed (object, trans, dbu);
|
edt::EditorHooks::transformed (object, applied_trans, view_trans);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -345,12 +223,149 @@ public:
|
||||||
gsi::Callback f_end_edit;
|
gsi::Callback f_end_edit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void register_editor_hooks (EditorHooksImpl *hooks, const std::string &name)
|
||||||
|
{
|
||||||
|
edt::EditorHooks::register_editor_hooks (hooks, name);
|
||||||
|
}
|
||||||
|
|
||||||
gsi::Class<EditorHooksImpl> decl_EditorHooks ("lay", "EditorHooks",
|
gsi::Class<EditorHooksImpl> decl_EditorHooks ("lay", "EditorHooks",
|
||||||
callback ("begin_create", &EditorHooksImpl::begin_create, &EditorHooksImpl::f_begin_create,
|
gsi::callback ("begin_create", &EditorHooksImpl::begin_create, &EditorHooksImpl::f_begin_create,
|
||||||
"@brief Creation protocol - begin session\n"
|
"@brief Creation protocol - begin session\n"
|
||||||
"See \\EditorHooksBase for a description of the protocol"
|
"This method is called to initiate an object creation session. The session is ended with "
|
||||||
|
"\\end_create. Between these calls, new objects are announced with \\begin_new_objects, "
|
||||||
|
"\\create and \\end_new_objects calls. These calls are repeated to indicate changes in the objects "
|
||||||
|
"created.\n"
|
||||||
|
"\n"
|
||||||
|
"\\commit_create is called once before \\end_create to indicate that the last set of "
|
||||||
|
"objects are committed to the database."
|
||||||
|
) +
|
||||||
|
gsi::callback ("begin_new_objects", &EditorHooksImpl::begin_new_objects, &EditorHooksImpl::f_begin_new_objects,
|
||||||
|
"@brief Creation protocol - begin new objects\n"
|
||||||
|
"See \\begin_create for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::callback ("create", &EditorHooksImpl::create, &EditorHooksImpl::f_create, gsi::arg ("object"), gsi::arg ("view_trans"),
|
||||||
|
"@brief Creation protocol - indicate a new object\n"
|
||||||
|
"See \\begin_create for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::callback ("end_new_objects", &EditorHooksImpl::end_new_objects, &EditorHooksImpl::f_end_new_objects,
|
||||||
|
"@brief Creation protocol - finish list of new objects\n"
|
||||||
|
"See \\begin_create for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::callback ("commit_create", &EditorHooksImpl::commit_create, &EditorHooksImpl::f_commit_create,
|
||||||
|
"@brief Creation protocol - commit new objects\n"
|
||||||
|
"See \\begin_create for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::callback ("end_create", &EditorHooksImpl::end_create, &EditorHooksImpl::f_end_create,
|
||||||
|
"@brief Creation protocol - finish session\n"
|
||||||
|
"See \\begin_create for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::callback ("begin_modify", &EditorHooksImpl::begin_modify, &EditorHooksImpl::f_begin_modify, gsi::arg ("view"),
|
||||||
|
"@brief Modification protocol - begin session\n"
|
||||||
|
"This method is called to initiate an object modification session. The session is ended with "
|
||||||
|
"\\end_modify. Between these calls, modified objects are announced with \\begin_modifications, "
|
||||||
|
"\\modified and \\end_modifications calls. These calls are repeated to indicate changes in the objects "
|
||||||
|
"modified while moving the mouse for example.\n"
|
||||||
|
"\n"
|
||||||
|
"\\commit_modify is called once before \\end_modify to indicate that the last set of "
|
||||||
|
"objects are committed to the database."
|
||||||
|
) +
|
||||||
|
gsi::callback ("begin_modifications", &EditorHooksImpl::begin_modifications, &EditorHooksImpl::f_begin_modifications,
|
||||||
|
"@brief Modification protocol - begin modifications\n"
|
||||||
|
"See \\begin_modify for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::callback ("modified", &EditorHooksImpl::modified, &EditorHooksImpl::f_modified, gsi::arg ("object"), gsi::arg ("view_trans"),
|
||||||
|
"@brief Modification protocol - indicate a modified object\n"
|
||||||
|
"See \\begin_modify for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::callback ("end_modifications", &EditorHooksImpl::end_modifications, &EditorHooksImpl::f_end_modifications,
|
||||||
|
"@brief Modification protocol - finish list of modifications\n"
|
||||||
|
"See \\begin_modify for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::callback ("commit_modify", &EditorHooksImpl::commit_modify, &EditorHooksImpl::f_commit_modify,
|
||||||
|
"@brief Modification protocol - commit new objects\n"
|
||||||
|
"See \\begin_modify for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::callback ("end_modify", &EditorHooksImpl::end_modify, &EditorHooksImpl::f_end_modify,
|
||||||
|
"@brief Modification protocol - finish session\n"
|
||||||
|
"See \\begin_modify for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::callback ("begin_edit", &EditorHooksImpl::begin_edit, &EditorHooksImpl::f_begin_edit, gsi::arg ("view"),
|
||||||
|
"@brief Editing protocol - begin session\n"
|
||||||
|
"This method is called to initiate an object editing session. The session is ended with "
|
||||||
|
"\\end_edit. Between these calls, edits are announced with \\begin_edits, "
|
||||||
|
"\\transformed and \\end_edits calls. These calls are repeated to indicate changes in the objects "
|
||||||
|
"modified while moving the mouse for example.\n"
|
||||||
|
"\n"
|
||||||
|
"\\commit_edit is called once before \\end_edit to indicate that the last set of "
|
||||||
|
"objects are committed to the database."
|
||||||
|
) +
|
||||||
|
gsi::callback ("begin_edits", &EditorHooksImpl::begin_edits, &EditorHooksImpl::f_begin_edits,
|
||||||
|
"@brief Editing protocol - begin edits\n"
|
||||||
|
"See \\begin_edit for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::callback ("transformed", &EditorHooksImpl::transformed, &EditorHooksImpl::f_transformed, gsi::arg ("object"), gsi::arg ("applied_trans"), gsi::arg ("view_trans"),
|
||||||
|
"@brief Editing protocol - indicate an object transformation\n"
|
||||||
|
"See \\begin_edit for a description of the protocol.\n"
|
||||||
|
"\n"
|
||||||
|
"@param object A path to the modified object\n"
|
||||||
|
"@param applied_trans The DBU-space of the transformation applied to the object\n"
|
||||||
|
"@param view_trans The combined transformation of DBU space to view space\n"
|
||||||
|
) +
|
||||||
|
gsi::callback ("end_edits", &EditorHooksImpl::end_edits, &EditorHooksImpl::f_end_edits,
|
||||||
|
"@brief Editing protocol - finish list of edits\n"
|
||||||
|
"See \\begin_edit for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::callback ("commit_edit", &EditorHooksImpl::commit_edit, &EditorHooksImpl::f_commit_edit,
|
||||||
|
"@brief Editing protocol - commit new objects\n"
|
||||||
|
"See \\begin_edit for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::callback ("end_edit", &EditorHooksImpl::end_edit, &EditorHooksImpl::f_end_edit,
|
||||||
|
"@brief Editing protocol - finish session\n"
|
||||||
|
"See \\begin_edit for a description of the protocol."
|
||||||
|
) +
|
||||||
|
gsi::method ("technology=", &EditorHooksImpl::set_technology, gsi::arg ("technology"),
|
||||||
|
"@brief sets the name of the technology the hooks are associated with\n"
|
||||||
|
"This will clear all technology associations and associate the hooks with that technology only.\n"
|
||||||
|
) +
|
||||||
|
gsi::method ("clear_technologies", &EditorHooksImpl::clear_technologies,
|
||||||
|
"@brief Clears the list of technologies the hooks are associated with.\n"
|
||||||
|
"See also \\add_technology.\n"
|
||||||
|
) +
|
||||||
|
gsi::method ("add_technology", &EditorHooksImpl::add_technology, gsi::arg ("tech"),
|
||||||
|
"@brief Additionally associates the hooks with the given technology.\n"
|
||||||
|
"See also \\clear_technologies.\n"
|
||||||
|
) +
|
||||||
|
gsi::method ("is_for_technology", &EditorHooksImpl::is_for_technology, gsi::arg ("tech"),
|
||||||
|
"@brief Returns a value indicating whether the hooks are associated with the given technology.\n"
|
||||||
|
) +
|
||||||
|
gsi::method ("for_technologies", &EditorHooksImpl::for_technologies,
|
||||||
|
"@brief Returns a value indicating whether the hooks are associated with any technology.\n"
|
||||||
|
"The method is equivalent to checking whether the \\technologies list is empty.\n"
|
||||||
|
) +
|
||||||
|
gsi::method ("technologies", &EditorHooksImpl::get_technologies,
|
||||||
|
"@brief Gets the list of technologies these hooks are associated with.\n"
|
||||||
|
) +
|
||||||
|
gsi::method ("name", &EditorHooksImpl::name,
|
||||||
|
"@brief Gets the name of the hooks object.\n"
|
||||||
|
"This is the name, the object was registered under in the system."
|
||||||
|
) +
|
||||||
|
gsi::method_ext ("register", ®ister_editor_hooks, gsi::arg ("name"),
|
||||||
|
"@brief Registers the hooks in the system.\n"
|
||||||
|
"The hooks will not be active before they are registered in the system. Registration will "
|
||||||
|
"also transfer object ownership to the system.\n"
|
||||||
|
"\n"
|
||||||
|
"The name is arbitary, but should be unique. Upon registration, this hooks object will "
|
||||||
|
"replace others with the same name already registered in the system. This will simplify "
|
||||||
|
"debugging as you can re-run the same code, without accumulating hooks.\n"
|
||||||
),
|
),
|
||||||
"@brief An implementation base class for editor hooks\n"
|
"@brief An implementation base class for editor hooks\n"
|
||||||
|
"\n"
|
||||||
|
"Editor hooks allow implementing technology-specific callbacks into the editor "
|
||||||
|
"for example to implement visual feedback about DRC rules.\n"
|
||||||
|
"\n"
|
||||||
|
"This class provides the basic interface. To implement callbacks, use the \\EditorHooks class. "
|
||||||
|
"You should not need to instantiate this class.\n"
|
||||||
|
"\n"
|
||||||
// @@@
|
// @@@
|
||||||
"\n"
|
"\n"
|
||||||
"The EditorHooks class has been introduced in version 0.29."
|
"The EditorHooks class has been introduced in version 0.29."
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue