-
Notifications
You must be signed in to change notification settings - Fork 289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DUALITY-150 - Resource Selection Dialog #593
Conversation
Thanks for the PR! I have assigned the team of community contributors for a first review session and will take a look myself as well soon. |
Looks good to me. Well formatted and structured 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there an icon you think would be more fitting? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General note on Duality code style: Please prefer explicit type names over var
. I've seen this in some places, but didn't want to flag each of them.
@@ -0,0 +1,82 @@ | |||
namespace Duality.Editor.Forms | |||
{ | |||
using System; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duality Code Style: Using directives should be at the top of the file, outside of the namespace and separated via newline.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noted. I'll update this.
Hopefully you are also aware of the subtlety in resolution when the using statements are outside of the namespace declaration.
@@ -18,9 +18,12 @@ | |||
|
|||
namespace Duality.Editor.Plugins.Base.PropertyEditors | |||
{ | |||
using Forms; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duality Code Style: Using directives should be at the top of the file, outside of the namespace and separated via newline.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above.
{ | ||
if (this.buttonShowPressed && this.buttonShowHovered) this.ShowReferencedContent(); | ||
if (this.buttonShowPressed && this.buttonShowHovered) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that the "show" button has been repurposed to "select", we should also rename the variables referring to it, such as buttonShowPressed
and potential others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Roger. This is where I thought refactoring out the input elements would be beneficial. For now I will focus on just addressing the comment, but ill make a note to come back to this later.
{ | ||
var tmpDataObject = new DataObject(); | ||
|
||
tmpResourceSelectionForm.SerializeToData(tmpDataObject); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we de/serialization here - maybe just expose the selection via property and access it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping to keep this as minimal a change as possible, and given the way paste, copy, drag and drop are used I'm leery of deviating too far. Can you elaborate further on what you would like to see?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure! So the reason for serialization at the point where I assume you copied it from is that we're stashing things in the Windows clipboard via Ctrl+C / Ctrl+V. Since this means that data can, in some situations, travel outside of Duality, serialization is a requirement to make this work.
With the new dialog, however, there is no need for data to ever leave Duality. Just hand it over like you would normally, e.g. ask the dialog what the user selected directly. One way to go about this would be to add a SelectedResult
property to the dialog class, which is retrieved where you also check for the DialogResult
.
Okay, so I did a quick code review (changes above) and also took a deeper look at behavior and implementation. Very clean PR so far, nicely minimal and to-the-point, big 👍 for that! We still have some things ahead before merging though, here's a list of things I found:
As you will notice, some of them are high-level quality or consistency control, so we're on the right track here :) Let us know if you have questions or there's more to discuss. (Also, thanks to @AdamsLair/duality-contributors for the first level review - feel free to stay around and join the discussion!) |
Updated the description of the PR to reflect requested changes. Will get into them as time permits. Have you looked into using a linter or a service like SonarQube/SonarSource for quality controls and validation of the day to day contributions? |
Up and down now navigate up and down in the tree view
I am unable to reproduce the scrollbar situation in the latest build of the branch. I had already resized the dialog, but the behavior itself does not look to have been changed. Attempted Repro Steps:
Repeat for 50 bitmapsRepeat for 50 Components |
Huh, weird. Thanks for checking! I'll take a look myself in the next review stage. See if I can find a fix or workaround with the repro on my machine. Ping me when you're ready for the code review 👍 |
Okay. I switched over to the label and text field due to the sample form @ilexp pointed to. I can switch back pretty quickly, so I'll hold off for a bit on any other feedback. |
I think I am ready for the next review. @ilexp |
Added to my ToDo, will get back to you as soon as I manage 👍 If any of the @AdamsLair/duality-contributors want to user test the latest changes or start with the code review, go ahead. I'll join in. |
What do you think about the cuetextbox vs. Text box and a label? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Saw some minor formatting issues but other than that looks clean. This the first review I did so if you have any suggestions feel free to say so.
tmpNode.Name.ToLowerInvariant().Contains(tmpFilterValue) || | ||
tmpNode.Path.ToLowerInvariant().Contains(tmpFilterValue) | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor thing but formatting seems to be a bit off
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replaced the spaces with tabs.
@@ -14,6 +14,7 @@ public static class EditorBaseResCache | |||
{ | |||
public static readonly Bitmap DropdownSettingsBlack = EditorBaseRes.DropdownSettingsBlack; | |||
public static readonly Icon IconEye = EditorBaseRes.IconEye; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting is a bit off here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might actually be due to using tabs for alignment (as opposed to indentation) and GitHub using a different tab size. If it looks good in VS with a tab size of 4, that's alright.
The proper solution would be to use spaces for alignment (but not indentation), which is a style guide that I only started implementing later in the project, so this file not doing it that way is me not having updated it yet. Since it has nothing to do with this PR, I'd just make sure the tab solution works in VS / with tab size 4 and not change anything else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understood.
protected bool buttonShowHovered = false; | ||
protected bool buttonShowPressed = false; | ||
protected bool buttonSelectHovered = false; | ||
protected bool buttonSelectPressed = false; | ||
protected bool panelHovered = false; | ||
protected Point panelDragBegin = Point.Empty; | ||
protected Bitmap prevImage = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting is a bit off here
protected bool buttonShowHovered = false; | ||
protected bool buttonShowPressed = false; | ||
protected bool buttonSelectHovered = false; | ||
protected bool buttonSelectPressed = false; | ||
protected bool panelHovered = false; | ||
protected Point panelDragBegin = Point.Empty; | ||
protected Bitmap prevImage = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting is a bit off here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See tab alignment comment above.
I don't have a strong opinion either way, maybe slight favor towards the cue text one, if any. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks good overall! Some change requests and suggestions on the code style side. I think we're good to go after addressing them, ping me when you're ready.
|
||
this.ComponentReference = component; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Style:
- Fields should be next to fields, properties should be next to properties and methods should be next to methods. Do not mix them if it can be avoided within reason.
- Keep statics at the top, instance methods below.
- If the number of members of the same type grows beyond what can be easily observed with a full overview, try to group semantically where it makes sense.
- Use two newlines to separate different member types, one newline to separate semantic groups within the same type, no newline between items of the same semantic group and type.
Example:
public class Foo
{
private int field1;
private int field2;
private int field3;
public int Property1
{
get { /* ... */ }
set { /* ... */ }
}
public int Property2
{
get { /* ... */ }
set { /* ... */ }
}
public int Property3
{
get { /* ... */ }
set { /* ... */ }
}
public Foo()
{
// ...
}
public void Method1()
{
// ...
}
public void Method2()
{
// ...
}
public void Method3()
{
// ...
}
}
this.ComponentReference = component; | ||
} | ||
|
||
private string _name; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Style: Do not use underscore prefixes for fields or parameters.
this.objectReferenceListing.BeginUpdate(); | ||
this.Model.Nodes.Clear(); | ||
|
||
if (this.FilteredType.IsSubclassOf(typeof(GameObject)) || this.FilteredType == typeof(GameObject)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: Use typeof(GameObject).IsAssignableFrom(this.FilteredType)
to wrap this up in a single check. Also covers cases where you'd have an interface type instead of GameObject
.
{ | ||
ReferenceNode tmpNode = new ReferenceNode(currentObject); | ||
|
||
this.Model.Nodes.Add(tmpNode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: The newline between the two lines of the inner loop doesn't seem to be necessary. Keep it if you want (not a change request), but as a general rule of thumb, I try to make every newline express something meaningful and avoid those where it's not clear what exactly they're separating, like logical code blocks. Here, instantiating the node and adding the node each are so short and self-documenting that they might as well be regarded as a single logical unit, in which case they don't really need the newline.
|
||
foreach (Component currentComponent in Scene.Current.FindComponents(this.FilteredType)) | ||
{ | ||
ReferenceNode tmpNode = new ReferenceNode(currentComponent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: This is also true for other places in code, but why is this variable prefixed with a tmp
? It isn't really any more temporary than any other local variable, so might as well skip the prefix and give it a regular name. node
would be just fine here as long as the context is clear and there's no ambiguity in scope.
@@ -14,6 +14,7 @@ public static class EditorBaseResCache | |||
{ | |||
public static readonly Bitmap DropdownSettingsBlack = EditorBaseRes.DropdownSettingsBlack; | |||
public static readonly Icon IconEye = EditorBaseRes.IconEye; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might actually be due to using tabs for alignment (as opposed to indentation) and GitHub using a different tab size. If it looks good in VS with a tab size of 4, that's alright.
The proper solution would be to use spaces for alignment (but not indentation), which is a style guide that I only started implementing later in the project, so this file not doing it that way is me not having updated it yet. Since it has nothing to do with this PR, I'd just make sure the tab solution works in VS / with tab size 4 and not change anything else.
protected bool buttonShowHovered = false; | ||
protected bool buttonShowPressed = false; | ||
protected bool buttonSelectHovered = false; | ||
protected bool buttonSelectPressed = false; | ||
protected bool panelHovered = false; | ||
protected Point panelDragBegin = Point.Empty; | ||
protected Bitmap prevImage = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See tab alignment comment above.
if (tmpPropertyInfo != null) | ||
{ | ||
t = tmpPropertyInfo.PropertyType; | ||
} else if (tmpFieldInfo != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Style: This should be
}
else if (...)
{
@@ -201,7 +230,7 @@ protected override void OnPaint(PaintEventArgs e) | |||
rectText, | |||
format); | |||
|
|||
ControlRenderer.DrawBorder(e.Graphics, | |||
this.ControlRenderer.DrawBorder(e.Graphics, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call adding the missing this.
👍
} | ||
} | ||
|
||
this.objectReferenceListing.NodeFilter += this.NodeFilter; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this event subscription separate from the others in the constructor?
…onentReference to AutoProperties.
I think I have addressed the formatting issues and code quality issues raised in the earlier comments. I think we are good to go. @ilexp |
Sounds great, code looks good as well. Thank you for your work on this! I think I can take over from here with my side of the ToDo:
I'll post here with my progress on this. |
#FIX: Fixed a bug where entering a non-existent filter value would spawn an exception in the selection code.
#CHANGE: Adjusted column header background color using a header draw callback.
#CHANGE: Components now display the full path of their GameObjects in the Path column, and a combo of short name and type name in the Name column.
Added some final touches to the code, merged to master and triggered a binary release. The new dialog will be out there in about 15 minutes. I'll close issue #150 and proceed to create one for the remaining optional items. |
Created new issues for the remaining items. We're done here. Thanks! 😃 |
Overview
This PR Provides the requested interface addition detailed in #150, to allow a user to select a resource from a filtered list. It provides all available resources to the user in a form that looks like the following:
As can be seen in the screenshots, the header of the form changes to explain to the user the type of resource they are currently looking for. It filters from the list of resources provided by the
IContentProvider
interface.There are three major parts of this change proposal:
ObjectRefPropertyEditor
interaction model:ObjectRefPropertyEditor
derivative elements to track the type of the editorI took a look through the test cases and I didn't see anything in the way of UI test cases for representative test cases, but I did run our current nunit test cases and they are all passing. I am quite interested in the thoughts you all have as to how you would like to proceed with automated test cases on a change of this nature.
Manual Test Cases & Validation
ContentProvider
interfaceOK
the resource reference should remain the sameCancel
the resource reference should remain the sameOK
the resource reference should update to the new resourceCancel
the resource reference should remain the sameComponent
references aGameObject
it should provide a populated listing to select one from the current scene.Component
references aComponent
it should provide a populated listing to select one from the current scene.I am open to further test cases. =)
TODO
using
statements to be outside the namespace declarations, per S&PbuttonShowPressed
tobuttonSelectPressed
select
button should not be grayed out when no selection is presentContentRefDialog
form toObjectRefSelectionDialog
CreateObjectDialog
where possible.Further Enhancements