MJW Posted October 24, 2015 Share Posted October 24, 2015 (edited) I wish someone who understands the subject would write a tutorial on using regular Visual Studio controls (non-PropertyBased controls) in plugins. I have some vague notion how it's done from looking at the code for Red ochre's Scribble plugin, but I'm not sure I understand exactly how the pieces fit together. (I'd also like to encourage anyone who understands some matter of general interest to write a tutorial, the way BoltBait has done for CodeLab. I intend to try to do so.) Edited October 24, 2015 by MJW Quote Link to comment Share on other sites More sharing options...
toe_head2001 Posted October 24, 2015 Share Posted October 24, 2015 What specifically would need to be covered in the tutorial? Hooking up the UI controls to the Effect Tokens? Specifying that the WinForm is a EffectConfigDialog? I assume you know how to populate a WinForm with standard controls, and create events for them. Quote My Gallery | My Plugin Pack Layman's Guide to CodeLab Link to comment Share on other sites More sharing options...
MJW Posted October 24, 2015 Author Share Posted October 24, 2015 (edited) I know how to create a regular VS Form, and if I didn't, I could find dozens of books and articles telling me how to do it. What I'd very much appreciate more details on, and which as far as I know isn't currently documented anywhere, is how to use the controls within the PDN plugin environment. As you mention, hooking up the UI controls to the Effect Tokens, and things like that. I'm not sure in what way declaring a WinForm to be an EffectConfigDialog makes it different from a standard WinForm class library project, but if it is different, I'd like to know about it. Most of the stuff I'd like to know, and which I think others might benefit from knowing, concerns how the token figures in to maintaining the control state and initiating traversals. Edited October 24, 2015 by MJW Quote Link to comment Share on other sites More sharing options...
toe_head2001 Posted October 24, 2015 Share Posted October 24, 2015 (edited) I've made a simplified code example here. Not exactly a "How to" or a tutorial, but I hope my comments are sufficient. This is your xyzConfigDialog.cs file. It acts as a WinForm file. See first code comment. namespace xyzEffect { // Notice it doesn't say " : Form", but rather " : EffectConfigDialog<xyzEffectPlugin, xyzConfigToken>" // Another option is simply " : EffectConfigDialog", but I don't like that option internal partial class xyzConfigDialog : EffectConfigDialog<xyzEffectPlugin, xyzConfigToken> { // Standard stuff here. No need to explain. public xyzConfigDialog() { InitializeComponent(); } //When the checkbox is toggled it tells the Tokens to update private void checkBox1_CheckedChanged(object sender, EventArgs e) { FinishTokenUpdate(); } //When the numberBox is toggled it tells the Tokens to update private void numericUpDown1_ValueChanged(object sender, EventArgs e) { FinishTokenUpdate(); } // Initailized the Tokens from your xyzConfigToken.cs file protected override xyzConfigToken CreateInitialToken() { return new xyzConfigToken(); } // Sets the UI control values from the stored token values protected override void InitDialogFromToken(xyzConfigToken fromToken) { checkBox1.Checked = fromToken.UseColor; numericUpDown1.Value = fromToken.Width; } //Sets the token values from the UI control values protected override void LoadIntoTokenFromDialog(xyzConfigToken toToken) { toToken.UseColor = checkBox1.Checked; toToken.Width = numericUpDown1.Value; } } } This is your xyzConfigToken.cs file namespace xyzEffect { // Notice the " : EffectConfigToken" class xyzConfigToken : EffectConfigToken { private bool t_useColor; private int t_width; // Initializes the configuration token public xyzConfigToken() : base() { t_useColor = true; t_width = 20; } private xyzConfigToken(bool useColor, int width) { t_useColor = useColor; t_width = width; } public override object Clone() { return new xyzConfigToken(t_useColor, t_width); } // These are the public functions that can be referrence from other classes public bool UseColor { get { return t_useColor; } set { t_useColor = value; } } public int Width { get { return t_width; } set { t_width = value; } } } } This is your xyzEffect.cs file namespace xyzEffect { // Notice the " : Effect<xyzConfigToken>", rather than " : PropertyBasedEffect" // Another option is simply " : Effect". Again, I don't like that option. internal class xyzEffectPlugin : Effect<xyzConfigToken> { ... bool useColor; int width; // Inside OnSetRender, grab the saved Tokens so that your cool script can use their values. protected override void OnSetRenderInfo(xyzConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs) { useColor = newToken.UseColor; width = newToken.Width; } ... // The rest is standard stuff... Edited October 24, 2015 by toe_head2001 2 Quote My Gallery | My Plugin Pack Layman's Guide to CodeLab Link to comment Share on other sites More sharing options...
MJW Posted October 24, 2015 Author Share Posted October 24, 2015 Thank you so much, toe_head2001! I'll probably have a few questions tomorrow, after I have a chance to study it a bit. Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted October 24, 2015 Share Posted October 24, 2015 I made IndirectUI largely so most folks wouldn't ever have to worry about WinForms and manual data binding It can be a real mess. Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted October 24, 2015 Share Posted October 24, 2015 MJW some of the Dwarves collaborated on such a guide. I will send you a PM and a link. 3 Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker Link to comment Share on other sites More sharing options...
MJW Posted October 24, 2015 Author Share Posted October 24, 2015 Thank you, Ego Eram Reputo! I'm eager to read it. Perhaps it could be published in the Developer's Forum as a How-to. 1 Quote Link to comment Share on other sites More sharing options...
ReMake Posted October 24, 2015 Share Posted October 24, 2015 ...Perhaps it could be published in the Developer's Forum as a How-to. I think the publication of this material could stimulate the developers of effects plugins. 1 Quote Link to comment Share on other sites More sharing options...
BoltBait Posted October 24, 2015 Share Posted October 24, 2015 I would like to see a tutorial (including links to resources) on how to use the OptionBased library. Once I play with it and learn the ins-and-outs, I wonder if I could add support for it in CodeLab... Who is the developer/maintainer of the OptionBased library? 1 Quote Click to play: Download: BoltBait's Plugin Pack | CodeLab | and how about a Computer Dominos Game Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted October 25, 2015 Share Posted October 25, 2015 Thank you, Ego Eram Reputo! I'm eager to read it. Perhaps it could be published in the Developer's Forum as a How-to. I think the publication of this material could stimulate the developers of effects plugins. It started out as my own reference tool. It's grown over time, but is still far from ready for a public release. Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker Link to comment Share on other sites More sharing options...
MJW Posted October 25, 2015 Author Share Posted October 25, 2015 (edited) It may take a little while, but I hope by combining what I learn from Red ochre's Scribble plugin, toe_head2001's comment, and Ego Eram Reputo's guide, I'll understand it well enough to write a How-to post. I intend to concentrate on the subject of binding controls to data that can be used by PDN. Other Visual Studio plugin issue can be dealt with separately (and some already are in "Help needed: Using Visual Studio instead of CodeLab for developing" and BoltBait's "Beyond CodeLab" tutorial). Edited October 25, 2015 by MJW Quote Link to comment Share on other sites More sharing options...
null54 Posted October 25, 2015 Share Posted October 25, 2015 In addition to using the built-in Windows Forms controls many of the Indirect UI controls can be replicated. I ported Red Ochre's FurBlur plugin to use Windows Forms to allow XML presets to be used, a screenshot of the resulting UI is here. The source code in this post has been replaced by the attachment in post #20 3 Quote Plugin Pack | PSFilterPdn | Content Aware Fill | G'MIC | Paint Shop Pro Filetype | RAW Filetype | WebP Filetype The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait Link to comment Share on other sites More sharing options...
ReMake Posted October 25, 2015 Share Posted October 25, 2015 (edited) Thank you for the source code, null54. It's very useful. Edited October 25, 2015 by ReMake Quote Link to comment Share on other sites More sharing options...
MJW Posted October 25, 2015 Author Share Posted October 25, 2015 null54, that's very interesting because my primary reason for asking about non-PropertyBased effects was I had the idea that I might make an Open Source-type library of IndirectUI lookalike controls. It looks like you've already gone quite a ways in that direction. Quote Link to comment Share on other sites More sharing options...
null54 Posted October 26, 2015 Share Posted October 26, 2015 null54, that's very interesting because my primary reason for asking about non-PropertyBased effects was I had the idea that I might make an Open Source-type library of IndirectUI lookalike controls. It looks like you've already gone quite a ways in that direction. If you look at the Paint.NET code with ILSpy you can see that many of the IndirectUI controls use the native Windows Forms controls while handling all the layout and databinding. The PaintDotNet folder in the FurBlur source code contains the custom controls from the Paint.NET 3.36 source code that are used to recreate the feel of IndirectUI, the rest are standard WinForms controls. 1 Quote Plugin Pack | PSFilterPdn | Content Aware Fill | G'MIC | Paint Shop Pro Filetype | RAW Filetype | WebP Filetype The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait Link to comment Share on other sites More sharing options...
MJW Posted October 26, 2015 Author Share Posted October 26, 2015 (edited) Thanks for the link to the disassembler, null54. I didn't have a disassembler and have been meaning to install one if I could find a decent free one. I had assumed from their appearance that many IndirectUI controls were pretty much standard WinForm controls, usually with the addition of the (very useful) reset button. Making custom controls which are combinations of other controls is pretty easy, as I recall, so those would probably be relatively simple to implement. I'm not too concerned about the lay-out issue. IndirectUI's auto-positioning is convenient, if inflexible, but positioning controls isn't too difficult in VS, so I think that could be left to the plugin programmer. The hard part would be devising a data-binding scheme that's as transparent and easy to use as possible. I think that the more that could be built into the controls the better, but because they all share the token class, that seems to me to be difficult to achieve. (Given my current incomplete understanding of how it all works, the previous sentence may be completely confused and off base.) EDIT: Now that I've had the chance to look at the code and the guide a little more carefully, I see that the controls are not that closely tied to the token system, which is good. From what I gather, there are really just a few fairly simple things that need to be done: InitialInitToken must create a token with the default values. InitDialogFromToken must assign the token's values to the controls. InitTokenFromDialog must save the control values in the token. FinishTokenUpdate initiates a new traversal (and causes InitTokenFromDialog to be called). As far as I know, the only special thing the controls need to do is, when their values are changed, call a routine which (normally) calls FinishTokenUpdate. (For those who don't already know, the token is a class that pretty much just contains the same things as the CodeLab Amount variables. The values in the token are copied over to local variables in OnSetRenderInfo.) EDIT 2: I'm sure I could figure it out for myself (pretty sure, at least), but I don't see in the FurBlur or Scribble code where the reset-arrow buttons are added or processed, though I can see from running the plugins that they are. Perhaps someone more familiar with the code can explain how that works. Edited October 27, 2015 by MJW Quote Link to comment Share on other sites More sharing options...
null54 Posted October 28, 2015 Share Posted October 28, 2015 EDIT 2: I'm sure I could figure it out for myself (pretty sure, at least), but I don't see in the FurBlur or Scribble code where the reset-arrow buttons are added or processed, though I can see from running the plugins that they are. Perhaps someone more familiar with the code can explain how that works. The Windows Forms version of FurBlur does not have reset buttons, mainly because I have not found a good way to store the defaults. Quote Plugin Pack | PSFilterPdn | Content Aware Fill | G'MIC | Paint Shop Pro Filetype | RAW Filetype | WebP Filetype The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait Link to comment Share on other sites More sharing options...
MJW Posted October 28, 2015 Author Share Posted October 28, 2015 I'm glad I didn't spend a lot of time looking! I have some ideas on how to do it. Quote Link to comment Share on other sites More sharing options...
null54 Posted October 28, 2015 Share Posted October 28, 2015 I'm glad I didn't spend a lot of time looking! I have some ideas on how to do it. I ended up adding a new class to store the original values. The attached source code now has reset buttons, and the UI was updated to match Red Ochre's latest version. FurBlurWinFormsSource.zip 1 Quote Plugin Pack | PSFilterPdn | Content Aware Fill | G'MIC | Paint Shop Pro Filetype | RAW Filetype | WebP Filetype The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait Link to comment Share on other sites More sharing options...
MJW Posted October 28, 2015 Author Share Posted October 28, 2015 Thank you, null54, that will be very helpful. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.