Rick Brewster

CodeLab v4.3 (for advanced users) Released July 13, 2019

Recommended Posts

I added a feature to CodeLab which I think is quite useful. I've always hated inserting new controls in the middle of some previously-defined controls, and having to renumber the Amount variables; so I added a "Renumber UI Variables" option to the Edit list. A new control can be created with any unused number and inserted, out of order, into the middle of the other UI variables. Running the renumber option renumbers the UI variables consecutively, and changes all the UI variable uses in the code to match. (Though I explained it in terms of adding a new variable, renumbering also allows UI variables to be rearranged in any order, and then renumbered.)

 

I changed only two files: CodeLabConfigDialog.cs to add the option into the Edit menu along with the mouse-click event handler, and CodeTextBox.cs to add the renumbering code. I also added a little renumber icon PNG file.

 

I have no intention of starting a separate ColeLab line (heaven forbid!). I was hoping that perhaps if the feature is popular, BoltBait might possibly add it (or some variation of it) to a future revision of CodeLab.

 

The renumbering code is:

Hidden Content:

        public bool CanRenumberUIVariables
        {
            get
            {
                // Might want enable only if there are UI variables.
                return !string.IsNullOrEmpty(this.Text);
            }
        }

        // Renumber the Amount vaiables so they are in order from 1 to n.
        // The variables can originally be numbered in almost any manner.
        // I try to catch most error conditions. I don't catch the condition where there's a gap in the UI
        // numbers, and that variable is created in the user (non-UICode) part of the code.
        private int[] varNum = null; // Must be accessable to MatchEvaluator.
        private int numVars = 0;
        public bool RenumberUIVars()
        {
            string text = this.Text;
            varNum = new int[100];
            numVars = GetCurrentUINumbering(text, varNum);

            if (numVars == -1)
            {
                MessageBox.Show("Could not process the UICode region.", "Renumber Error");
                return false;
            }

            // There are obviously more efficent appoaches that don't require searching through
            // the array. But this method is straight forward and given the number of variables,
            // should work just fine.

            // Check for duplicate entries and determine if the variables are already in order.
            bool needsRenumbering = false;
            for (int i = 0; i < numVars; i++)
            {
                int myNum = varNum[i];
                if (myNum != i + 1)
                    needsRenumbering = true;

                // Check for duplicates.
                for (int j = i + 1; j < numVars; j++)
                {
                    if (myNum == varNum[j])
                    {
                        MessageBox.Show("Amount" + myNum.ToString() + " occurs more than once.", "Renumber Error");
                        return false;
                    }
                }
            }

            if (!needsRenumbering)
            {
                MessageBox.Show("No renumbering required.", "Renumber");
                return true;
            }

            // Change the Amount variable names so renumbered and non-renumbered variables aren't confused.
            // The substituted string is random, but shouldn't occur in any source code.
            text = Regex.Replace(text, @"\bAmount(\d+)\b", "Amt%!%$1");

            // Change the old names to the new names.
            this.Text = Regex.Replace(text, @"Amt%!%\d+", ReplaceWithRenumbered);

            MessageBox.Show("Renumbering complete.", "Renumber");
            return true;
        }

        private string ReplaceWithRenumbered(Match m)
        {
            int n;
            if (int.TryParse(m.Value.Substring(6), out n))
            {
                // If in range, substitute the renumbered value, else used original value.
                // Try to find the new number in the renumber array.
                int i;
                for (i = 0; (varNum[i] != n) && (i < numVars); i++)
                    ;
                return "Amount" + ((i == numVars) ? n : i + 1).ToString();
            }
            else
            {
                // This shouldn't happen, but just in case.
                return "Amount" + m.Value.Substring(6);
            }
        }

        private int GetCurrentUINumbering(string text, int[] results)
        {
            int varCnt = 0;
            int max = results.Length - 1;

            string findUIRegion = @"\#region UICode$(?s:(?<uicode>.*?))\n\#endregion";
            Match m = Regex.Match(text, findUIRegion, RegexOptions.Multiline);
            if (!m.Success)
                return -1;

            string textUI = m.Groups["uicode"].Value;
            string pattern = @"\s*Amount(?<number>\d+)[ =;\t]";
            foreach (Match mv in Regex.Matches(textUI, pattern))
            {
                int n;
                if (int.TryParse(mv.Groups["number"].Value, out n))
                {
                    // (This should always find an integer.)
                    results[varCnt] = n;
                    if (varCnt++ == max)
                        break;  // Just ignore any unprocessed variables (this shouldn't happen!)
                }
            }

            return varCnt;
        }

 

If anyone wants to try it, the DLL is here: <snip>

 

The VS (2013) project is here:

Edited by BoltBait

Share this post


Link to post
Share on other sites

MJW, please don't distribute a modified CodeLab.

I love what you've done and I'll include it in the next release of CodeLab.

But, in the future, just PM me something like that and I'll look at it. I usually accept code contributions.

I've got some other small changes already done, so I'll look at your code this weekend and incorporate it. Then I'll make an official build.

Share this post


Link to post
Share on other sites

PM me your real name and I'll be sure to add it to the About box.

Share this post


Link to post
Share on other sites

Thank you very much, BoltBait, but I'm not sure such a minor contribution warrants inclusion in the About menu, and for some reason I'm reluctant to have my actual identity revealed (I use my MJW handle on many sites besides Paint.NET forums). So for right now, I'll just remain the anonymous MJW.

Share this post


Link to post
Share on other sites

CodeLab 2.5 Released

This is only for Paint.NET 4.0!

Changes:

▪ Two buttons added to the "View Source" screen.

▪ You can no longer build untitled files to dll. (Requested by skyoxZ)

▪ Added UI Elements Renumber command. (Requested by MJW)

Grab the CodeLab DLL here:

http://www.boltbait.com/pdn/CodeLab/

How to Renumber UI Elements

The easiest way to work with CodeLab is to design your UI first, then write the code to your effect. I usually do this using the UI Designer located in the File > User Interface Designer menu. For example, let's say you want to design an effect with a foreground and background color selection. After using the User Interface Designer your code may look like this:

#region UICode
ColorBgra Amount1 = ColorBgra.FromBgr(0,0,0); // Foreground
ColorBgra Amount2 = ColorBgra.FromBgr(0,0,0); // Background
#endregion
:
Now, let's assume you've written your effect and everything's working fine. Then, later you decide to add an Alpha control for each of the color wheels. Here's the best way to do it:

Use the UI Designer to add 2 new Alpha Controls to the bottom of the list. After doing that, your code will look like this:

#region UICode
ColorBgra Amount1 = ColorBgra.FromBgr(0,0,0); // Foreground
ColorBgra Amount2 = ColorBgra.FromBgr(0,0,0); // Background
int Amount3 = 255; // [0,255] Foreground Alpha
int Amount4 = 255; // [0,255] Background Alpha
#endregion
:
At this point, you can write the code that makes the new controls work... or you can wait until you've reordered the controls.

You'll probably want the alpha controls under the corresponding color wheel controls. In order to do that, carefully reorder the lines of the UICode block, like so:

#region UICode
ColorBgra Amount1 = ColorBgra.FromBgr(0,0,0); // Foreground
int Amount3 = 255; // [0,255] Foreground Alpha
ColorBgra Amount2 = ColorBgra.FromBgr(0,0,0); // Background
int Amount4 = 255; // [0,255] Background Alpha
#endregion
:
DO NOT change the variable names... let's let CodeLab do that for you!

Notice in our code above, we've moved the Alpha slider Amount3 to just below Color wheel Amount1.

At this point you're ready to renumber the controls. Use the menu option File > Renumber UI Variables. After, your code looks like this:

#region UICode
ColorBgra Amount1 = ColorBgra.FromBgr(0,0,0); // Foreground
int Amount2 = 255; // [0,255] Foreground Alpha
ColorBgra Amount3 = ColorBgra.FromBgr(0,0,0); // Background
int Amount4 = 255; // [0,255] Background Alpha
#endregion
:
...and all of the rest of your code has been updated as well.

I also modified the User Interface Designer so that if you open it when the UI controls need to be renumbered, it will do that for you before the UI Designer opens.

NOTE: Although it is possible to reorder controls in the UI Designer, you will need to update your code manually to handle your changes done this way.

Share this post


Link to post
Share on other sites

CodeLab 2.5 in Russian


You can find the new version of CodeLab in Russian here.

Вы можете найти новую версию CodeLab на русском языке здесь.

Edited by ReMake

Share this post


Link to post
Share on other sites

I have a few related suggestions:

 

When CodeLab generates a new file, it should include the following type of header, with the entries left blank:

// Author:
// Name:
// Title:
// Submenu:
// Desc:
// Keywords:

 

(When building the DLL, blank fields should be ignored.)

 

The header should have fields for everything on the Build DLL menu except the icon. I don't believe there's currently any way to specify the version (and subversion) or that the plugin is an Adjustment.

 

When building the DLL, if the DLL builder can't find the icon .png file in the "source" directory, it should look in a "source\icons" subdirectory. That would make it easier to organize the icons.

 

I realize I can always copy the header from another file, and there isn't that much that needs to be entered in the DLL build menu, but my suggestions would make it easier (and prevent me from forgetting to enter the version number when building -- which I always seem to do.)

Edited by MJW
  • Upvote 1

Share this post


Link to post
Share on other sites

When CodeLab generates a new file, it should include the following type of header, with the entries left blank:

// Author:

// Name:

// Title:

// Submenu:

// Desc:

// Keywords:

That's a darn good idea. I'll make that change for the next release.

 

When building the DLL, if the DLL builder can't find the icon .png file in the "source" directory, it should look in a "source\icons" subdirectory. That would make it easier to organize the icons.

Meh. I don't know about this one. Maybe. I'll think about it.

 

...and prevent me from forgetting to enter the version number when building -- which I always seem to do.)

I should make a comment for the version number too.

  • Upvote 1

Share this post


Link to post
Share on other sites

Thank you, BoltBait. Having the DLL Build entries automatically filled in from the comments has certainly saved me a lot of annoyance. It was only recently I discovered that if the icon file is in the Source directory, I wouldn't have to enter it myself.

Share this post


Link to post
Share on other sites

Hi! So, I've been a happy user of CodeLab in the past (I created the Grim Color Reaper effect). However, updating Paint.net to 4.0.5 and CodeLab to 2.5, there are some puzzling issues:

 

1. Undo (Ctrl+Z) doesn't seem to work, it just moves the cursor back to the place of the last edit. This makes any editing final and is quite frustrating.

 

2. Code completion / Intellisense was announced but I can't seem to trigger it in any way (tried: hover text, select text, right click, tab, Ctrl+Enter).

 

3. If your filename is "Untitled.cs", CodeLab says you must save your file before compiling to dll (minor issue but can be quite confusing if you're firing up CodeLab for the first time and doing a quick test, giving the impression that it doesn't work).

Share this post


Link to post
Share on other sites

1. Yeah, Ctrl-Z doesn't work because now that I'm using a custom editor control (for syntax highlighting, etc.) I'd have to write my own Ctrl-Z undo handler. I'm just too lazy to do it. It is a pain, seriously. I actually spent half a day trying to implement this and I couldn't get anything to work acceptably. So, I gave up.

2. Code completion works when you press the "." key. For example, inside of your render loop, type:

Color.

After pressing the "." you should see a list of options. Arrow down and press "enter key" or "tab key" to select one.

3. CodeLab works just fine for tinkering. You don't need to name your effect if you don't plan on saving as a dll file. If you do plan on saving as a dll file, you must save your script first so that CodeLab will know what to name the dll file. This name is also used for the namespace. By specifying a unique filename/namespace, you prevent plugins walking all over each other.

Share this post


Link to post
Share on other sites

CodeLab 2.6 Released

This is only for Paint.NET 4.0.6+!

Changes:

▪ Added empty script comments to the default script for build screen default values. (Requested by MJW)

▪ Fixed processing of script comments for when comments are empty.

▪ Added 4 forms of help capability to built effects. (Tutorial 6) (Requested my MJW)

▪ Added help content editor to Save as DLL screen.

▪ Added // Help: comment for help content.

▪ Added "custom help" to File New templates.

▪ Cleaned up "using" statements for compiled scripts.

▪ Cleaned up some of the File New template code generation.

▪ Added access to current and default palettes in File New templates. (Requested by MJW)

 

 

Grab the CodeLab DLL here:

http://www.boltbait.com/pdn/CodeLab/

HelpButton.png

HelpEditorUI.png

  • Upvote 5

Share this post


Link to post
Share on other sites

When I try to build CodeLab26, I get the following error:

The designer cannot process the code at line 716:
this.largeFontToolStripMenuItem.CheckState = (EditorInLargeFontMode) ? CheckState.Checked : CheckState.Unchecked;
The code within the method 'InitializeComponent' is generated by the designer and should not be manually modified.
Please remove any changes and try opening the designer again. 

I know I've had the same problem building previous versions, but I can't for the life of me remember what I did about it. I can tell VS to ignore the error and continue, but I'm a little nervous about doing so, because it gives me one of those, "Are you absolutely certain you want to do this? Continuing may end civilization as we know it!" warnings.

Share this post


Link to post
Share on other sites

Stop opening that file!

Seriously, don't open that file. That's the solution.

Share this post


Link to post
Share on other sites

I'm not sure what you mean. I only opened the file in the sense that I loaded the solution into Visual Studio (by clicking CodeLab.sln) to build the project. I didn't modify or specifically open any of the files before clicking Build Solution.

Edited by MJW

Share this post


Link to post
Share on other sites

I have a suggestion. I think the double-vector position control should be changed to three decimal places instead of the current two. As it is, there are only 200 or so possible values, which means for most reasonable window sizes, the position cannot be placed within a pixel. Even with three decimal places, positioning for large windows wouldn't be within a  single pixel, but at least it would usually be fine enough to be useful. I didn't use the position control in my Texture Shader plugin for that very reason.
 

Edited by MJW

Share this post


Link to post
Share on other sites

I have a suggestion. I think the double-vector position control should be changed to three decimal places instead of the current two.

I have no control over the precision of the double-vector control. That would be something for Rick to implement.

If you need more precision than the double-vector control can offer, try using one of the individual slider types (int or float).

Share this post


Link to post
Share on other sites

That's too bad. I assumed (without looking) that it was one of those values that could be set in all that IndirectUI initialization code.

 

I do use the sliders instead, but for positioning within the window, they seem inelegant compared to the position control.

Share this post


Link to post
Share on other sites

 

I didn't use the position control in my Texture Shader plugin for that very reason.

You can change the Double Vector UpDownIncrement in VS if that helps. Won't show another digit but means you can fine adjust with the up/down slider end arrows.

Try my 'Gears' plugin for an example.

Three decimal places as default would be better though IMO!

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.