VIX-3697 New Arch Prop#738
Conversation
johncbaur
left a comment
There was a problem hiding this comment.
Probably should address high level comments in confluence before tackling the comments identified here.
https://vixenlights.atlassian.net/wiki/x/AwALDQ
src/Vixen.Application/SetupDisplay/ViewModels/PropNodeTreeViewModel.cs
Outdated
Show resolved
Hide resolved
src/Vixen.Application/SetupDisplay/ViewModels/PropNodeTreeViewModel.cs
Outdated
Show resolved
Hide resolved
src/Vixen.Modules/Editor/FixtureWizard/FixtureWizard_sreonfzn_wpftmp.csproj
Show resolved
Hide resolved
src/Vixen.Application/SetupDisplay/Wizards/Pages/DimmingWizardPage.cs
Outdated
Show resolved
Hide resolved
src/Vixen.Application/SetupDisplay/Wizards/Views/DimmingWizardPageView.xaml
Show resolved
Hide resolved
b68ff74 to
1f8bd43
Compare
jeffu231
left a comment
There was a problem hiding this comment.
I am not sure if this is still WIP, but many of the comments have yet to be addressed with these last updates. The Extended.Wpf package needs to also have a replacement since its license prevents us from using it. If it is still WIP, then I will await further comment until you are ready.
|
Absolutely WIP. I've made A LOT of changes over the last few weeks and am
conducting testing now. I hope to have something to evaluate for
everyone on Wednesday. I will write all the changes up in Confluence.
Thanks,
David Markson
*Cell*: (817) 584-4755
*E-mail*: ***@***.***
…On Mon, Feb 16, 2026 at 10:31 AM Jeff ***@***.***> wrote:
***@***.**** commented on this pull request.
I am not sure if this is still WIP, but many of the comments have yet to
be addressed with these last updates. The Extended.Wpf package needs to
also have a replacement since its license prevents us from using it. If it
is still WIP, then I will await further comment until you are ready.
—
Reply to this email directly, view it on GitHub
<#738 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/BMJ3GZRAE6CN5IDAVRYQSD34MHWFTAVCNFSM6AAAAACJN67Y7WVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZTQMBZGU2DCOJVGY>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
|
A lot of changes. Please review the Confluence page for details |
| @@ -0,0 +1,58 @@ | |||
| namespace Vixen.Sys.Props.HelperTools | |||
| { | |||
| public class PropParameters : Dictionary<string, object> | |||
There was a problem hiding this comment.
Still trying to figure out the purpose for this helper class but if we continue forward with it, I think all usages of it should use the nameof() method on properties instead of string constants. This should allow developers to rename properties and this code will go along for the ride.
UPDATE: So I have reviewed more of the changes. I don't think we can use the nameof because the explicit properties have been removed and been replaced with the Dictionary. I think this PropParameters has some downsides:
- Using strings as keys to this Dictionary is inefficient when compared to directory property usage.
- It also makes it difficult to rename properties as we will have to search for the strings.
- I think it might be harder to read and inspect the code.
- Prevents using reflection to discover properties
- May complicate XML serialization if we go down that path
- Prevents being able to implement INotifyPropertyChange
- Prevents putting additional code in the setter of the property
| } | ||
| else if (!VixenSystem.Props.IsUniquePropTitle(value)) | ||
| { | ||
| MessageBox.Show($"{value} already exists. Enter a unique name.", "Prop name must be unique", MessageBoxButtons.OK, MessageBoxIcon.Error); |
There was a problem hiding this comment.
My objection is with the MessageBox. Models should not directly spawn UI's. I think we should strive for clear separation of business rules and UI.
Not sure it reaching out to the database of props is a good idea.
This is just speculation but what if I created a temporary Prop for some use case and as soon as the name is set it pops up this message box when the prop was going to get destroyed?
|
|
||
|
|
||
| private ObservableCollection<AxisRotationModel> _rotations; | ||
| public ObservableCollection<AxisRotationModel> Rotations |
There was a problem hiding this comment.
Rotations should not be unique to a LightProp.cs. I think this property was originally on the model at the base level. I sort of would like to do a deeper dive discussion with @jeffu231 on why we need both a model and a prop. Seems like if we combined these classes we might make our lives easier. Need to have a discussion before taking any action on this comment.
There was a problem hiding this comment.
Need to move this class back to Vixen.Application ViewModels folder.
| public static readonly IPropertyData IsSubNodeProperty = RegisterProperty<bool>(nameof(IsSubNode), false); | ||
| #endregion | ||
|
|
||
| private void OnIsTopNodeChanged() |
There was a problem hiding this comment.
This method appears not be used.
| } | ||
| public static readonly IPropertyData IsTopNodeProperty = RegisterProperty<bool>(nameof(IsTopNode), true); | ||
|
|
||
| public bool IsSubNode |
There was a problem hiding this comment.
If IsTopNode and IsSubNode are inverses of each other used for visibility there are several methods of handling that in the XAML with InverseBooleanToVisibilityConverter. Only change if this appeals to you.
|
|
||
| #endregion | ||
|
|
||
| #region Temporary properties to get Change Prop to work |
There was a problem hiding this comment.
This is a strange region name. What is meant by Temporary?
| IPropFactory newPropFactory = PropFactory.CreateInstance(propType); | ||
|
|
||
| // Create a default Prop | ||
| (IProp newProp, IPropGroup propGroup) = newPropFactory.CreateBaseProp(); |
There was a problem hiding this comment.
This is where I noticed that supporting groups got broken. The previous design was that the prop(s) were not created until the user had gone through Wizard to know how many props to create. Seems like to me we may need to hide the Group page when editing the prop after initial creation. We also probably need to look into allowing the user to just hit finish rather than forcing them to go through all the pages. I think Nick was asking for this feature as well.
| internal void UpdatePreviewModel(IProp prop, bool force = false) | ||
| { | ||
| if (force == true) | ||
| DrawProp(prop?.PropModel); |
There was a problem hiding this comment.
I don't think we want to have this force argument. Is there a strong need for it? If we continue to support a prop preview and a full setup preview, we have two OpenTK contexts running simultaneously. My testing showed that this could result in only one of the two actually drawing because the other one seemed to get confused.
I tried to document this on the DrawProp method.
///
/// This method needs to be called within the OpenTK control render method.
/// Otherwise the two OpenTK controls get confused and the prop preview won't render properly or consistently.
///
|
|
||
| #endregion] | ||
|
|
||
| private Axis GetAxis(string axis) |
There was a problem hiding this comment.
This method appears to be no longer used.
| }; | ||
| } | ||
|
|
||
| private string GetAxis(Axis axis) |
There was a problem hiding this comment.
This method appears to be no longer used.
| <ResourceDictionary Source="../Themes/Theme.xaml"/> | ||
| </ResourceDictionary.MergedDictionaries> | ||
|
|
||
| <BooleanToVisibilityConverter x:Key="BoolToVis"/> |
There was a problem hiding this comment.
This XAML file already has a BooleanToVisibilityConverter.
|
|
||
| namespace VixenApplication.SetupDisplay.Wizards.Factory | ||
| { | ||
| public static class PropFactory |
There was a problem hiding this comment.
Could this just be another method in the PropWizardFactory?
If not, best practice is that each class gets its own cs file.
| NodeCount = 25; | ||
| Title = "Basic Attributes"; | ||
| Description = $"Enter attributes for {PropType.Arch.GetEnumDescription()}"; | ||
| NodeCountMinimum = 3; |
There was a problem hiding this comment.
Do we want a NodeCountMaximum? I know all my arches are ~70 pixels, so 100 is not very large. You see videos of putting arches over sidewalks and driveways. I would imagine a driveway would be more than 100 pixels. Seems like the maximum could grow to something unreasonable like the size of short or int.
The legacy Arch smart object seems to let the count grow.
| /// Gets or sets the NodeCount value. | ||
| /// Gets or sets the number of lights. | ||
| /// </summary> | ||
| /// <remarks> |
There was a problem hiding this comment.
I believe the Wizard pages are effectively models. We shouldn't need to create Catel properties on the models.
| /// <summary> | ||
| /// Gets or sets if the wizard will additionally generate a left and right prop. | ||
| /// </summary> | ||
| public bool LeftRight |
There was a problem hiding this comment.
The wizard pages are the model and I don't believe need to be Catel properties.
| /// </summary> | ||
| /// <param name="nodePoints"></param> | ||
| /// <param name="angleInDegrees"></param> | ||
| protected static void RotateNodePoints(List<NodePoint> nodePoints, int angleInDegrees) |
There was a problem hiding this comment.
This method is only used by the Line model which really isn't in use anymore.
We should clean this up.
| // (Optionally) rotate the points along the X, Y, and Z axis | ||
| RotatePoints(treePoints); | ||
| //ToDo : Replace null with rotation | ||
| RotatePoints(treePoints, null); |
There was a problem hiding this comment.
Rotations on the tree were working. Not sure why this code was changed to pass null.
Not sure why the argument was added.
| private IEnumerable<NodePoint> Get3DNodePoints(float width, float height) | ||
| protected override IEnumerable<NodePoint> Get3DNodePoints() | ||
| { | ||
| float width = (float)PropParameters["Width"]; |
There was a problem hiding this comment.
I am not sure the prop models need a width and height.
The props were rendering with a normalized with and height of 1x1.
Suggest setting width and height local variables to 1.0f here.
| protected BaseLightProp(string name, PropType propType) : base(name, propType) | ||
| { | ||
| StringType = StringTypes.Pixel; | ||
| Rotations = new ObservableCollection<AxisRotationModel>(); |
There was a problem hiding this comment.
This is probably a duplicate comment but Rotations belong in BaseProp.
| /// </summary> | ||
| /// <syntax> | ||
| /// <p>Function Definition Table syntax:</p> | ||
| /// <p>Function Definition Table syntax:<br> |
There was a problem hiding this comment.
Was this change intentional?
Look like we have a 'p' tag that is not closed.
| LeftRight = false; | ||
|
|
||
| } | ||
| DimmingTypeOption = DimmingType.NoCurve; |
There was a problem hiding this comment.
Shouldn't these Dimming options be initialized in the base class?
| [PropertyOrder(11)] | ||
| public int NodeSize | ||
| private int _lightSize; | ||
| public int LightSize |
There was a problem hiding this comment.
Could this be moved to BaseLightProp ? Seems like all Light props are going to have a Light size.
| catch (Exception ex) | ||
| { | ||
| Logging.Error(ex, $"An error occured handling Arch property {e.PropertyName} changed"); | ||
| private void Arch_PropertyChanged(object? sender, PropertyChangedEventArgs e) |
There was a problem hiding this comment.
This event handler can probably be removed.
|
|
||
|
|
||
| // Create Preview model | ||
| PropModel = new ArchModel(); |
There was a problem hiding this comment.
This class looks like it was updated such that the Arch properties are disconnected from the PropModel properties. The properties on the Arch (prop) can be changed and they won't be reflected on the PropModel. Seems like that could cause problems and was not the original design.
|
|
||
| public MountingPositionType MountingPosition { get; set; } | ||
|
|
||
| public ObservableCollection<AxisRotationModel> Rotations { get; set; } |
There was a problem hiding this comment.
We shouldn't have to define Rotations on every prop model. We should define it once in the base class.
| Gamma = 2.2; | ||
| Curve = null; | ||
|
|
||
| ColorTypeOption = ColorType.SingleColor; |
There was a problem hiding this comment.
Shouldn't the color attributes get initialized in the base class BaseLightProp?
| InitializeComponent(); | ||
| } | ||
|
|
||
| private ColorType ColorTypeOption |
There was a problem hiding this comment.
I don't understand why this view has properties. Was this cloned from the DimmingWizardPageView? Standard MVVM you bind directly to the view model.
| } | ||
| } | ||
|
|
||
| private void SingleColorButtonClick(object sender, RoutedEventArgs e) |
There was a problem hiding this comment.
Normally in MVVM you set up commands and the view model has boolean flags to determine which controls are visible.
There was a problem hiding this comment.
I don't know what this file is. Seems like it should not be in source control.
| Library | ||
| } | ||
|
|
||
| public enum ColorType |
There was a problem hiding this comment.
Should we consider using ColorProperty.cs - ElementColorType ?
| SelectedItem="{Binding SelectedColorSet, Mode=TwoWay}"> | ||
| <ComboBox.ItemsSource> | ||
| <x:Array Type="{x:Type sys:String}"> | ||
| <sys:String>RGB</sys:String> |
There was a problem hiding this comment.
We should probably create an enumeration for the Color Mixing order we support. I think EnumDescriptionTypeConverter can decorate the enum to provide strings in the WPF UIs.
| } | ||
| private static readonly IPropertyData SingleColorProperty = RegisterProperty<Color>(nameof(SingleColorOption)); | ||
|
|
||
| public ObservableCollection<string> ColorSetNames |
There was a problem hiding this comment.
When doing color mixing (RGB) I think we should consider creating an enum for the color sets / color order we support. This probably means we need separate state for discrete color set names vs RGB, RGBW, color order. The former is entirely user defined. The RGB, RGBW options are determined at compile time and can be represented in an enumeration.
| <RowDefinition Height="auto" /> | ||
| </Grid.RowDefinitions> | ||
|
|
||
| <WindowsFormsHost x:Name="ZedGraphControlHost" Grid.Row="0" Grid.Column="0" Width="295" Height="295" Margin="0,3,0,0"> |
There was a problem hiding this comment.
I hesitate to make these comments given I imagine getting this curve stuff working on the Wizard page was probably a lot of work. I commend the effort. Ideally we would have a WPF user control that we drop on this Wizard page that could be reused.
The fact that it does not fit on the Wizard page as it stands is not ideal. The part that off the page could be moved to the right of the drawing area but I am not sure it is worth the effort or to have two versions of the Curve editor in the solution.
Given Jeff views curves as an Advanced feature used sparingly. The Wizard page could just have a button to launch the existing WinForms curve editor and we don't have to touch that code.
| #endregion | ||
|
|
||
| #region Public Properties | ||
| public ColorType ColorTypeOption |
There was a problem hiding this comment.
Wizard pages are models and don't need to use Catel properties. I think there extra overhead with Catel properties that is not needed for these models and sets a bad example to copy.
The code needs a complete review as this will be the basis for future props.
Other notes: