Closed NickeZ closed 7 years ago
In the display builder, some widgets do have an 'enabled' property. That was meant to be a runtime property, used by the widget runtime internally, for example if a PV is missing or read-only. I'll turn them into true runtime properties, not configurable in the editor.
If you really want to not have a widget there, use the visible property. The background and foreground color of invisible widgets is consistently transparent ;-)
As for the representation of disabled widgets, I started by simply disabling the underlying Java FX widget. That does the trick: It appears the way JavaFX decided that disabled UI items should look, i.e. somewhat greyed out. You can no longer interact with the widget, for example not enter a text into a text entry widget. But that also means you can't interact with the widget at all, not even open the context menu for inspecting PVs, what you might have to do to determine why the widget is disabled. So I ended up showing them somewhat greyed out as Java FX does, still 'enabled' in the Java FX sense, but trying to ignore input by for example not being 'editable', details depend on the widget.
I see, I was going to use it for PVs that exists but aren't implemented in the driver yet. So whatever value is printed in the widget can safely be ignored. It's a way for me to do the whole OPI and try to get a feeling of it before implementing the whole driver. It might be to small use case for you to consider. I'll just change the foreground color for now to imitate a disabled state.
Understood. Somewhat related to #1972, where a display shows PVs that are not meant to exist, and the user should then not be confused by 'disconnected' widget states. For that, I'd suggest to simply not place missing PVs on a display. In your case you have the PVs, they will become functional, it's just not all implemented, yet. I wouldn't worry too much about that, just add a label "Preview, not functional" for now. If you plan to add access security to your IOCs anyway, you could also place those records in an ASG "DISABLED" which removes write access, so then the widgets will become disabled just as they would in an operational setup when you have no write access.
I'm going to try out the ASG: DISABLED
. Seems like the most appropriate solution. On the other hand I still think it should be up to the screen designer to specify how "non-writable" widgets should look.
One more comment. If I have a widget that doesn't connect to any PV at all that should still be able to show a disabled state. And I guess you were ironic when you said that I could make the widgets invisible, but I also want to make clear that I think that is a terrible UX to hide stuff that you merely want to disable.
An ASG that prohibits write access should work nicely. Key widgets already show a 'disabled' look when the PV cannot be written.
(Left: Widgets with read-only PV)
Widgets that don't, yet, properly represent a disabled state can be updated to do so.
As for disconnected, #1972, disconnected PVs are a severe problem. Disconnected PVs cannot be part of an expected operational setup. Widgets must clearly indicate that there is no connection and that the widget cannot display any meaningful value. If you have for example two types of motors, some that have feature X and some that don't, there can't be one display where the disconnected PVs related to the missing feature X are simply shown in some disabled state. You need two different displays (most straight forward). Technically, you could have one display with a script that makes the widgets for missing PVs invisible, but this is not the best solution. For one it requires a script, which is always harder to understand and maintain. It also creates search requests for the PVs on the network that you know are not there. That creates unnecessary network traffic. When you later debug your control system setup to identify typos in PV names, you see those search requests and wonder: Are these faulty displays, or were these meant to not exist?!
An ASG that prohibits write access should work nicely.
I agree, except if the disabled widget does not connect to a PV. As in it maybe opens another OPI or runs a script or whatever.
Key widgets already show a 'disabled' look when the PV cannot be written.
I know, but this is currently not customizable. I'm not saying it has to be, but I don't think I can make consistent UIs with the current implementation. It looks like the opacity is changed on the widget but you probably want to change the brightness. If I for example design multiple themes for my interface the brightness should probably change different amounts in different themes.
As for disconnected, #1972, disconnected PVs are a severe problem.
Yes but why is it up to BOY/BOB to decide which PVs are a severe problem? I think it is wrong for the framework to cripple alarm handling in this way. AFAIK you want to reduce the amounts of alarms/indicators to the most useful ones. If multiple PVs belong to the same device and those PVs dies there is no benefit to go bananas and paint pink over the whole screen. This "feature" also makes it more difficult to design OPIs before the actual IOC is running.
Widgets must clearly indicate that there is no connection and that the widget cannot display any meaningful value.
Sure don't remove that possibility and it is probably a good default value. But I think the framework shouldn't be opinionated about the alarms.
You need two different displays (most straight forward).
What about the DRY principle? It seems like that will quickly become an unmaintainable mess if I have multiple devices with multiple optional features.
Technically, you could have one display with a script that makes the widgets for missing PVs invisible, but this is not the best solution.
I don't want to make stuff invisible, aren't people going to come asking where the buttons went? It seems like a horrible user experience that stuff disappears.
It also creates search requests for the PVs on the network that you know are not there. When you later debug your control system setup to identify typos in PV names, you see those search requests and wonder: Are these faulty displays, or were these meant to not exist?!
Why would a disabled widget connect to a PV? That doesn't sound necessary.
tl.dr. I think that mixing the "Disabled" state of a widget with the "disconnected" and/or the "readable/writable" property is wrong and you are limiting the users of BOB. I also think all cases deserve "full" customizability, i.e. let the interface designer change bg/fg/border colors.
Sorry, I still don't see your use case. Are you planning to have operational displays for stuff that doesn't exist? Will operators in the control room use screens where items are disabled on purpose because the PVs don't exist? Why put them on in the first place?
If you have a "simple" and a "sophisticated" motor, of course you use the DRY principle: A basic_motor.bob for the simple one. The sophisticated.bob embeds basic_motor.bob and adds the widgets for the extra PVs. Fully modular.
I agree with you that "mixing the disabled state .. with disconnected .. is wrong". In operational EPICS setups, IOCs run for years. They're only offline for updates and reboots during maintenance days. Disconnected is otherwise a big problem that needs to be obvious, not masked as disabled, i.e. an expected state. Disabled is for read-only access: It's there, but the specific user cannot change that PV right now because of access restrictions. You can still read, though, so the widget keeps showing values, only disables the write access.
As for customizing the 'disabled' look:
It needs to be consistent for all widgets, not one widget type showing up shaded, another has a gray border and yet another one shows a red 'X'.
In principle, JavaFX already has a way to do this: Node.setDisable
. There's the technical issue that this fully disables the node, won't react to context menu requests, so can't get the PV name etc.
So we assign a .not_enabled
style. There is one entry in a style sheet that allows defining the look of disabled widgets: https://github.com/kasemir/org.csstudio.display.builder/blob/master/org.csstudio.javafx/src/org/csstudio/javafx/csstudio.css That style sheet path could become a preference setting, so for your site you can increase the opacity or instead change the background, within the limits of the styling support of the different Java FX nodes.
Are you planning to have operational displays for stuff that doesn't exist?
Maybe, we will have stuff that move around and will be accessible through different PVs depending on which network it currently sits. I want to be able to handle disconnects gracefully in this case because it might not be the end of the world.
Will operators in the control room use screens where items are disabled on purpose because the PVs don't exist? Why put them on in the first place?
One example is that we have PV naming conventions and behavior conventions for data acquisition cards which means that I can use exactly the same screen for all our data acquisition cards. Having disconnected PVs might not be useful in the control room, but we design a lot of OPIs which aren't for the control room. (Hell, we don't even have a control room at ESS yet...)
If you have a "simple" and a "sophisticated" motor, of course you use the DRY principle: A basic_motor.bob for the simple one. The sophisticated.bob embeds basic_motor.bob and adds the widgets for the extra PVs. Fully modular.
Sure, but I have a feeling that you mix up all my arguments to win the discussion.
I agree with you that "mixing the disabled state .. with disconnected .. is wrong". In operational EPICS setups, IOCs run for years. They're only offline for updates and reboots during maintenance days. Disconnected is otherwise a big problem that needs to be obvious, not masked as disabled, i.e. an expected state. Disabled is for read-only access: It's there, but the specific user cannot change that PV right now because of access restrictions. You can still read, though, so the widget keeps showing values, only disables the write access.
We essentially disagree on what the different words mean. When you say disabled you mean read only. This means that BOY and BOB have a different interpretation for the same word. (I don't know what happens to the widget if a PV is read only in BOY actually, does it also get the disabled property? At least I know that I could set widgets to disabled and they wouldn't be responsive.)
So we assign a .not_enabled style. There is one entry in a style sheet that allows defining the look of disabled widgets: https://github.com/kasemir/org.csstudio.display.builder/blob/master/org.csstudio.javafx/src/org/csstudio/javafx/csstudio.css That style sheet path could become a preference setting, so for your site you can increase the opacity or instead change the background, within the limits of the styling support of the different Java FX nodes.
Great I thought the behavior it was hard coded. I agree with you that it should be consistent and it is probably enough to have a single place to define how "disabled" should work. But it might also be limiting someone because of a use case we can't think of.
stuff that move around ... different PVs .. depending on which network
We have a similar case on beam lines. Devices where I/O modules can be added or removed.
Our display consists of several embedded displays, and a script or rule updates what's shown in each embedded section:
That seems to fit your example where you'd switch between blank.bob and stuff.bob, and also handles the case where there are more options.
Note that rules only get invoked for value updates from connected PVs.
Same for scripts by default, but scripts have an option to also get invoked for disconnects.
In our case we do have a PV that tells us what's there, so we use a rule to update the embedded widget's file
property based on that PV.
When you use a script, you can react to either the value of a PV or also to the disconnected state, see the 10_scripts.bob
example.
While this ticket is about BOY, I'm updating the 'enabled' handling for the display builder, see its ticket.
In there I try to describe the meaning of 'disabled', which should answer
Why would a disabled widget connect to a PV? That doesn't sound necessary.
Example: Checkbox that's disabled will still reflect the current state of its PV. The checkbox will check/uncheck as the PV changes, but you can't click on the checkbox to write to the PV. If a widget should disconnect, set the pv_name to empty.
This ticket is about both BOB and BOY.
If you want to update the BOY representation, its look of disabled widgets, go ahead.
For the display builder, enabled/disabled will be as discussed in https://github.com/kasemir/org.csstudio.display.builder/issues/210. A widget disabled by setting 'enabled=false' in either the property editor or a script/rule will remain disabled. A widget enabled by setting 'enabled=true' in either the property editor or a script/rule will indeed be enabled (user can enter text, push button, toggle checkbox) while the PV is writable. It will disable when the PV becomes read-only. This can happen at runtime, in fact that's the point of dynamic channel access security, and the UI needs to reflect it.
Enable/disable is all about enabling/disabling the interactive behavior of the widget. To disconnect it from the PV (for example to test displays while PVs don't exist), set the PV name to empty. Or, sometimes it's also useful to create a test database that just has placeholder PVs.
Hey, I'm playing around a bit in BOB and when I set the property "enabled" to "false" for a widget that seems to be ignored in runtime.
Since widgets looks so different in BOY in disabled state I propose that we have separate background and foreground colors for disabled widgets.
Cheers