mirror of https://github.com/KLayout/klayout.git
Reworked implementation to include user feedback
This commit is contained in:
parent
7c81a8e954
commit
652b596164
|
|
@ -375,8 +375,9 @@ PropertiesPage::count () const
|
|||
void
|
||||
PropertiesPage::select_entries (const std::vector<size_t> &entries)
|
||||
{
|
||||
tl_assert (entries.size () == 1);
|
||||
m_index = entries.front ();
|
||||
if (! entries.empty ()) {
|
||||
m_index = entries.front ();
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ ShapePropertiesPage::do_apply (bool current_only, bool relative, bool commit)
|
|||
}
|
||||
}
|
||||
|
||||
int new_layer = layer_selector ()->current_layer ();
|
||||
int new_layer = layer_selector ()->current_layer_ensure ();
|
||||
if (new_layer >= 0 && int (pos->layer ()) != new_layer) {
|
||||
unsigned int gs_layer = cv->layout ().guiding_shape_layer ();
|
||||
ChangeLayerApplicator *cla = new ChangeLayerApplicator (cv_index, (unsigned int) new_layer);
|
||||
|
|
|
|||
|
|
@ -181,9 +181,10 @@ PropertiesPage::count () const
|
|||
void
|
||||
PropertiesPage::select_entries (const std::vector<size_t> &entries)
|
||||
{
|
||||
tl_assert (entries.size () == 1);
|
||||
m_index = entries.front ();
|
||||
invalidate ();
|
||||
if (! entries.empty ()) {
|
||||
m_index = entries.front ();
|
||||
invalidate ();
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
|
|
|
|||
|
|
@ -235,10 +235,11 @@ PropertiesDialog::PropertiesDialog (QWidget * /*parent*/, db::Manager *manager,
|
|||
m_current_object = 0;
|
||||
|
||||
// look for next usable editable
|
||||
m_object_indexes.resize (mp_properties_pages.size ());
|
||||
if (m_index >= int (mp_properties_pages.size ())) {
|
||||
m_index = -1;
|
||||
} else {
|
||||
m_object_indexes.push_back (0);
|
||||
m_object_indexes [m_index].push_back (0);
|
||||
}
|
||||
|
||||
update_title ();
|
||||
|
|
@ -383,6 +384,7 @@ BEGIN_PROTECTED
|
|||
delete *p;
|
||||
} else {
|
||||
mp_properties_pages.push_back (*p);
|
||||
(*p)->set_page_set (this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -398,10 +400,11 @@ BEGIN_PROTECTED
|
|||
// look for next usable editable
|
||||
m_index = 0;
|
||||
m_object_indexes.clear ();
|
||||
m_object_indexes.resize (mp_properties_pages.size ());
|
||||
if (m_index >= int (mp_properties_pages.size ())) {
|
||||
m_index = -1;
|
||||
} else {
|
||||
m_object_indexes.push_back (0);
|
||||
m_object_indexes [m_index].push_back (0);
|
||||
}
|
||||
|
||||
mp_tree_model->end_reset_model ();
|
||||
|
|
@ -436,6 +439,7 @@ PropertiesDialog::current_index_changed (const QModelIndex &index, const QModelI
|
|||
}
|
||||
|
||||
m_object_indexes.clear ();
|
||||
m_object_indexes.resize (mp_properties_pages.size ());
|
||||
|
||||
if (! index.isValid ()) {
|
||||
|
||||
|
|
@ -462,56 +466,66 @@ PropertiesDialog::current_index_changed (const QModelIndex &index, const QModelI
|
|||
|
||||
}
|
||||
|
||||
m_index = -1;
|
||||
|
||||
auto selection = mp_ui->tree->selectionModel ()->selectedIndexes ();
|
||||
|
||||
// establish a single-selection on the current item
|
||||
if (mp_tree_model->parent (index).isValid ()) {
|
||||
int oi = mp_tree_model->object_index (index);
|
||||
int pi = mp_tree_model->page_index (index);
|
||||
m_index = pi;
|
||||
m_object_indexes [pi].push_back (size_t (oi));
|
||||
}
|
||||
|
||||
m_index = mp_tree_model->page_index (index);
|
||||
// establish individual selections for the other items
|
||||
// as far as allowed by "can_apply_to_all"
|
||||
for (auto i = selection.begin (); i != selection.end (); ++i) {
|
||||
if (*i != index && mp_tree_model->parent (*i).isValid ()) {
|
||||
int oi = mp_tree_model->object_index (*i);
|
||||
int pi = mp_tree_model->page_index (*i);
|
||||
if (mp_properties_pages [pi]->can_apply_to_all ()) {
|
||||
m_object_indexes [pi].push_back (size_t (oi));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mp_properties_pages [m_index]->can_apply_to_all ()) {
|
||||
// establish group node selection as current item -> translate into "all" for "can_apply_to_all" pages
|
||||
// or first item unless an item is explicitly selected.
|
||||
if (! mp_tree_model->parent (index).isValid ()) {
|
||||
int pi = index.row ();
|
||||
m_index = pi;
|
||||
m_object_indexes [pi].clear ();
|
||||
if (mp_properties_pages [pi]->can_apply_to_all ()) {
|
||||
for (size_t oi = 0; oi < mp_properties_pages [pi]->count (); ++oi) {
|
||||
m_object_indexes [pi].push_back (oi);
|
||||
}
|
||||
} else if (mp_properties_pages [pi]->count () > 0 && m_object_indexes [pi].empty ()) {
|
||||
m_object_indexes [pi].push_back (0);
|
||||
}
|
||||
}
|
||||
|
||||
m_object_indexes.push_back (size_t (mp_tree_model->object_index (index)));
|
||||
|
||||
auto selection = mp_ui->tree->selectionModel ()->selectedIndexes ();
|
||||
for (auto i = selection.begin (); i != selection.end (); ++i) {
|
||||
if (mp_tree_model->parent (*i).isValid () && mp_tree_model->page_index (*i) == m_index) {
|
||||
int oi = mp_tree_model->object_index (*i);
|
||||
if (oi != int (m_object_indexes.front ())) {
|
||||
m_object_indexes.push_back (size_t (oi));
|
||||
}
|
||||
// establish group node selection for other items -> translate into "all" for "can_apply_to_all" pages
|
||||
for (auto i = selection.begin (); i != selection.end (); ++i) {
|
||||
if (*i != index && ! mp_tree_model->parent (*i).isValid ()) {
|
||||
int pi = i->row ();
|
||||
m_object_indexes [pi].clear ();
|
||||
if (mp_properties_pages [pi]->can_apply_to_all ()) {
|
||||
for (size_t oi = 0; oi < mp_properties_pages [pi]->count (); ++oi) {
|
||||
m_object_indexes[pi].push_back (oi);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
m_object_indexes.push_back (size_t (mp_tree_model->object_index (index)));
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
m_index = index.row ();
|
||||
|
||||
if (mp_properties_pages [m_index]->can_apply_to_all ()) {
|
||||
|
||||
for (size_t oi = 0; oi < mp_properties_pages [m_index]->count (); ++oi) {
|
||||
m_object_indexes.push_back (oi);
|
||||
}
|
||||
|
||||
} else if (mp_properties_pages [m_index]->count () > 0) {
|
||||
|
||||
m_object_indexes.push_back (0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (! m_object_indexes.empty ()) {
|
||||
if (m_index >= 0 && ! m_object_indexes [m_index].empty ()) {
|
||||
m_current_object = 0;
|
||||
for (int i = 0; i < m_index; ++i) {
|
||||
m_current_object += mp_properties_pages [i]->count ();
|
||||
}
|
||||
m_current_object += int (m_object_indexes.front ());
|
||||
m_current_object += int (m_object_indexes [m_index].front ());
|
||||
} else {
|
||||
m_current_object = -1;
|
||||
}
|
||||
|
|
@ -552,7 +566,10 @@ PropertiesDialog::update_controls ()
|
|||
mp_ui->ok_button->setEnabled (! mp_properties_pages [m_index]->readonly ());
|
||||
mp_ui->tree->setEnabled (true);
|
||||
|
||||
mp_properties_pages [m_index]->select_entries (m_object_indexes);
|
||||
for (int i = 0; i < int (mp_properties_pages.size ()); ++i) {
|
||||
mp_properties_pages [i]->select_entries (m_object_indexes [i]);
|
||||
}
|
||||
|
||||
mp_properties_pages [m_index]->update ();
|
||||
|
||||
}
|
||||
|
|
@ -563,7 +580,7 @@ PropertiesDialog::next_pressed ()
|
|||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
if (m_object_indexes.empty ()) {
|
||||
if (m_index < 0 || m_object_indexes [m_index].empty ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -576,7 +593,7 @@ BEGIN_PROTECTED
|
|||
}
|
||||
|
||||
// advance the current entry
|
||||
int object_index = int (m_object_indexes.front ());
|
||||
int object_index = int (m_object_indexes [m_index].front ());
|
||||
++object_index;
|
||||
|
||||
// look for next usable editable if at end
|
||||
|
|
@ -593,7 +610,8 @@ BEGIN_PROTECTED
|
|||
}
|
||||
|
||||
m_object_indexes.clear ();
|
||||
m_object_indexes.push_back (object_index);
|
||||
m_object_indexes.resize (mp_properties_pages.size ());
|
||||
m_object_indexes [m_index].push_back (object_index);
|
||||
|
||||
++m_current_object;
|
||||
update_title ();
|
||||
|
|
@ -611,7 +629,7 @@ PropertiesDialog::prev_pressed ()
|
|||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
if (m_object_indexes.empty ()) {
|
||||
if (m_index < 0 || m_object_indexes [m_index].empty ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -624,7 +642,7 @@ BEGIN_PROTECTED
|
|||
}
|
||||
|
||||
// advance the current entry
|
||||
int object_index = int (m_object_indexes.front ());
|
||||
int object_index = int (m_object_indexes [m_index].front ());
|
||||
if (object_index == 0) {
|
||||
|
||||
// look for last usable editable if at end
|
||||
|
|
@ -643,7 +661,8 @@ BEGIN_PROTECTED
|
|||
--object_index;
|
||||
|
||||
m_object_indexes.clear ();
|
||||
m_object_indexes.push_back (object_index);
|
||||
m_object_indexes.resize (mp_properties_pages.size ());
|
||||
m_object_indexes [m_index].push_back (object_index);
|
||||
|
||||
--m_current_object;
|
||||
update_title ();
|
||||
|
|
@ -669,12 +688,12 @@ PropertiesDialog::update_title ()
|
|||
bool
|
||||
PropertiesDialog::any_next () const
|
||||
{
|
||||
if (m_object_indexes.empty ()) {
|
||||
if (m_index < 0 || m_object_indexes [m_index].empty ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int index = m_index;
|
||||
if (m_object_indexes.front () + 1 >= mp_properties_pages [index]->count ()) {
|
||||
if (m_object_indexes [m_index].front () + 1 >= mp_properties_pages [index]->count ()) {
|
||||
++index;
|
||||
}
|
||||
|
||||
|
|
@ -685,12 +704,12 @@ PropertiesDialog::any_next () const
|
|||
bool
|
||||
PropertiesDialog::any_prev () const
|
||||
{
|
||||
if (m_object_indexes.empty ()) {
|
||||
if (m_index < 0 || m_object_indexes [m_index].empty ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int index = m_index;
|
||||
if (m_object_indexes.front () == 0) {
|
||||
if (m_object_indexes [m_index].front () == 0) {
|
||||
--index;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ private:
|
|||
db::Manager *mp_manager;
|
||||
lay::Editables *mp_editables;
|
||||
int m_index, m_prev_index;
|
||||
std::vector<size_t> m_object_indexes;
|
||||
std::vector<std::vector<size_t> > m_object_indexes;
|
||||
QStackedLayout *mp_stack;
|
||||
QLabel *mp_none;
|
||||
lay::MainWindow *mp_mw;
|
||||
|
|
|
|||
|
|
@ -514,7 +514,7 @@ struct LayerSelectionComboBoxPrivateData
|
|||
};
|
||||
|
||||
LayerSelectionComboBox::LayerSelectionComboBox (QWidget *parent)
|
||||
: QComboBox (parent), dm_update_layer_list (this, &LayerSelectionComboBox::do_update_layer_list)
|
||||
: QComboBox (parent), dm_update_layer_list (this, &LayerSelectionComboBox::do_update_layer_list), m_ignore_layer_list_changed (false)
|
||||
{
|
||||
mp_private = new LayerSelectionComboBoxPrivateData ();
|
||||
mp_private->no_layer_available = false;
|
||||
|
|
@ -651,7 +651,9 @@ LayerSelectionComboBox::set_view (lay::LayoutViewBase *view, int cv_index, bool
|
|||
void
|
||||
LayerSelectionComboBox::on_layer_list_changed (int)
|
||||
{
|
||||
update_layer_list ();
|
||||
if (! m_ignore_layer_list_changed) {
|
||||
update_layer_list ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -795,8 +797,8 @@ LayerSelectionComboBox::set_current_layer (const db::LayerProperties &props)
|
|||
setCurrentIndex (-1);
|
||||
}
|
||||
|
||||
void
|
||||
LayerSelectionComboBox::set_current_layer (int l)
|
||||
const db::Layout *
|
||||
LayerSelectionComboBox::layout () const
|
||||
{
|
||||
const db::Layout *layout = mp_private->layout;
|
||||
if (! layout && mp_private->view) {
|
||||
|
|
@ -805,9 +807,22 @@ LayerSelectionComboBox::set_current_layer (int l)
|
|||
layout = & cv->layout ();
|
||||
}
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
if (l >= 0 && layout && layout->is_valid_layer ((unsigned int) l)) {
|
||||
mp_private->last_props = layout->get_properties ((unsigned int) l);
|
||||
db::Layout *
|
||||
LayerSelectionComboBox::layout ()
|
||||
{
|
||||
return const_cast<db::Layout *> (((const LayerSelectionComboBox *) this)->layout ());
|
||||
}
|
||||
|
||||
void
|
||||
LayerSelectionComboBox::set_current_layer (int l)
|
||||
{
|
||||
const db::Layout *ly = layout ();
|
||||
|
||||
if (l >= 0 && ly && ly->is_valid_layer ((unsigned int) l)) {
|
||||
mp_private->last_props = ly->get_properties ((unsigned int) l);
|
||||
}
|
||||
|
||||
if (l < 0) {
|
||||
|
|
@ -821,6 +836,12 @@ LayerSelectionComboBox::set_current_layer (int l)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
LayerSelectionComboBox::is_no_layer_selected () const
|
||||
{
|
||||
return currentIndex () < 0;
|
||||
}
|
||||
|
||||
int
|
||||
LayerSelectionComboBox::current_layer () const
|
||||
{
|
||||
|
|
@ -832,7 +853,40 @@ LayerSelectionComboBox::current_layer () const
|
|||
}
|
||||
}
|
||||
|
||||
db::LayerProperties
|
||||
int
|
||||
LayerSelectionComboBox::current_layer_ensure ()
|
||||
{
|
||||
int i = currentIndex ();
|
||||
if (i < 0 || i > int (mp_private->layers.size ())) {
|
||||
|
||||
return -1;
|
||||
|
||||
} else if (mp_private->layers [i].second < 0) {
|
||||
|
||||
db::Layout *ly = layout ();
|
||||
if (! ly) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_ignore_layer_list_changed = true;
|
||||
try {
|
||||
unsigned int l = ly->insert_layer (mp_private->layers [i].first);
|
||||
mp_private->layers [i].second = l;
|
||||
m_ignore_layer_list_changed = false;
|
||||
return l;
|
||||
} catch (...) {
|
||||
m_ignore_layer_list_changed = false;
|
||||
throw;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
return mp_private->layers [i].second;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
db::LayerProperties
|
||||
LayerSelectionComboBox::current_layer_props () const
|
||||
{
|
||||
int i = currentIndex ();
|
||||
|
|
|
|||
|
|
@ -300,13 +300,37 @@ public:
|
|||
*/
|
||||
void set_current_layer (int l);
|
||||
|
||||
/**
|
||||
* @brief Gets a valid indicating whether a layer is selected
|
||||
*
|
||||
* This method returns true if "no layer" is selected
|
||||
*/
|
||||
bool is_no_layer_selected () const;
|
||||
|
||||
/**
|
||||
* @brief Get the current layer (index)
|
||||
*
|
||||
* NOTE: this method returns -1 if no layer is selected or
|
||||
* the current layer does not exist. Use "is_no_layer_selected"
|
||||
* for a value telling whether no layer is selected (true)
|
||||
* or a not-yet-existing layer is selected (false).
|
||||
*/
|
||||
int current_layer () const;
|
||||
|
||||
/**
|
||||
* @brief Get the current layer (index) and makes sure it exists
|
||||
*
|
||||
* This method ensures that the layer is created if it does not
|
||||
* exist yet. It returns -1 on "no layer" (if enabled).
|
||||
*/
|
||||
int current_layer_ensure ();
|
||||
|
||||
/**
|
||||
* @brief Get the current layer properties
|
||||
*
|
||||
* If "no layer" is selected, this method returns the last properties set
|
||||
* with "set_current_layer". Use "is_no_layer_selected" to get
|
||||
* a value indicating whether the "no layer" entry is selected.
|
||||
*/
|
||||
db::LayerProperties current_layer_props () const;
|
||||
|
||||
|
|
@ -323,10 +347,13 @@ protected slots:
|
|||
private:
|
||||
LayerSelectionComboBoxPrivateData *mp_private;
|
||||
tl::DeferredMethod<LayerSelectionComboBox> dm_update_layer_list;
|
||||
bool m_ignore_layer_list_changed;
|
||||
|
||||
void on_layer_list_changed (int);
|
||||
void update_layer_list ();
|
||||
void do_update_layer_list ();
|
||||
db::Layout *layout ();
|
||||
const db::Layout *layout () const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue