Detect update scene
-
@bob james said:
I would go so far as to request that auto-update be the default
No, I think most users expect SU's native functions to behave as usual.
-
@jiminy-billy-bob said:
@bob james said:
I would go so far as to request that auto-update be the default
No, I think most users expect SU's native functions to behave as usual.
I yield to the power
-
@dan rathbun said:
Hmmm.. I cannot get the EntityObserver to fire when the Page is updated.
Me neither... I guess I'll have to check for changes when the active page changes.
-
Actually, that's not even a good solution since users can change layers visibility between the scene update and the active scene change.
Am I stuck ? Hoping that one day Trimble will add this observer method... -
Perhaps if you explain 'in words', what it is you are trying to achieve/trap for then we might better suggest a work-around ??
I understand it your Layer tool 'switches Layers' properties'.
By default it should NOT affect any Scene [Page] layer-settings, unless you have some specific functions in the tool activated by say a button that is clicked by the user: like 'Update Current Scene's Layers' or 'Update All Scenes' Layers' [dangerous!]: then, on running the update function it's easy to get the page [from 'pages.selected_page' or one of the 'pages'], and then reset that page's layers using http://sketchup.com/intl/en/developer/docs/ourdoc/page.php#set_visibility
which allows you to control that page's layers visibility.
You can simply iterate through an array of ON or OFF layers and set them for that page.
page.set_visibility(layer, true)
orpage.set_visibility(layer, false)
Your tool should never reset a page's layers without the user's express knowledge.
If you are changing a layer's property - like 'not displaying on new pages' then the user needs to be aware of the change...
Your dialog needs to get the current layer statuses when it opens.
When a user switches to a scene, then if your dialog is open it needs to get the now current state of the layers; similarly if the user adds a layer or changes a layer-state manually or via another tool ?
BUT if your dialog is set to open as 'modal', then no such changes can be made while the dialog remains open - thus the layer states it gets at startup are always right [unless it's on a MAC which isn't supported anyway!]If this is not helpful then please expand on what it is you are trying to do here ?
-
In my plugin, you can nest layers in groups. By hiding a group, you hide all the nested layers. But, it keeps track of the layer's visibility before they were hidden-by-group. So when you unhide the group, the layers that were previously hidden stay hidden.
(The best way to understand it is to try it yourself )The problem is, when should I store the group's visibility, when I can't know when the scene is updated ?
So yeah, for now I update the scene (only the layers state) every time a layer or group visibility changes. I warn users on the download page, but that's clearly not ideal...
-
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