WIP: lib browser, drag and drop partially works

This commit is contained in:
Matthias Koefferlein 2019-08-02 00:53:24 +02:00
parent a567002e6c
commit 67944240b2
8 changed files with 154 additions and 57 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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);
};
/**

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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 {

View File

@ -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;
};
/**