mirror of https://github.com/KLayout/klayout.git
WIP: lib browser, drag and drop partially works
This commit is contained in:
parent
a567002e6c
commit
67944240b2
|
|
@ -1107,12 +1107,12 @@ PathService::config_finalize ()
|
|||
InstService::InstService (db::Manager *manager, lay::LayoutView *view)
|
||||
: edt::Service (manager, view),
|
||||
m_angle (0.0), m_scale (1.0),
|
||||
m_mirror (false), m_cell_name (""), m_lib_name (""), m_pcell_parameters (""),
|
||||
m_mirror (false), m_cell_name (""), m_lib_name (""), m_pcell_parameters (),
|
||||
m_array (false), m_rows (1), m_columns (1),
|
||||
m_row_x (0.0), m_row_y (0.0), m_column_x (0.0), m_column_y (0.0),
|
||||
m_place_origin (false), m_reference_transaction_id (0),
|
||||
m_needs_update (true), m_has_valid_cell (false), m_in_drag_drop (false),
|
||||
m_current_cell (0), m_drag_drop_cell (0), m_cv_index (-1)
|
||||
m_current_cell (0), m_cv_index (-1)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -1142,22 +1142,44 @@ bool
|
|||
InstService::drag_enter_event (const db::DPoint &p, const lay::DragDropDataBase *data)
|
||||
{
|
||||
const lay::CellDragDropData *cd = dynamic_cast <const lay::CellDragDropData *> (data);
|
||||
if (view ()->is_editable () && cd && cd->layout () == & view ()->active_cellview ()->layout ()) {
|
||||
if (view ()->is_editable () && cd && (cd->layout () == & view ()->active_cellview ()->layout () || cd->library ())) {
|
||||
|
||||
view ()->cancel ();
|
||||
|
||||
// NOTE: the cancel above might delete the cell we are dragging (if that is
|
||||
// a non-placed PCell). Hence we need to check whether the cell still is valid
|
||||
if (cd->layout ()->is_valid_cell_index (cd->cell_index ())) {
|
||||
set_edit_marker (0);
|
||||
|
||||
set_edit_marker (0);
|
||||
m_cv_index = view ()->active_cellview_index ();
|
||||
m_in_drag_drop = true;
|
||||
|
||||
m_cv_index = view ()->active_cellview_index ();
|
||||
m_in_drag_drop = true;
|
||||
m_drag_drop_cell = cd->cell_index ();
|
||||
if (cd->library ()) {
|
||||
m_lib_name = cd->library ()->get_name ();
|
||||
} else {
|
||||
m_lib_name.clear ();
|
||||
}
|
||||
|
||||
m_pcell_parameters.clear ();
|
||||
m_cell_name.clear ();
|
||||
|
||||
if (cd->is_pcell ()) {
|
||||
|
||||
const db::PCellDeclaration *pcell_decl = cd->layout ()->pcell_declaration (cd->cell_index ());
|
||||
if (pcell_decl) {
|
||||
|
||||
m_cell_name = pcell_decl->name ();
|
||||
const std::vector<db::PCellParameterDeclaration> &pd = pcell_decl->parameter_declarations();
|
||||
for (std::vector<db::PCellParameterDeclaration>::const_iterator i = pd.begin (); i != pd.end (); ++i) {
|
||||
m_pcell_parameters.insert (std::make_pair (i->get_name (), i->get_default ()));
|
||||
}
|
||||
|
||||
do_begin_edit (p);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
} else if (cd->layout ()->is_valid_cell_index (cd->cell_index ())) {
|
||||
|
||||
m_cell_name = cd->layout ()->cell_name (cd->cell_index ());
|
||||
do_begin_edit (p);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
|
@ -1260,10 +1282,6 @@ InstService::do_begin_edit (const db::DPoint &p)
|
|||
std::pair<bool, db::cell_index_type>
|
||||
InstService::make_cell (const lay::CellView &cv)
|
||||
{
|
||||
if (m_in_drag_drop) {
|
||||
return std::make_pair (true, m_drag_drop_cell);
|
||||
}
|
||||
|
||||
if (m_has_valid_cell) {
|
||||
return std::make_pair (true, m_current_cell);
|
||||
}
|
||||
|
|
@ -1301,20 +1319,10 @@ InstService::make_cell (const lay::CellView &cv)
|
|||
const db::PCellDeclaration *pc_decl = layout->pcell_declaration (pci.second);
|
||||
if (pc_decl) {
|
||||
|
||||
std::map<std::string, tl::Variant> parameters;
|
||||
tl::Extractor ex (m_pcell_parameters.c_str ());
|
||||
while (! ex.at_end ()) {
|
||||
std::string n;
|
||||
ex.read_word_or_quoted (n);
|
||||
ex.test (":");
|
||||
ex.read (parameters.insert (std::make_pair (n, tl::Variant ())).first->second);
|
||||
ex.test (";");
|
||||
}
|
||||
|
||||
const std::vector<db::PCellParameterDeclaration> &pcp = pc_decl->parameter_declarations ();
|
||||
for (std::vector<db::PCellParameterDeclaration>::const_iterator pd = pcp.begin (); pd != pcp.end (); ++pd) {
|
||||
std::map<std::string, tl::Variant>::const_iterator p = parameters.find (pd->get_name ());
|
||||
if (p != parameters.end ()) {
|
||||
std::map<std::string, tl::Variant>::const_iterator p = m_pcell_parameters.find (pd->get_name ());
|
||||
if (p != m_pcell_parameters.end ()) {
|
||||
pv.push_back (p->second);
|
||||
} else {
|
||||
pv.push_back (pd->get_default ());
|
||||
|
|
@ -1491,9 +1499,20 @@ InstService::configure (const std::string &name, const std::string &value)
|
|||
}
|
||||
|
||||
if (name == cfg_edit_inst_pcell_parameters) {
|
||||
m_pcell_parameters = value;
|
||||
|
||||
m_pcell_parameters.clear ();
|
||||
tl::Extractor ex (value.c_str ());
|
||||
while (! ex.at_end ()) {
|
||||
std::string n;
|
||||
ex.read_word_or_quoted (n);
|
||||
ex.test (":");
|
||||
ex.read (m_pcell_parameters.insert (std::make_pair (n, tl::Variant ())).first->second);
|
||||
ex.test (";");
|
||||
}
|
||||
|
||||
m_needs_update = true;
|
||||
return true; // taken
|
||||
|
||||
}
|
||||
|
||||
if (name == cfg_edit_inst_place_origin) {
|
||||
|
|
|
|||
|
|
@ -223,7 +223,8 @@ private:
|
|||
double m_scale;
|
||||
bool m_mirror;
|
||||
db::DPoint m_disp;
|
||||
std::string m_cell_name, m_lib_name, m_pcell_parameters;
|
||||
std::string m_cell_name, m_lib_name;
|
||||
std::map<std::string, tl::Variant> m_pcell_parameters;
|
||||
bool m_array;
|
||||
unsigned int m_rows, m_columns;
|
||||
double m_row_x, m_row_y, m_column_x, m_column_y;
|
||||
|
|
@ -232,7 +233,7 @@ private:
|
|||
bool m_needs_update;
|
||||
bool m_has_valid_cell;
|
||||
bool m_in_drag_drop;
|
||||
db::cell_index_type m_current_cell, m_drag_drop_cell;
|
||||
db::cell_index_type m_current_cell;
|
||||
int m_cv_index;
|
||||
db::ICplxTrans m_trans;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "tlGlobPattern.h"
|
||||
#include "dbPCellHeader.h"
|
||||
#include "dbPCellVariant.h"
|
||||
#include "dbLibrary.h"
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QPalette>
|
||||
|
|
@ -273,6 +274,7 @@ CellTreeModel::CellTreeModel (QWidget *parent, lay::LayoutView *view, int cv_ind
|
|||
m_pad = ((flags & NoPadding) == 0);
|
||||
|
||||
mp_layout = & view->cellview (cv_index)->layout ();
|
||||
mp_library = 0;
|
||||
tl_assert (! mp_layout->under_construction () && ! (mp_layout->manager () && mp_layout->manager ()->transacting ()));
|
||||
|
||||
build_top_level ();
|
||||
|
|
@ -293,6 +295,28 @@ CellTreeModel::CellTreeModel (QWidget *parent, db::Layout *layout, unsigned int
|
|||
m_pad = ((flags & NoPadding) == 0);
|
||||
|
||||
mp_layout = layout;
|
||||
mp_library = 0;
|
||||
tl_assert (! mp_layout->under_construction () && ! (mp_layout->manager () && mp_layout->manager ()->transacting ()));
|
||||
|
||||
build_top_level ();
|
||||
|
||||
m_current_index = m_selected_indexes.begin ();
|
||||
}
|
||||
|
||||
CellTreeModel::CellTreeModel (QWidget *parent, db::Library *library, unsigned int flags, const db::Cell *base, Sorting sorting)
|
||||
: QAbstractItemModel (parent),
|
||||
m_flags (flags),
|
||||
m_sorting (sorting),
|
||||
mp_parent (parent),
|
||||
mp_view (0),
|
||||
m_cv_index (-1),
|
||||
mp_base (base)
|
||||
{
|
||||
m_flat = ((flags & Flat) != 0) && ((flags & TopCells) == 0);
|
||||
m_pad = ((flags & NoPadding) == 0);
|
||||
|
||||
mp_layout = &library->layout ();
|
||||
mp_library = library;
|
||||
tl_assert (! mp_layout->under_construction () && ! (mp_layout->manager () && mp_layout->manager ()->transacting ()));
|
||||
|
||||
build_top_level ();
|
||||
|
|
@ -309,18 +333,23 @@ void
|
|||
CellTreeModel::configure (lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting)
|
||||
{
|
||||
db::Layout *layout = & view->cellview (cv_index)->layout ();
|
||||
|
||||
do_configure (layout, view, cv_index, flags, base, sorting);
|
||||
do_configure (layout, 0, view, cv_index, flags, base, sorting);
|
||||
}
|
||||
|
||||
void
|
||||
CellTreeModel::configure (db::Layout *layout, unsigned int flags, const db::Cell *base, Sorting sorting)
|
||||
{
|
||||
do_configure (layout, 0, -1, flags, base, sorting);
|
||||
do_configure (layout, 0, 0, -1, flags, base, sorting);
|
||||
}
|
||||
|
||||
void
|
||||
CellTreeModel::do_configure (db::Layout *layout, lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting)
|
||||
CellTreeModel::configure (db::Library *library, unsigned int flags, const db::Cell *base, Sorting sorting)
|
||||
{
|
||||
do_configure (& library->layout (), library, 0, -1, flags, base, sorting);
|
||||
}
|
||||
|
||||
void
|
||||
CellTreeModel::do_configure (db::Layout *layout, db::Library *library, lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting)
|
||||
{
|
||||
bool flat = ((flags & Flat) != 0) && ((flags & TopCells) == 0);
|
||||
|
||||
|
|
@ -362,6 +391,7 @@ CellTreeModel::do_configure (db::Layout *layout, lay::LayoutView *view, int cv_i
|
|||
m_pad = ((flags & NoPadding) == 0);
|
||||
|
||||
mp_layout = layout;
|
||||
mp_library = library;
|
||||
tl_assert (! mp_layout->under_construction () && ! (mp_layout->manager () && mp_layout->manager ()->transacting ()));
|
||||
|
||||
build_top_level ();
|
||||
|
|
@ -447,7 +477,7 @@ void
|
|||
CellTreeModel::set_sorting (Sorting s)
|
||||
{
|
||||
if (s != m_sorting) {
|
||||
do_configure (mp_layout, mp_view, m_cv_index, m_flags, mp_base, s);
|
||||
do_configure (mp_layout, mp_library, mp_view, m_cv_index, m_flags, mp_base, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -566,19 +596,23 @@ CellTreeModel::mimeTypes () const
|
|||
QMimeData *
|
||||
CellTreeModel::mimeData(const QModelIndexList &indexes) const
|
||||
{
|
||||
const db::Cell *c = 0;
|
||||
for (QModelIndexList::const_iterator i = indexes.begin (); i != indexes.end () && !c; ++i) {
|
||||
for (QModelIndexList::const_iterator i = indexes.begin (); i != indexes.end (); ++i) {
|
||||
|
||||
if (i->isValid()) {
|
||||
c = cell (*i);
|
||||
|
||||
if (is_pcell (*i)) {
|
||||
lay::CellDragDropData data (mp_layout, mp_library, pcell_id (*i), true);
|
||||
return data.to_mime_data ();
|
||||
} else if (cell (*i)) {
|
||||
lay::CellDragDropData data (mp_layout, mp_library, cell_index (*i), false);
|
||||
return data.to_mime_data ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (c) {
|
||||
lay::CellDragDropData data (mp_layout, c->cell_index ());
|
||||
return data.to_mime_data ();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -37,6 +37,11 @@ namespace tl
|
|||
class GlobPattern;
|
||||
}
|
||||
|
||||
namespace db
|
||||
{
|
||||
class Library;
|
||||
}
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
|
|
@ -88,6 +93,13 @@ public:
|
|||
*/
|
||||
CellTreeModel (QWidget *parent, db::Layout *layout, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName);
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* This constructor does not take a view but rather a layout from a library. It does not display hidden status or similar.
|
||||
*/
|
||||
CellTreeModel (QWidget *parent, db::Library *library, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName);
|
||||
|
||||
/**
|
||||
* @brief Dtor
|
||||
*/
|
||||
|
|
@ -110,10 +122,15 @@ public:
|
|||
void configure (lay::LayoutView *view, int cv_index, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName);
|
||||
|
||||
/**
|
||||
* @brief Reconfigures the model with a pure Layout view
|
||||
* @brief Reconfigures the model with a pure Layout
|
||||
*/
|
||||
void configure (db::Layout *layout, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName);
|
||||
|
||||
/**
|
||||
* @brief Reconfigures the model with a pure Layout from a library
|
||||
*/
|
||||
void configure (db::Library *library, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName);
|
||||
|
||||
/**
|
||||
* @brief Gets the layout this model is connected to
|
||||
*/
|
||||
|
|
@ -226,6 +243,7 @@ private:
|
|||
QWidget *mp_parent;
|
||||
lay::LayoutView *mp_view;
|
||||
db::Layout *mp_layout;
|
||||
db::Library *mp_library;
|
||||
int m_cv_index;
|
||||
const db::Cell *mp_base;
|
||||
std::vector <CellTreeItem *> m_toplevel;
|
||||
|
|
@ -236,7 +254,7 @@ private:
|
|||
void build_top_level ();
|
||||
void clear_top_level ();
|
||||
void search_children (const tl::GlobPattern &pattern, CellTreeItem *item);
|
||||
void do_configure (db::Layout *layout, lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting);
|
||||
void do_configure (db::Layout *layout, db::Library *library, lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -127,7 +127,6 @@ LibraryTreeWidget::keyPressEvent (QKeyEvent *event)
|
|||
void
|
||||
LibraryTreeWidget::startDrag (Qt::DropActions supportedActions)
|
||||
{
|
||||
#if 0 // @@@
|
||||
QModelIndex index = selectionModel ()->currentIndex ();
|
||||
if (index.isValid ()) {
|
||||
|
||||
|
|
@ -153,7 +152,6 @@ LibraryTreeWidget::startDrag (Qt::DropActions supportedActions)
|
|||
drag->exec(supportedActions, defaultDropAction);
|
||||
|
||||
}
|
||||
#endif // @@@
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -382,11 +380,10 @@ LibrariesView::set_split_mode (bool f)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0 // @@@
|
||||
void
|
||||
LibrariesView::clear_all ()
|
||||
{
|
||||
m_cellviews.clear ();
|
||||
m_libraries.clear ();
|
||||
m_needs_update.clear ();
|
||||
m_force_close.clear ();
|
||||
|
||||
|
|
@ -397,7 +394,6 @@ LibrariesView::clear_all ()
|
|||
mp_cell_list_headers.clear ();
|
||||
mp_cell_lists.clear ();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
LibrariesView::cm_cell_select ()
|
||||
|
|
@ -794,7 +790,7 @@ LibrariesView::do_update_content (int lib_index)
|
|||
|
||||
LibraryTreeWidget *cell_list = new LibraryTreeWidget (cl_frame, "tree", mp_view->view_object_widget ());
|
||||
cl_ly->addWidget (cell_list);
|
||||
cell_list->setModel (new CellTreeModel (cell_list, &m_libraries [i]->layout (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells | CellTreeModel::WithVariants, 0));
|
||||
cell_list->setModel (new CellTreeModel (cell_list, m_libraries [i].get (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells | CellTreeModel::WithVariants, 0));
|
||||
cell_list->setUniformRowHeights (true);
|
||||
|
||||
pl = cell_list->palette ();
|
||||
|
|
@ -869,7 +865,7 @@ LibrariesView::do_update_content (int lib_index)
|
|||
|
||||
CellTreeModel *model = dynamic_cast <CellTreeModel *> (mp_cell_lists [i]->model ());
|
||||
if (model) {
|
||||
model->configure (& m_libraries [i]->layout (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells | CellTreeModel::WithVariants, 0);
|
||||
model->configure (m_libraries [i].get (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells | CellTreeModel::WithVariants, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -302,10 +302,10 @@ private:
|
|||
|
||||
// select active cellview from sender (sender must be a cell tree)
|
||||
void set_active_celltree_from_sender ();
|
||||
#endif
|
||||
|
||||
// clears all widgets of the cell lists
|
||||
void clear_all ();
|
||||
#endif
|
||||
|
||||
// display string of nth cellview
|
||||
std::string display_string (int n) const;
|
||||
|
|
|
|||
|
|
@ -70,7 +70,9 @@ CellDragDropData::serialized () const
|
|||
|
||||
stream << QString::fromUtf8 ("CellDragDropData");
|
||||
stream << (quintptr) mp_layout;
|
||||
stream << (quintptr) mp_library;
|
||||
stream << m_cell_index;
|
||||
stream << m_is_pcell;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
@ -88,7 +90,10 @@ CellDragDropData::deserialize (const QByteArray &ba)
|
|||
quintptr p = 0;
|
||||
stream >> p;
|
||||
mp_layout = reinterpret_cast <const db::Layout *> (p);
|
||||
stream >> p;
|
||||
mp_library = reinterpret_cast <const db::Library *> (p);
|
||||
stream >> m_cell_index;
|
||||
stream >> m_is_pcell;
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -53,6 +53,12 @@ class QDragLeaveEvent;
|
|||
class QDropEvent;
|
||||
class QMimeData;
|
||||
|
||||
namespace db
|
||||
{
|
||||
class Library;
|
||||
class Layout;
|
||||
}
|
||||
|
||||
namespace lay {
|
||||
|
||||
class Viewport;
|
||||
|
|
@ -113,7 +119,7 @@ public:
|
|||
* @brief Default ctor
|
||||
*/
|
||||
CellDragDropData ()
|
||||
: mp_layout (0), m_cell_index (0)
|
||||
: mp_layout (0), mp_library (0), m_cell_index (0), m_is_pcell (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -124,8 +130,8 @@ public:
|
|||
* @param layout the layout where the cell lives in
|
||||
* @param cell_index The index of the cell
|
||||
*/
|
||||
CellDragDropData (const db::Layout *layout, db::cell_index_type cell_index)
|
||||
: mp_layout (layout), m_cell_index (cell_index)
|
||||
CellDragDropData (const db::Layout *layout, const db::Library *library, db::cell_index_type cell_or_pcell_index, bool is_pcell)
|
||||
: mp_layout (layout), mp_library (library), m_cell_index (cell_or_pcell_index), m_is_pcell (is_pcell)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -138,6 +144,14 @@ public:
|
|||
return mp_layout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the layout object where the cell lives in
|
||||
*/
|
||||
const db::Library *library () const
|
||||
{
|
||||
return mp_library;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the index of the cell
|
||||
*/
|
||||
|
|
@ -146,6 +160,14 @@ public:
|
|||
return m_cell_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the cell is a pcell
|
||||
*/
|
||||
bool is_pcell () const
|
||||
{
|
||||
return m_is_pcell;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Serializes itself to an QByteArray
|
||||
*/
|
||||
|
|
@ -160,7 +182,9 @@ public:
|
|||
|
||||
private:
|
||||
const db::Layout *mp_layout;
|
||||
const db::Library *mp_library;
|
||||
db::cell_index_type m_cell_index;
|
||||
bool m_is_pcell;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue