Improvement on Python interface of Occurrence, Point & CellViewer.

* Bug: In Isobar::PyOccurrence, use "compare by value" instead of
    "compare by pointer" for the Python comparison function. So we
    really can compare identical Occurrences.
* New: In Isobar::PyPoint, export the "manhattanDistance()" function.
* New: In Isobal::PyCellViewer, add the following funtions to the
    exported interface:
    - "select()"
    - "unselect()"
    - "unselectAll()"
    - "reframe()"
    - "setShowSelection()"
    So now we can easily highlight components from Python (to ease
    debug).
* New: In Hurricane::CellViewer, create a proxy for the CellWidget
    "reframe()" function.
This commit is contained in:
Jean-Paul Chaput 2020-09-11 12:55:51 +02:00
parent 0b5ce309eb
commit 3e6d5622e8
7 changed files with 199 additions and 98 deletions

View File

@ -243,8 +243,27 @@ extern "C" {
DirectDeleteMethod(PyOccurrence_DeAlloc,PyOccurrence)
PyTypeObjectLinkPyTypeNewInit(Occurrence)
DirectDeleteMethod (PyOccurrence_DeAlloc,PyOccurrence)
DirectReprMethod (PyOccurrence_Repr ,PyOccurrence, Occurrence)
DirectStrMethod (PyOccurrence_Str ,PyOccurrence, Occurrence)
DirectCmpByValueMethod(PyOccurrence_Cmp ,IsPyOccurrence, PyOccurrence)
DirectHashMethod (PyOccurrence_Hash ,Occurrence)
extern void PyOccurrence_LinkPyType ()
{
cdebug_log(20,0) << "PyOccurrence_LinkType()" << endl;
PyTypeOccurrence.tp_dealloc = (destructor) PyOccurrence_DeAlloc;
PyTypeOccurrence.tp_compare = (cmpfunc) PyOccurrence_Cmp;
PyTypeOccurrence.tp_repr = (reprfunc) PyOccurrence_Repr;
PyTypeOccurrence.tp_str = (reprfunc) PyOccurrence_Str;
PyTypeOccurrence.tp_hash = (hashfunc) PyOccurrence_Hash;
PyTypeOccurrence.tp_new = (newfunc) PyOccurrence_NEW;
PyTypeOccurrence.tp_init = (initproc) PyOccurrence_Init;
PyTypeOccurrence.tp_methods = PyOccurrence_Methods;
}
//PyTypeObjectLinkPyTypeNewInit(Occurrence)
//PyTypeObjectLinkPyType(Occurrence)

View File

@ -27,21 +27,18 @@ extern "C" {
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Point,point,function)
// x=================================================================x
// +=================================================================+
// | "PyPoint" Python Module Code Part |
// x=================================================================x
// +=================================================================+
#if defined(__PYTHON_MODULE__)
// x-------------------------------------------------------------x
// +-------------------------------------------------------------+
// | "PyPoint" Attribute Methods |
// x-------------------------------------------------------------x
// +-------------------------------------------------------------+
// ---------------------------------------------------------------
// Attribute Method : "PyPoint_NEW ()"
static PyObject* PyPoint_NEW ( PyObject* module, PyObject *args )
{
cdebug_log(20,0) << "PyPoint_NEW()" << endl;
@ -86,36 +83,48 @@ extern "C" {
}
// ---------------------------------------------------------------
// Attribute Method : "PyPoint_Translate ()"
static PyObject* PyPoint_Translate ( PyPoint *self, PyObject* args )
static PyObject* PyPoint_translate ( PyPoint *self, PyObject* args )
{
cdebug_log(20,0) << "PyPoint_Translate()" << endl;
cdebug_log(20,0) << "PyPoint_translate()" << endl;
HTRY
METHOD_HEAD ( "Box.Translate()" )
PyObject* arg0;
PyObject* arg1;
if ( ! ParseTwoArg ( "Box.Translate", args, INTS2_ARG, &arg0, &arg1 ) ) return ( NULL );
point->translate ( PyAny_AsLong(arg0), PyAny_AsLong(arg1) );
METHOD_HEAD( "Point.translate()" )
PyObject* arg0;
PyObject* arg1;
if (not ParseTwoArg( "Point.translate", args, INTS2_ARG, &arg0, &arg1 )) return NULL;
point->translate( PyAny_AsLong(arg0), PyAny_AsLong(arg1) );
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyPoint_manhattanDistance ( PyPoint *self, PyObject* args )
{
cdebug_log(20,0) << "PyPoint_manhattanDistance()" << endl;
DbU::Unit distance = 0;
HTRY
METHOD_HEAD ( "Point.manahattanDistance()" )
PyObject* pyPoint = NULL;
if (not PyArg_ParseTuple(args,"O:Point.manhattanDistance()", &pyPoint)) {
PyErr_SetString ( ConstructorError, "Point.manhattanDistance(): Takes exactly one argument." );
return NULL;
}
if (not IsPyPoint(pyPoint)) {
PyErr_SetString ( ConstructorError, "Point.manhattanDistance(): Argument is not a Point." );
return NULL;
}
distance = point->manhattanDistance( *(PYPOINT_O(pyPoint)) );
HCATCH
return PyDbU_FromLong(distance);
}
// Standart Accessors (Attributes).
DirectGetLongAttribute(PyPoint_getX,getX,PyPoint,Point)
DirectGetLongAttribute(PyPoint_getY,getY,PyPoint,Point)
DirectSetLongAttribute(PyPoint_SetX,setX,PyPoint,Point)
DirectSetLongAttribute(PyPoint_SetY,setY,PyPoint,Point)
DirectSetLongAttribute(PyPoint_setX,setX,PyPoint,Point)
DirectSetLongAttribute(PyPoint_setY,setY,PyPoint,Point)
// Standart destroy (Attribute).
@ -128,14 +137,15 @@ extern "C" {
// PyPoint Attribute Method table.
PyMethodDef PyPoint_Methods[] =
{ { "getX" , (PyCFunction)PyPoint_getX , METH_NOARGS , "Return the Point X value." }
, { "getY" , (PyCFunction)PyPoint_getY , METH_NOARGS , "Return the Point Y value." }
, { "setX" , (PyCFunction)PyPoint_SetX , METH_VARARGS, "Modify the Point X value." }
, { "setY" , (PyCFunction)PyPoint_SetY , METH_VARARGS, "Modify the Point Y value." }
, { "translate", (PyCFunction)PyPoint_Translate, METH_VARARGS, "Translate the point of dx and dy." }
, { "destroy" , (PyCFunction)PyPoint_destroy , METH_NOARGS
, "Destroy associated hurricane object The python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */
{ { "getX" , (PyCFunction)PyPoint_getX , METH_NOARGS , "Return the Point X value." }
, { "getY" , (PyCFunction)PyPoint_getY , METH_NOARGS , "Return the Point Y value." }
, { "setX" , (PyCFunction)PyPoint_setX , METH_VARARGS, "Modify the Point X value." }
, { "setY" , (PyCFunction)PyPoint_setY , METH_VARARGS, "Modify the Point Y value." }
, { "translate" , (PyCFunction)PyPoint_translate , METH_VARARGS, "Translate the point of dx and dy." }
, { "manhattanDistance" , (PyCFunction)PyPoint_manhattanDistance, METH_VARARGS, "Compute the Manhattan distance between the two points." }
, { "destroy" , (PyCFunction)PyPoint_destroy , METH_NOARGS
, "Destroy associated hurricane object The python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */
};

View File

@ -14,9 +14,7 @@
// +-----------------------------------------------------------------+
#ifndef PY_OCCURRENCE_H
#define PY_OCCURRENCE_H
#pragma once
#include "hurricane/isobar/PyHurricane.h"
#include "hurricane/Occurrence.h"
@ -51,5 +49,3 @@ namespace Isobar {
} // extern "C".
} // Isobar namespace.
#endif // PY_OCCURRENCE_H

View File

@ -838,6 +838,10 @@ namespace Hurricane {
{ if ( _cellWidget ) _cellWidget->unselectAll(); }
void CellViewer::reframe ( const Box& area, bool historyEnable )
{ if ( _cellWidget ) _cellWidget->reframe( area, historyEnable ); }
void CellViewer::printDisplay ()
{
if ( !_cellWidget ) return;

View File

@ -14,7 +14,9 @@
// +-----------------------------------------------------------------+
#include "hurricane/isobar/PyBox.h"
#include "hurricane/isobar/PyCell.h"
#include "hurricane/isobar/PyOccurrence.h"
#include "hurricane/viewer/PyCellViewer.h"
#include "hurricane/viewer/CellWidget.h"
@ -233,15 +235,85 @@ extern "C" {
}
static PyObject* PyCellViewer_select ( PyCellViewer* self, PyObject* args )
{
cdebug_log(20,0) << "PyCellViewer_select()" << endl;
HTRY
METHOD_HEAD("CellViewer.select()")
PyObject* pyOccurrence = NULL;
if (not PyArg_ParseTuple(args,"O:CellViewer.select()", &pyOccurrence)) {
PyErr_SetString ( ConstructorError, "CellViewer.select(): Takes exactly one argument." );
return NULL;
}
if (not IsPyOccurrence(pyOccurrence)) {
PyErr_SetString ( ConstructorError, "CellViewer.select(): Argument is not an Occurrence." );
return NULL;
}
cw->select( *(PYOCCURRENCE_O(pyOccurrence)) );
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyCellViewer_unselect ( PyCellViewer* self, PyObject* args )
{
cdebug_log(20,0) << "PyCellViewer_unselect()" << endl;
HTRY
METHOD_HEAD("CellViewer.unselect()")
PyObject* pyOccurrence = NULL;
if (not PyArg_ParseTuple(args,"O:CellViewer.unselect()", &pyOccurrence)) {
PyErr_SetString ( ConstructorError, "CellViewer.unselect(): Takes exactly one argument." );
return NULL;
}
if (not IsPyOccurrence(pyOccurrence)) {
PyErr_SetString ( ConstructorError, "CellViewer.unselect(): Argument is not an Occurrence." );
return NULL;
}
cw->unselect( *(PYOCCURRENCE_O(pyOccurrence)) );
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyCellViewer_unselectAll ( PyCellViewer* self )
{
cdebug_log(20,0) << "PyCellViewer_unselectAll()" << endl;
HTRY
METHOD_HEAD("CellViewer.unselectAll()")
cw->unselectAll();
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyCellViewer_reframe ( PyCellViewer* self, PyObject* args )
{
cdebug_log(20,0) << "PyCellViewer_reframe ()" << endl;
HTRY
METHOD_HEAD("CellViewer.reframe()")
PyObject* pyBox = NULL;
PyObject* historyEnable = NULL;
if (not PyArg_ParseTuple(args,"OO:CellViewer.reframe()", &pyBox, &historyEnable)) {
PyErr_SetString ( ConstructorError, "CellViewer.reframe(): Takes exactly two argument." );
return NULL;
}
if (not IsPyBox(pyBox)) {
PyErr_SetString ( ConstructorError, "CellViewer.reframe(): First argument is not a Box." );
return NULL;
}
cw->reframe ( *(PYBOX_O(pyBox)), (PyObject_IsTrue(historyEnable) != 0) );
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyCellViewer_fit ( PyCellViewer* self )
{
cdebug_log(20,0) << "PyCellViewer_fit()" << endl;
HTRY
METHOD_HEAD("CellViewer.fit()")
cw->getCellWidget()->fitToContents();
METHOD_HEAD("CellViewer.fit()")
cw->getCellWidget()->fitToContents();
HCATCH
Py_RETURN_NONE;
}
@ -276,42 +348,53 @@ extern "C" {
}
DirectSetBoolAttribute(PyCellViewer_setShowSelection,setShowSelection,PyCellViewer,CellViewer)
DirectSetBoolAttribute(PyCellViewer_setShowSelection ,setShowSelection ,PyCellViewer,CellViewer)
DirectSetBoolAttribute(PyCellViewer_setCumulativeSelection,setCumulativeSelection,PyCellViewer,CellViewer)
// ---------------------------------------------------------------
// PyCellViewer Attribute Method table.
PyMethodDef PyCellViewer_Methods[] =
{ { "hasMenu" , (PyCFunction)PyCellViewer_hasMenu , METH_VARARGS
, "Return true if the menu at \"path\" exists." }
, { "hasMenuAction" , (PyCFunction)PyCellViewer_hasMenuAction , METH_VARARGS
, "Return true if the menu action at \"path\" exists." }
, { "addMenu" , (PyCFunction)PyCellViewer_addMenu , METH_VARARGS
, "Create a new menu at \"path\" and returns true if success." }
, { "addToMenu" , (PyCFunction)PyCellViewer_addToMenu , METH_VARARGS
, "Creates a new action at \"path\" and returns true if success." }
, { "getCell" , (PyCFunction)PyCellViewer_getCell , METH_NOARGS
, "Return the currently edited Cell." }
, { "setCell" , (PyCFunction)PyCellViewer_setCell , METH_VARARGS
, "Load a Cell into the viewer." }
, { "setApplicationName" , (PyCFunction)PyCellViewer_setApplicationName , METH_VARARGS
, "Sets the application (binary) name." }
, { "setAnonNetSelectable", (PyCFunction)PyCellViewer_setAnonNetSelectable, METH_VARARGS
, "Allow/disallow anonymous nets to be selectables." }
, { "setLayerVisible" , (PyCFunction)PyCellViewer_setLayerVisible , METH_VARARGS
, "Sets the visibility state of the layer <name>." }
, { "setShowSelection" , (PyCFunction)PyCellViewer_setShowSelection , METH_VARARGS
, "Display/hide the selection." }
, { "fit" , (PyCFunction)PyCellViewer_fit , METH_NOARGS
, "Triggers a full redraw of the visible area." }
, { "refresh" , (PyCFunction)PyCellViewer_refresh , METH_NOARGS
, "Fit the contents to the viewer's visible area." }
, { "removeHistory" , (PyCFunction)PyCellViewer_removeHistory , METH_VARARGS
, "Remove a Cell from the viewer's history." }
, { "destroy" , (PyCFunction)PyCellViewer_destroy , METH_NOARGS
, "Destroy the associated hurricane object. The python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */
{ { "hasMenu" , (PyCFunction)PyCellViewer_hasMenu , METH_VARARGS
, "Return true if the menu at \"path\" exists." }
, { "hasMenuAction" , (PyCFunction)PyCellViewer_hasMenuAction , METH_VARARGS
, "Return true if the menu action at \"path\" exists." }
, { "addMenu" , (PyCFunction)PyCellViewer_addMenu , METH_VARARGS
, "Create a new menu at \"path\" and returns true if success." }
, { "addToMenu" , (PyCFunction)PyCellViewer_addToMenu , METH_VARARGS
, "Creates a new action at \"path\" and returns true if success." }
, { "getCell" , (PyCFunction)PyCellViewer_getCell , METH_NOARGS
, "Return the currently edited Cell." }
, { "setCell" , (PyCFunction)PyCellViewer_setCell , METH_VARARGS
, "Load a Cell into the viewer." }
, { "setApplicationName" , (PyCFunction)PyCellViewer_setApplicationName , METH_VARARGS
, "Sets the application (binary) name." }
, { "setAnonNetSelectable" , (PyCFunction)PyCellViewer_setAnonNetSelectable , METH_VARARGS
, "Allow/disallow anonymous nets to be selectables." }
, { "setLayerVisible" , (PyCFunction)PyCellViewer_setLayerVisible , METH_VARARGS
, "Sets the visibility state of the layer <name>." }
, { "setShowSelection" , (PyCFunction)PyCellViewer_setShowSelection , METH_VARARGS
, "Display/hide the selection." }
, { "setCumulativeSelection", (PyCFunction)PyCellViewer_setCumulativeSelection, METH_VARARGS
, "Make the selection cumulative." }
, { "select" , (PyCFunction)PyCellViewer_select , METH_VARARGS
, "Add an occurrence to the selected set." }
, { "unselect" , (PyCFunction)PyCellViewer_unselect , METH_VARARGS
, "Add an occurrence to the selected set." }
, { "unselectAll" , (PyCFunction)PyCellViewer_unselectAll , METH_NOARGS
, "Clear the selected set." }
, { "reframe" , (PyCFunction)PyCellViewer_reframe , METH_VARARGS
, "Zoom toward the given area." }
, { "fit" , (PyCFunction)PyCellViewer_fit , METH_NOARGS
, "Triggers a full redraw of the visible area." }
, { "refresh" , (PyCFunction)PyCellViewer_refresh , METH_NOARGS
, "Fit the contents to the viewer's visible area ." }
, { "removeHistory" , (PyCFunction)PyCellViewer_removeHistory , METH_VARARGS
, "Remove a Cell from the viewer's history." }
, { "destroy" , (PyCFunction)PyCellViewer_destroy , METH_NOARGS
, "Destroy the associated hurricane object. The python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */
};

View File

@ -14,14 +14,11 @@
// +-----------------------------------------------------------------+
#ifndef HURRICANE_CELL_VIEWER_H
#define HURRICANE_CELL_VIEWER_H
#pragma once
#include <list>
#include <map>
#include <functional>
#include <boost/any.hpp>
#include <QIcon>
#include <QMainWindow>
class QEvent;
@ -29,17 +26,16 @@ class QKeyEvent;
class QAction;
class QMenu;
class QPrinter;
#include "hurricane/Commons.h"
#include "hurricane/Observer.h"
#include "hurricane/Name.h"
#include "hurricane/Occurrence.h"
#include "hurricane/viewer/MoveCommand.h"
#include "hurricane/viewer/ZoomCommand.h"
#include "hurricane/viewer/RulerCommand.h"
#include "hurricane/viewer/SelectCommand.h"
#include "hurricane/viewer/HierarchyCommand.h"
#include "hurricane/viewer/CellWidget.h"
#include "hurricane/Commons.h"
#include "hurricane/Observer.h"
#include "hurricane/Name.h"
#include "hurricane/Occurrence.h"
#include "hurricane/viewer/MoveCommand.h"
#include "hurricane/viewer/ZoomCommand.h"
#include "hurricane/viewer/RulerCommand.h"
#include "hurricane/viewer/SelectCommand.h"
#include "hurricane/viewer/HierarchyCommand.h"
#include "hurricane/viewer/CellWidget.h"
namespace Hurricane {
@ -133,6 +129,7 @@ namespace Hurricane {
void unselect ( Occurrence& );
void unselectAll ();
inline void setLayerVisible ( const Name& layer, bool visible );
void reframe ( const Box& , bool historyEnable=true );
void runScript ( QString scriptPath );
virtual CellViewer* vcreate () const;
virtual std::string _getString () const;
@ -227,6 +224,3 @@ namespace Hurricane {
GETSTRING_POINTER_SUPPORT(Hurricane::CellViewer)
IOSTREAM_POINTER_SUPPORT(Hurricane::CellViewer)
#endif

View File

@ -14,9 +14,7 @@
// +-----------------------------------------------------------------+
#ifndef PY_HURRICANE_CELL_VIEWER_H
#define PY_HURRICANE_CELL_VIEWER_H
#pragma once
#include "hurricane/isobar/PyHurricane.h"
#include "hurricane/viewer/CellViewer.h"
@ -56,6 +54,3 @@ extern "C" {
} // End of Isobar namespace.
#endif // PY_HURRICANE_CELL_VIEWER_H