Detect update scene
-
Why do you change a scene's layers automatically?
This is doing something the user's won't anticipate or always want...When the tool opens it 'clones' the current-layers setup - which might be those from a scene-tab OR, if the user has recent manually manipulated the layers and not updated the scene-tab, there could be a mismatch between these two layer-sets... I assume you want to use the 'current-layers' as seen on screen...
I understand that you will want to apply the tool's changes to the current-layers setup 'on screen'... BUT those layers are not necessarily those used by the current Scene tab !
For example, what if I want to manipulate the layers setup and then make a new scene-tab using those - BUT I do NOT want to change the layers setup in the previously current scene-tab, do I ?
So after the user has 'reset the current layers'... can't you just let them 'update' [or create] their scene-tab[s] manually, OR perhaps have a button in your dialog that does 'Apply Changes to Current Scene-tab' ? That way you can use a scene-tab as the source, manipulate the layers on screen, without changing the scene-tab, then either update the scene-tab OR make a new scene-tab using those layers.
Dan's earlier suggestion http://sketchucation.com/forums/viewtopic.php?p=494139#p494139 allows you to spot when a layer's state changes, at that point simply repopulate the dialog with the current layer-settings ? No need to think about pages/scenes...
You will need to attach such an 'entity' observer to all existing layers as the tool is loaded [or a new model is opened etc using an App observer], and also a model.layers_observer to spot when the a new layer is added and then add the 'entity' observer to that too ? This can also spot when current layer changes [which you should not try to switch off]...Your pages observer can spot a page/scene change and repopulate the tool's layers set using the current layers.
This way the pages/page/layers/layer/app observers acting together can always [re]populate your dialog with the current layers setup: the page/scene-tab update should not be automatic - either the user manually updates the scene-tab[s] OR you add a button to do that...
-
@tig said:
Why do you change a scene's layers automatically?
Because I want the group's visibility and the nested layers' visibility to stay in sync. If a user saves the layers' visibility by updating the scene, I would not be aware of that, and wouldn't know what to do with the group's visibility.
-
Sorry, I am missing something here.
What happens if there are no scene-tabs in the model?
Presumably the layers still switch on/off as the user decides...
Why must the selected scene-tab's layers be affect immediately by the changes ?You could change the visibility of layers without ever doing anything to the scene-tab's layer settings.
Your layer changes are dynamic, and occur 'on screen' as the user makes them.
The user needs to decide when he updates a scene-tab, or makes another scene-tab to utilize the new layer settings, leaving the previous selected scene-tab's layers unaffected... The former can be done with a button in your tool's dialog or manually using 'update' on the scene-tab context-menu; the later needs to be done in the scene-tab context-menu or scene-manager ?When you activate your tool it must load a set of layers & groups from somewhere.
What happens if new layers have been manually added or layers manually deleted, what happens if a scene-tab is updated ?
By using the previously outlined observers you could establish these things and get a current layer set and repopulate the dialog when these things occur...
The grouping of layers persists across scene-tabs, the settings of the individual layers potentially changes with each scene-tab change, is the 'groups' setting remembered with a scene-tab ? -
@tig said:
Sorry, I am missing something here.
I guess videos will explain it better.
This is what I want to avoid, recorded withOUT auto-update :
[screenr:ac7tf0pd]yDqH[/screenr:ac7tf0pd]This is with auto-update :
[screenr:ac7tf0pd]2ZqH[/screenr:ac7tf0pd] -
I think I see the difference
So the layers change in your dialog to match the Scene-tab's [or the current manually setup] layers.
But when changing a Scene-tab the 'group' values are ignored...
So I see a couple of ways to resolve this without having to 'auto-update' the scene's layers to match the dialog and thereby confuse the user...You get/set an attribute array attached to the model for the 'Groups' and their 'Layers' contents [with visibility flags?].
You can also get/set an attribute array of Groups [with on/off flags] with each Scene [page].So now you have access to the permutations.
You manually make or update a scene-tab [either manually or through the tool itself], the current state of your tool's data, and the current Groups is then set as a 'Groups' attribute with that Scene [page].Later a scene-tab changes, the pages.selected_page gets its reference, and lets that you get its Groups attribute that the scene has had set earlier, and it then updates the tool's data saved in the model attribute - available even when the dialog is inactive, but read in when it next opens... The change of layers comes from the scene-tab, and is reflected in the tool's layer settings too...
You change the settings in the tool's dialog, these are dynamically saved to the model's attributes as Groups and their Layers. Only when the scene-tab is updated does that data get read to set the Groups attribute for the page.
One issue you need to address is the 'making of new layers'.
By SketchUp's default these are visible in all new scenes [auto-updating the scenes' layer lists], this is a know bugbear.
It is possible to set a flag for a layer as you make it, which then stops this behavior http://sketchup.com/intl/en/developer/docs/ourdoc/layer.php#page_behaviorI am sure this scene0tab auto-update issue can be circumvented with some careful planning
-
@tig said:
You manually make or update a scene-tab [either manually or through the tool itself], the current state of your tool's data, and the current Groups is then set as a 'Groups' attribute with that Scene [page].
Sure, that's what I'm trying to acheive. But the problem is how to detect manual updates ?
Everything else is up and running. I just need to find a way to detect a page update, otherwise everything gets messed up. I wouldn't know when to save the tool's data so that it matches the layers state when the user comes back to this page.
-
So we go full circle
A page is an entity.
So can you an an entity_observer to each page, that fires onChangeEntity ?
Do nothing to modify the page in the response - we are changing your tool...If the page changes on an 'update' does such an observer fire ?
-
-
We go round in circles...
Although page and layer are entities we cannot get valid/useful entity-observer results...
The layers and pages observer do not spot 'active/selected' changes.
A model-observer only spots undo-able transactions.
A tools-observer do not see page-update events.You could set up a UI timer to poll the pages, and get just the pages.selected_page [every few seconds ?] and save a @array of its '.layers' [or perhaps a hash? - perhaps using 'names' rather than id's as they will then be sortable?]: it compares the @array with the last time it saved this - @array_previous [cloned from the @array] - then if it mismatches it triggers your tool to redo the current layers based on the selected_page.layers [which returns an array of the page's non-visible layers]. This will work as the selected_page changes too, if the layers mismatch it updates the dialog...
You only need to set/compare the layer records for a page that is selected.
A user updating a non-selected page is coped with when that page becomes selected and your tool updates the layer set as it spots the change ?
I'll sleep on it...
Any other ideas ?? -
I wondered about a timer-based solution, but isn't it too heavy for performance ?
-
I suggest that you try it and see...
If the only tool we have is a hammer, watch out screws!A UI timer should run in parallel with other processes...
Your UI timer loop can kick in at say every 5 seconds - and it is stopped when the dialog closes - the newly opened dialog refreshes from the current settings anyway, and starts a new timer...
It is only collecting thepages.selected_page.layers
[perhaps as sorted layer.names for easier comparison ?] and then comparing those with the list it got the previous time [using a array == @array ?]. It does nothing if there is a match, but on a mismatch it refreshes your tool's layer lists ?
Some example code ideas:### when the dialog first opens and is to be 'populated'... @timer=UI.start_timer(5, true) @array=[] unless @array array=Sketchup.active_model.pages.selected_page.layers.collect{|e|e.name}.sort unless array==@array ### update your tool's dialog's layer list here... end @array=array.clone } ### ... ### elsewhere in dialog code... dialog.set_on_close{ UI.stop_timer(@timer) } ###
I know it's not ideal, but it might be the best you have ?
If it causes too many issues then we are no worse off ?
-
Got it fully working !
Thanks TIG for taking a deep look at this -
Well, actually it needs some tweaking ^^
-
Advertisement