public CodeLabConfigToken() : base()
		{
			UserScriptObject = null;
			UserCode = "";
            LastExceptions = new List<Exception>();
			ScriptName = "MyScript";
		}
        public BackgroundEffectRenderer(Effect effect,
            EffectConfigToken effectToken,
            RenderArgs dstArgs,
            RenderArgs srcArgs,
            PdnRegion renderRegion,
            int tileCount,
            int workerThreads)
        {
            this.effect = effect;
            this.effectToken = effectToken;
            this.dstArgs = dstArgs;
            this.srcArgs = srcArgs;
            this.renderRegion = renderRegion;
            this.renderRegion.Intersect(dstArgs.Bounds);
            this.tileRegions = SliceUpRegion(renderRegion, tileCount, dstArgs.Bounds);

            this.tilePdnRegions = new PdnRegion[this.tileRegions.Length];
            for (int i = 0; i < this.tileRegions.Length; ++i)
            {
                PdnRegion pdnRegion = Utility.RectanglesToRegion(this.tileRegions[i]);
                this.tilePdnRegions[i] = pdnRegion;
            }

            this.tileCount = tileCount;
            this.workerThreads = workerThreads;

            if ((effect.EffectDirectives & EffectDirectives.SingleThreaded) != 0)
            {
                this.workerThreads = 1;
            }

            this.threadPool = new Threading.ThreadPool(this.workerThreads, false);
        }
        public EffectBenchmark(string name, int iterations, Effect effect, EffectConfigToken token, Surface image)
            : base(name + " (" + iterations + "x)")
		{
            this.effect = effect;
            this.token = token;
            this.image = image;
            this.iterations = iterations;
		}
        protected override Keys GetEffectShortcutKeys(Effect effect)
        {
            Keys keys;

            if (effect is DesaturateEffect)
            {
                keys = Keys.Control | Keys.Shift | Keys.G;
            }
            else if (effect is AutoLevelEffect)
            {
                keys = Keys.Control | Keys.Shift | Keys.L;
            }
            else if (effect is InvertColorsEffect)
            {
                keys = Keys.Control | Keys.Shift | Keys.I;
            }
            else if (effect is HueAndSaturationAdjustment)
            {
                keys = Keys.Control | Keys.Shift | Keys.U;
            }
            else if (effect is SepiaEffect)
            {
                keys = Keys.Control | Keys.Shift | Keys.E;
            }
            else if (effect is BrightnessAndContrastAdjustment)
            {
                keys = Keys.Control | Keys.Shift | Keys.C;
            }
            else if (effect is LevelsEffect)
            {
                keys = Keys.Control | Keys.L;
            }
            else if (effect is CurvesEffect)
            {
                keys = Keys.Control | Keys.Shift | Keys.M;
            }
            else if (effect is PosterizeAdjustment)
            {
                keys = Keys.Control | Keys.Shift | Keys.P;
            }
            else
            {
                keys = Keys.None;
            }

            return keys;
        }
Exemple #5
0
        private bool IsBuiltInEffect(Effect effect)
        {
            if (effect == null)
            {
                return true;
            }

            Type effectType = effect.GetType();
            Type effectBaseType = typeof(Effect);

            // Built-in effects only live in PaintDotNet.Effects.dll

            if (effectType.Assembly == effectBaseType.Assembly)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
 protected override bool FilterEffects(Effect effect)
 {
     return (effect.Category == EffectCategory.Adjustment);
 }
        private bool Build(bool toDll)
        {
            bool retVal = false;
            listErrors.Items.Clear();
            try
            {
                string prepend2 = " : base(\"" + txtScriptName.Text + "\", null) {}";
                if (toDll)
                {
                    string oldargs = param.CompilerOptions;

                    Uri location = new Uri(System.Reflection.Assembly.GetEntryAssembly().CodeBase);
                    string fullPath = Uri.UnescapeDataString(System.IO.Path.GetDirectoryName(location.AbsolutePath));

                    fullPath = Path.Combine(fullPath, "Effects");
                    fullPath = Path.Combine(fullPath, txtScriptName.Text);
                    fullPath = Path.ChangeExtension(fullPath, ".dll");

                    param.CompilerOptions = param.CompilerOptions + " /debug- /target:library /out:\"" + fullPath + "\"";
                    cscp.CompileAssemblyFromSource(param, prepend + prepend2 + txtCode.Text + append);

                    param.CompilerOptions = oldargs;

                }
                else
                {
                    userScriptObject = null;
                    result = cscp.CompileAssemblyFromSource(param, prepend + prepend2 + txtCode.Text + append);
                }

                if (result.Errors.HasErrors)
                {
                    foreach (CompilerError err in result.Errors)
                    {
                        CompilerErrorWrapper cew = new CompilerErrorWrapper();
                        cew.CompilerError = err;
                        listErrors.Items.Add(cew);
                    }
                }
                else if (!toDll)
                {
                    userAssembly = result.CompiledAssembly;

                    foreach (Type type in userAssembly.GetTypes())
                    {
                        if (type.IsSubclassOf(typeof(Effect)) && !type.IsAbstract)
                        {
                            userScriptObject = (Effect)type.GetConstructor(Type.EmptyTypes).Invoke(new object[] { });
                        }
                    }
                    retVal = (userScriptObject != null);
                }
                else
                {
                    retVal = true;
                }
            }
            catch (Exception exc)
            {
                userScriptObject = null;
                listErrors.Items.Add("Internal Error: " + exc.ToString());
            }
            if (!toDll)
            {
                FinishTokenUpdate();
            }
            return retVal;
        }
        public void RunEffect(Type effectType)
        {
            bool oldDirtyValue = AppWorkspace.ActiveDocumentWorkspace.Document.Dirty;
            bool resetDirtyValue = false;

            AppWorkspace.Update(); // make sure the window is done 'closing'
            AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar();
            DocumentWorkspace activeDW = AppWorkspace.ActiveDocumentWorkspace;

            PdnRegion selectedRegion;

            if (activeDW.Selection.IsEmpty)
            {
                selectedRegion = new PdnRegion(activeDW.Document.Bounds);
            }
            else
            {
                selectedRegion = activeDW.Selection.CreateRegion();
            }

            BitmapLayer layer = (BitmapLayer)activeDW.ActiveLayer;

            using (new PushNullToolMode(activeDW))
            {
                try
                {
                    Effect effect = (Effect)Activator.CreateInstance(effectType);

                    EffectEnvironmentParameters eep = new EffectEnvironmentParameters(
                        AppWorkspace.AppEnvironment.PrimaryColor,
                        AppWorkspace.AppEnvironment.SecondaryColor,
                        AppWorkspace.AppEnvironment.PenInfo.Width,
                        selectedRegion);

                    string name = effect.Name;
                    EffectConfigToken newLastToken = null;
                    effect.EnvironmentParameters = eep;

                    if (!(effect.IsConfigurable))
                    {
                        Surface copy = activeDW.BorrowScratchSurface(this.GetType() + ".RunEffect() using scratch surface for non-configurable rendering");

                        try
                        {
                            using (new WaitCursorChanger(AppWorkspace))
                            {
                                copy.CopySurface(layer.Surface);
                            }

                            DoEffect(effect, null, selectedRegion, selectedRegion, copy);
                        }

                        finally
                        {
                            activeDW.ReturnScratchSurface(copy);
                        }
                    }
                    else
                    {
                        PdnRegion previewRegion = (PdnRegion)selectedRegion.Clone();
                        previewRegion.Intersect(RectangleF.Inflate(activeDW.VisibleDocumentRectangleF, 1, 1));

                        Surface originalSurface = activeDW.BorrowScratchSurface(this.GetType() + ".RunEffect() using scratch surface for rendering during configuration");

                        try
                        {
                            using (new WaitCursorChanger(AppWorkspace))
                            {
                                originalSurface.CopySurface(layer.Surface);
                            }

                            //
                            AppWorkspace.SuspendThumbnailUpdates();
                            //

                            using (EffectConfigDialog configDialog = effect.CreateConfigDialog())
                            {
                                configDialog.Opacity = 0.9;
                                configDialog.Effect = effect;
                                configDialog.EffectSourceSurface = originalSurface;
                                configDialog.Selection = selectedRegion;

                                EventHandler eh = new EventHandler(EffectConfigTokenChangedHandler);
                                configDialog.EffectTokenChanged += eh;

                                if (this.effectTokens.ContainsKey(effectType))
                                {
                                    EffectConfigToken oldToken = (EffectConfigToken)effectTokens[effectType].Clone();
                                    configDialog.EffectToken = oldToken;
                                }

                                BackgroundEffectRenderer ber = new BackgroundEffectRenderer(
                                    effect,
                                    configDialog.EffectToken,
                                    new RenderArgs(layer.Surface),
                                    new RenderArgs(originalSurface),
                                    previewRegion,
                                    tilesPerCpu * renderingThreadCount,
                                    renderingThreadCount);

                                ber.RenderedTile += new RenderedTileEventHandler(RenderedTileHandler);
                                ber.StartingRendering += new EventHandler(StartingRenderingHandler);
                                ber.FinishedRendering += new EventHandler(FinishedRenderingHandler);
                                configDialog.Tag = ber;

                                invalidateTimer.Enabled = true;
                                DialogResult dr = Utility.ShowDialog(configDialog, AppWorkspace);
                                invalidateTimer.Enabled = false;

                                this.InvalidateTimer_Tick(invalidateTimer, EventArgs.Empty);

                                if (dr == DialogResult.OK)
                                {
                                    this.effectTokens[effectType] = (EffectConfigToken)configDialog.EffectToken.Clone();
                                }

                                using (new WaitCursorChanger(AppWorkspace))
                                {
                                    ber.Abort();
                                    ber.Join();
                                    ber.Dispose();
                                    ber = null;

                                    if (dr != DialogResult.OK)
                                    {
                                        ((BitmapLayer)activeDW.ActiveLayer).Surface.CopySurface(originalSurface);
                                        activeDW.ActiveLayer.Invalidate();
                                    }

                                    configDialog.EffectTokenChanged -= eh;
                                    configDialog.Hide();
                                    AppWorkspace.Update();
                                    previewRegion.Dispose();
                                }

                                //
                                AppWorkspace.ResumeThumbnailUpdates();
                                //

                                if (dr == DialogResult.OK)
                                {
                                    PdnRegion remainingToRender = selectedRegion.Clone();
                                    PdnRegion alreadyRendered = PdnRegion.CreateEmpty();

                                    for (int i = 0; i < this.progressRegions.Length; ++i)
                                    {
                                        if (this.progressRegions[i] == null)
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            remainingToRender.Exclude(this.progressRegions[i]);
                                            alreadyRendered.Union(this.progressRegions[i]);
                                        }
                                    }

                                    activeDW.ActiveLayer.Invalidate(alreadyRendered);
                                    newLastToken = (EffectConfigToken)configDialog.EffectToken.Clone();
                                    AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar();
                                    DoEffect(effect, newLastToken, selectedRegion, remainingToRender, originalSurface);
                                }
                                else // if (dr == DialogResult.Cancel)
                                {
                                    using (new WaitCursorChanger(AppWorkspace))
                                    {
                                        activeDW.ActiveLayer.Invalidate();
                                        Utility.GCFullCollect();
                                    }

                                    resetDirtyValue = true;
                                    return;
                                }
                            }
                        }

                        finally
                        {
                            activeDW.ReturnScratchSurface(originalSurface);
                        }
                    }

                    // if it was from the Effects menu, save it as the "Repeat ...." item
                    if (effect.Category == EffectCategory.Effect)
                    {
                        this.lastEffect = effect;

                        if (newLastToken == null)
                        {
                            this.lastEffectToken = null;
                        }
                        else
                        {
                            this.lastEffectToken = (EffectConfigToken)newLastToken.Clone();
                        }

                        PopulateMenu(true);
                    }

                }

                finally
                {
                    selectedRegion.Dispose();
                    AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar();
                    AppWorkspace.Widgets.StatusBarProgress.EraseProgressStatusBar();
                    AppWorkspace.ActiveDocumentWorkspace.EnableOutlineAnimation = true;

                    for (int i = 0; i < this.progressRegions.Length; ++i)
                    {
                        if (this.progressRegions[i] != null)
                        {
                            this.progressRegions[i].Dispose();
                            this.progressRegions[i] = null;
                        }
                    }

                    if (resetDirtyValue)
                    {
                        AppWorkspace.ActiveDocumentWorkspace.Document.Dirty = oldDirtyValue;
                    }
                }
            }
        }
        private bool DoEffect(Effect effect, EffectConfigToken token, PdnRegion selectedRegion,
            PdnRegion regionToRender, Surface originalSurface)
        {
            bool oldDirtyValue = AppWorkspace.ActiveDocumentWorkspace.Document.Dirty;
            bool resetDirtyValue = false;

            bool returnVal = false;
            AppWorkspace.ActiveDocumentWorkspace.EnableOutlineAnimation = false;

            try
            {
                using (ProgressDialog aed = new ProgressDialog())
                {
                    if (effect.Image != null)
                    {
                        aed.Icon = Utility.ImageToIcon(effect.Image, Utility.TransparentKey);
                    }

                    aed.Opacity = 0.9;
                    aed.Value = 0;
                    aed.Text = effect.Name;
                    aed.Description = string.Format(PdnResources.GetString("Effects.ApplyingDialog.Description"), effect.Name);

                    invalidateTimer.Enabled = true;

                    using (new WaitCursorChanger(AppWorkspace))
                    {
                        HistoryMemento ha = null;
                        DialogResult result = DialogResult.None;

                        AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar();
                        AppWorkspace.Widgets.LayerControl.SuspendLayerPreviewUpdates();

                        try
                        {
                            ManualResetEvent saveEvent = new ManualResetEvent(false);
                            BitmapHistoryMemento bha = null;

                            // perf bug #1445: save this data in a background thread
                            PdnRegion selectedRegionCopy = selectedRegion.Clone();
                            PaintDotNet.Threading.ThreadPool.Global.QueueUserWorkItem(
                                delegate(object context)
                                {
                                    try
                                    {
                                        ImageResource image;

                                        if (effect.Image == null)
                                        {
                                            image = null;
                                        }
                                        else
                                        {
                                            image = ImageResource.FromImage(effect.Image);
                                        }

                                        bha = new BitmapHistoryMemento(effect.Name, image, this.AppWorkspace.ActiveDocumentWorkspace,
                                            this.AppWorkspace.ActiveDocumentWorkspace.ActiveLayerIndex, selectedRegionCopy, originalSurface);
                                    }

                                    finally
                                    {
                                        saveEvent.Set();
                                        selectedRegionCopy.Dispose();
                                        selectedRegionCopy = null;
                                    }
                                });

                            BackgroundEffectRenderer ber = new BackgroundEffectRenderer(
                                effect,
                                token,
                                new RenderArgs(((BitmapLayer)AppWorkspace.ActiveDocumentWorkspace.ActiveLayer).Surface),
                                new RenderArgs(originalSurface),
                                regionToRender,
                                tilesPerCpu * renderingThreadCount,
                                renderingThreadCount);

                            aed.Tag = ber;
                            ber.RenderedTile += new RenderedTileEventHandler(aed.RenderedTileHandler);
                            ber.RenderedTile += new RenderedTileEventHandler(RenderedTileHandler);
                            ber.StartingRendering += new EventHandler(StartingRenderingHandler);
                            ber.FinishedRendering += new EventHandler(aed.FinishedRenderingHandler);
                            ber.FinishedRendering += new EventHandler(FinishedRenderingHandler);
                            ber.Start();

                            result = Utility.ShowDialog(aed, AppWorkspace);

                            if (result == DialogResult.Cancel)
                            {
                                resetDirtyValue = true;

                                using (new WaitCursorChanger(AppWorkspace))
                                {
                                    ber.Abort();
                                    ber.Join();
                                    ((BitmapLayer)AppWorkspace.ActiveDocumentWorkspace.ActiveLayer).Surface.CopySurface(originalSurface);
                                }
                            }

                            invalidateTimer.Enabled = false;

                            ber.Join();
                            ber.Dispose();

                            saveEvent.WaitOne();
                            saveEvent.Close();
                            saveEvent = null;

                            ha = bha;
                        }

                        catch
                        {
                            using (new WaitCursorChanger(AppWorkspace))
                            {
                                ((BitmapLayer)AppWorkspace.ActiveDocumentWorkspace.ActiveLayer).Surface.CopySurface(originalSurface);
                                ha = null;
                            }
                        }

                        finally
                        {
                            AppWorkspace.Widgets.LayerControl.ResumeLayerPreviewUpdates();
                        }

                        using (PdnRegion simplifiedRenderRegion = Utility.SimplifyAndInflateRegion(selectedRegion))
                        {
                            using (new WaitCursorChanger(AppWorkspace))
                            {
                                AppWorkspace.ActiveDocumentWorkspace.ActiveLayer.Invalidate(simplifiedRenderRegion);
                            }
                        }

                        using (new WaitCursorChanger(AppWorkspace))
                        {
                            if (result == DialogResult.OK)
                            {
                                if (ha != null)
                                {
                                    AppWorkspace.ActiveDocumentWorkspace.History.PushNewMemento(ha);
                                }

                                AppWorkspace.Update();
                                returnVal = true;
                            }
                            else
                            {
                                Utility.GCFullCollect();
                            }
                        }
                    } // using
                } // using
            }

            finally
            {
                AppWorkspace.ActiveDocumentWorkspace.EnableOutlineAnimation = true;

                if (resetDirtyValue)
                {
                    AppWorkspace.ActiveDocumentWorkspace.Document.Dirty = oldDirtyValue;
                }
            }

            AppWorkspace.Widgets.StatusBarProgress.EraseProgressStatusBarAsync();
            return returnVal;
        }
        private void AddEffectToMenu(Effect effect, bool withShortcut)
        {
            if (!FilterEffects(effect))
            {
                return;
            }

            string name = effect.Name;

            if (effect.IsConfigurable)
            {
                string configurableFormat = PdnResources.GetString("Effects.Name.Format.Configurable");
                name = string.Format(configurableFormat, name);
            }

            PdnMenuItem mi = new PdnMenuItem(name, effect.Image, EffectMenuItem_Click);

            if (withShortcut)
            {
                mi.ShortcutKeys = GetEffectShortcutKeys(effect);
            }
            else
            {
                mi.ShortcutKeys = Keys.None;
            }

            mi.Tag = (object)effect.GetType();

            PdnMenuItem addEffectHere = this;

            if (effect.SubMenuName != null)
            {
                PdnMenuItem subMenu = null;

                // search for this subMenu
                foreach (ToolStripItem sub in this.DropDownItems)
                {
                    PdnMenuItem subpmi = sub as PdnMenuItem;

                    if (subpmi != null)
                    {
                        if (subpmi.Text == effect.SubMenuName)
                        {
                            subMenu = subpmi;
                            break;
                        }
                    }
                }

                if (subMenu == null)
                {
                    subMenu = new PdnMenuItem(effect.SubMenuName, null, null);
                    this.DropDownItems.Add(subMenu);
                }

                addEffectHere = subMenu;
            }

            addEffectHere.DropDownItems.Add(mi);
        }
 protected virtual Keys GetEffectShortcutKeys(Effect effect)
 {
     return Keys.None;
 }
 protected abstract bool FilterEffects(Effect effect);
Exemple #13
0
        private void HandleEffectException(AppWorkspace appWorkspace, Effect effect, Exception ex)
        {
            try
            {
                AppWorkspace.Widgets.StatusBarProgress.ResetProgressStatusBar();
                AppWorkspace.Widgets.StatusBarProgress.EraseProgressStatusBar();
            }

            catch (Exception)
            {
            }

            // Figure out if it's a built-in effect, or a plug-in
            bool builtIn = IsBuiltInEffect(effect);

            if (builtIn)
            {
                // For built-in effects, tear down Paint.NET which will result in a crash log
                throw new ApplicationException("Effect threw an exception", ex);
            }
            else
            {
                Icon formIcon = Utility.ImageToIcon(PdnResources.GetImageResource("Icons.BugWarning.png").Reference);

                string formTitle = PdnResources.GetString("Effect.PluginErrorDialog.Title");

                Image taskImage = null;

                string introText = PdnResources.GetString("Effect.PluginErrorDialog.IntroText");

                TaskButton restartTB = new TaskButton(
                    PdnResources.GetImageResource("Icons.RightArrowBlue.png").Reference,
                    PdnResources.GetString("Effect.PluginErrorDialog.RestartTB.ActionText"),
                    PdnResources.GetString("Effect.PluginErrorDialog.RestartTB.ExplanationText"));

                TaskButton doNotRestartTB = new TaskButton(
                    PdnResources.GetImageResource("Icons.WarningIcon.png").Reference,
                    PdnResources.GetString("Effect.PluginErrorDialog.DoNotRestartTB.ActionText"),
                    PdnResources.GetString("Effect.PluginErrorDialog.DoNotRestartTB.ExplanationText"));

                string auxButtonText = PdnResources.GetString("Effect.PluginErrorDialog.AuxButton1.Text");

                EventHandler auxButtonClickHandler =
                    delegate(object sender, EventArgs e)
                    {
                        using (PdnBaseForm textBoxForm = new PdnBaseForm())
                        {
                            textBoxForm.Name = "EffectCrash";

                            TextBox exceptionBox = new TextBox();

                            textBoxForm.Icon = Utility.ImageToIcon(PdnResources.GetImageResource("Icons.WarningIcon.png").Reference);
                            textBoxForm.Text = PdnResources.GetString("Effect.PluginErrorDialog.Title");

                            exceptionBox.Dock = DockStyle.Fill;
                            exceptionBox.ReadOnly = true;
                            exceptionBox.Multiline = true;

                            string exceptionText = AppWorkspace.GetLocalizedEffectErrorMessage(effect.GetType().Assembly, effect.GetType(), ex);

                            exceptionBox.Font = new Font(FontFamily.GenericMonospace, exceptionBox.Font.Size);
                            exceptionBox.Text = exceptionText;
                            exceptionBox.ScrollBars = ScrollBars.Vertical;

                            textBoxForm.StartPosition = FormStartPosition.CenterParent;
                            textBoxForm.ShowInTaskbar = false;
                            textBoxForm.MinimizeBox = false;
                            textBoxForm.Controls.Add(exceptionBox);
                            textBoxForm.Width = UI.ScaleWidth(700);

                            textBoxForm.ShowDialog();
                        }
                    };

                TaskButton clickedTB = TaskDialog.Show(
                    appWorkspace,
                    formIcon,
                    formTitle,
                    taskImage,
                    true,
                    introText,
                    new TaskButton[] { restartTB, doNotRestartTB },
                    restartTB,
                    doNotRestartTB,
                    TaskDialog.DefaultPixelWidth96Dpi * 2,
                    auxButtonText,
                    auxButtonClickHandler);

                if (clickedTB == restartTB)
                {
                    // Next, apply restart logic
                    CloseAllWorkspacesAction cawa = new CloseAllWorkspacesAction();
                    cawa.PerformAction(appWorkspace);

                    if (!cawa.Cancelled)
                    {
                        SystemLayer.Shell.RestartApplication();
                        Startup.CloseApplication();
                    }
                }
            }
        }