Basic implementation of the 'layer binding' feature of issie #2116

This commit is contained in:
Matthias Koefferlein 2025-08-15 22:58:03 +02:00
parent a73aa1115f
commit 491dd3bb26
3 changed files with 106 additions and 7 deletions

View File

@ -156,7 +156,7 @@ PropertiesPage::attach_service (img::Service *service)
layer_binding_cbx->set_no_layer_available (true);
if (service && service->view ()) {
int cv_index = 0; // TODO: fixed currently
int cv_index = service->view ()->active_cellview_index ();
layer_binding_cbx->set_view (service->view (), cv_index, true);
} else {
layer_binding_cbx->set_view (0, -1);

View File

@ -291,7 +291,7 @@ void
View::render (const lay::Viewport &vp, lay::ViewObjectCanvas &canvas)
{
const img::Object *image = image_object ();
if (! image) {
if (! image || ! image->is_visible ()) {
return;
}
@ -420,12 +420,16 @@ Service::Service (db::Manager *manager, lay::LayoutViewBase *view)
m_move_mode (Service::move_none),
m_moved_landmark (0),
m_keep_selection_for_move (false),
m_images_visible (true)
m_images_visible (true),
m_visibility_cache_valid (false)
{
// place images behind the grid
z_order (-1);
mp_view->annotations_changed_event.add (this, &Service::annotations_changed);
mp_view->layer_list_changed_event.add (this, &Service::layer_list_changed);
mp_view->active_cellview_changed_event.add (this, &Service::layer_visibilty_changed);
mp_view->current_layer_list_changed_event.add (this, &Service::current_layer_list_changed);
}
Service::~Service ()
@ -437,9 +441,20 @@ Service::~Service ()
clear_transient_selection ();
}
void
Service::layer_visibilty_changed ()
{
if (m_visibility_cache_valid && ! m_visibility_cache.empty ()) {
view ()->redraw_deco_layer ();
}
m_visibility_cache_valid = false;
}
void
Service::annotations_changed ()
{
m_visibility_cache_valid = false;
// NOTE: right now, we don't differentiate: every annotation change may be a change in an image too.
// We just forward this event as a potential image changed event
images_changed_event ();
@ -450,7 +465,7 @@ Service::show_images (bool f)
{
if (m_images_visible != f) {
m_images_visible = f;
view ()->redraw ();
view ()->redraw_deco_layer ();
}
}
@ -919,6 +934,61 @@ Service::end_move (const db::DPoint &, lay::angle_constraint_type)
m_move_mode = move_none;
}
bool
Service::image_is_visible (const img::Object *image)
{
if (! image->is_visible ()) {
return false;
}
if (! m_visibility_cache_valid) {
std::vector<const img::Object *> images_with_bindings;
for (obj_iterator user_object = mp_view->annotation_shapes ().begin (); user_object != mp_view->annotation_shapes ().end (); ++user_object) {
const img::Object *i = dynamic_cast <const img::Object *> ((*user_object).ptr ());
if (i && ! i->layer_binding ().is_null ()) {
images_with_bindings.push_back (i);
}
}
m_visibility_cache.clear ();
if (! images_with_bindings.empty ()) {
for (auto img = images_with_bindings.begin (); img != images_with_bindings.end (); ++img) {
m_visibility_cache.insert (std::make_pair (*img, true));
}
int cv_index = view ()->active_cellview_index ();
if (cv_index < 0) {
cv_index = 0;
}
const lay::LayerPropertiesList &lp = view ()->get_properties ();
for (auto i = lp.begin_const_recursive (); ! i.at_end (); ++i) {
if (! i->has_children ()) {
const lay::ParsedLayerSource &source = i->source (true);
if (source.cv_index () == cv_index) {
for (auto img = images_with_bindings.begin (); img != images_with_bindings.end (); ++img) {
if (source.layer_props ().log_equal ((*img)->layer_binding ())) {
m_visibility_cache [*img] = i->visible (true);
}
}
}
}
}
}
m_visibility_cache_valid = true;
}
auto i = m_visibility_cache.find (image);
return i != m_visibility_cache.end () ? i->second : true;
}
const db::DUserObject *
Service::find_image (const db::DPoint &p, const db::DBox &search_box, double l, double &dmin, const std::set<img::Service::obj_iterator> *exclude)
{
@ -932,7 +1002,7 @@ Service::find_image (const db::DPoint &p, const db::DBox &search_box, double l,
lay::AnnotationShapes::touching_iterator r = mp_view->annotation_shapes ().begin_touching (search_box);
while (! r.at_end ()) {
const img::Object *image = dynamic_cast<const img::Object *> ((*r).ptr ());
if (image && image->is_visible () && (! exclude || exclude->find (mp_view->annotation_shapes ().iterator_from_pointer (&*r)) == exclude->end ())) {
if (image && image_is_visible (image) && (! exclude || exclude->find (mp_view->annotation_shapes ().iterator_from_pointer (&*r)) == exclude->end ())) {
images.push_back (&*r);
}
++r;
@ -1318,7 +1388,7 @@ Service::select (const db::DBox &box, lay::Editable::SelectionMode mode)
lay::AnnotationShapes::touching_iterator r = mp_view->annotation_shapes ().begin_touching (search_dbox);
while (! r.at_end ()) {
const img::Object *iobj = dynamic_cast<const img::Object *> ((*r).ptr ());
if (iobj && iobj->is_visible () && (! exclude || exclude->find (mp_view->annotation_shapes ().iterator_from_pointer (&*r)) == exclude->end ())) {
if (iobj && image_is_visible (iobj) && (! exclude || exclude->find (mp_view->annotation_shapes ().iterator_from_pointer (&*r)) == exclude->end ())) {
if (is_selected (*iobj, box)) {
any_selected = true;
if (select (mp_view->annotation_shapes ().iterator_from_pointer (&*r), mode)) {
@ -1464,7 +1534,7 @@ Service::render_bg (const lay::Viewport &vp, lay::ViewObjectCanvas &canvas)
lay::AnnotationShapes::touching_iterator user_object = mp_view->annotation_shapes ().begin_touching (vp.box ());
while (! user_object.at_end ()) {
const img::Object *image = dynamic_cast <const img::Object *> ((*user_object).ptr ());
if (image && image->is_visible ()) {
if (image && image_is_visible (image)) {
images.push_back (image);
}
++user_object;

View File

@ -457,6 +457,11 @@ public:
return m_images_visible;
}
/**
* @brief Returns a value indicating whether the given image is visible
*/
bool image_is_visible (const img::Object *image);
/**
* @brief Implement the menu response function
*/
@ -513,6 +518,9 @@ private:
bool m_keep_selection_for_move;
// Flag indicating whether images are visible
bool m_images_visible;
// The visibility cache for the layer bindings
bool m_visibility_cache_valid;
std::map<const img::Object *, bool> m_visibility_cache;
void show_message ();
@ -578,6 +586,27 @@ private:
* @brief Event handler for changes in the annotations
*/
void annotations_changed ();
/**
* @brief Event handler for changes in the layer visibility
*/
void layer_list_changed (int)
{
layer_visibilty_changed ();
}
/**
* @brief Event handler for a change of the current layer list
*/
void current_layer_list_changed (int)
{
layer_visibilty_changed ();
}
/**
* @brief Common handler for a potential change in layer visibility
*/
void layer_visibilty_changed ();
};
}