Merge lp:~paolorotolo/pinta/fix-for-1093971 into lp:pinta

Proposed by Paolo Rotolo
Status: Needs review
Proposed branch: lp:~paolorotolo/pinta/fix-for-1093971
Merge into: lp:pinta
Diff against target: 167457 lines (+164881/-0) (has conflicts)
428 files modified
Makefile.am (+117/-0)
Makefile.in (+849/-0)
Pinta.Core/.gitignore (+3/-0)
Pinta.Core/Actions/AdjustmentsActions.cs (+57/-0)
Pinta.Core/Actions/EditActions.cs (+433/-0)
Pinta.Core/Actions/EffectsActions.cs (+93/-0)
Pinta.Core/Actions/FileActions.cs (+131/-0)
Pinta.Core/Actions/HelpActions.cs (+93/-0)
Pinta.Core/Actions/ImageActions.cs (+301/-0)
Pinta.Core/Actions/LayerActions.cs (+292/-0)
Pinta.Core/Actions/ViewActions.cs (+276/-0)
Pinta.Core/Actions/WindowActions.cs (+153/-0)
Pinta.Core/Classes/Anchor.cs (+43/-0)
Pinta.Core/Classes/AsyncEffectRenderer.cs (+361/-0)
Pinta.Core/Classes/BaseExtension.cs (+41/-0)
Pinta.Core/Classes/BasePaintBrush.cs (+42/-0)
Pinta.Core/Classes/BaseTool.cs (+276/-0)
Pinta.Core/Classes/Document.cs (+735/-0)
Pinta.Core/Classes/DocumentWorkspace.cs (+273/-0)
Pinta.Core/Classes/DocumentWorkspaceHistory.cs (+172/-0)
Pinta.Core/Classes/GradientRenderer.cs (+229/-0)
Pinta.Core/Classes/GradientRenderers.cs (+204/-0)
Pinta.Core/Classes/IExtension.cs (+15/-0)
Pinta.Core/Classes/IndexEventArgs.cs (+21/-0)
Pinta.Core/Classes/IndexEventHandler.cs (+15/-0)
Pinta.Core/Classes/Layer.cs (+280/-0)
Pinta.Core/Classes/LayerProperties.cs (+53/-0)
Pinta.Core/Classes/ObservableObject.cs (+53/-0)
Pinta.Core/Classes/Palette.cs (+236/-0)
Pinta.Core/Classes/ScaleFactor.cs (+377/-0)
Pinta.Core/Effects/BaseEffect.cs (+199/-0)
Pinta.Core/Effects/BinaryPixelOp.cs (+152/-0)
Pinta.Core/Effects/BitVector2DSurfaceAdapter.cs (+207/-0)
Pinta.Core/Effects/ColorBgra.cs (+702/-0)
Pinta.Core/Effects/ColorDifferenceEffect.cs (+101/-0)
Pinta.Core/Effects/ColorTransferMode.cs (+17/-0)
Pinta.Core/Effects/Histogram.cs (+220/-0)
Pinta.Core/Effects/HistogramRGB.cs (+136/-0)
Pinta.Core/Effects/HsvColor.cs (+189/-0)
Pinta.Core/Effects/IBitVector2D.cs (+57/-0)
Pinta.Core/Effects/ISurfaceDraw.cs (+50/-0)
Pinta.Core/Effects/IrregularSurface.cs (+206/-0)
Pinta.Core/Effects/LocalHistogramEffect.cs (+535/-0)
Pinta.Core/Effects/PixelOp.cs (+113/-0)
Pinta.Core/Effects/PlacedSurface.cs (+175/-0)
Pinta.Core/Effects/RgbColor.cs (+132/-0)
Pinta.Core/Effects/Scanline.cs (+86/-0)
Pinta.Core/Effects/SplineInterpolator.cs (+119/-0)
Pinta.Core/Effects/UnaryPixelOp.cs (+107/-0)
Pinta.Core/Effects/UnaryPixelOps.cs (+965/-0)
Pinta.Core/Effects/UserBlendOp.cs (+34/-0)
Pinta.Core/Effects/UserBlendOps.Generated.cs (+368/-0)
Pinta.Core/Effects/UserBlendOps.cs (+74/-0)
Pinta.Core/Effects/Utility.cs (+710/-0)
Pinta.Core/Enumerations/EffectAdjustment.cs (+36/-0)
Pinta.Core/Enumerations/GradientColorMode.cs (+36/-0)
Pinta.Core/EventArgs/CanvasInvalidatedEventArgs.cs (+48/-0)
Pinta.Core/EventArgs/DocumentCancelEventArgs.cs (+43/-0)
Pinta.Core/EventArgs/DocumentEventArgs.cs (+40/-0)
Pinta.Core/EventArgs/HistoryItemAddedEventArgs.cs (+40/-0)
Pinta.Core/EventArgs/HistoryItemRemovedEventArgs.cs (+39/-0)
Pinta.Core/EventArgs/LivePreviewEndedEventArgs.cs (+49/-0)
Pinta.Core/EventArgs/LivePreviewRenderUpdatedEventArgs.cs (+43/-0)
Pinta.Core/EventArgs/LivePreviewStartedEventArgs.cs (+37/-0)
Pinta.Core/EventArgs/ModifyCompressionEventArgs.cs (+42/-0)
Pinta.Core/EventArgs/TextChangedEventArgs.cs (+40/-0)
Pinta.Core/EventArgs/ToolEventArgs.cs (+41/-0)
Pinta.Core/Extensions/CairoExtensions.cs (+1410/-0)
Pinta.Core/Extensions/GdkExtensions.cs (+106/-0)
Pinta.Core/Extensions/GtkExtensions.cs (+193/-0)
Pinta.Core/Extensions/OtherExtensions.cs (+109/-0)
Pinta.Core/Extensions/ToolBarButton.cs (+45/-0)
Pinta.Core/Extensions/ToolBarComboBox.cs (+69/-0)
Pinta.Core/Extensions/ToolBarFontComboBox.cs (+65/-0)
Pinta.Core/Extensions/ToolBarImage.cs (+43/-0)
Pinta.Core/Extensions/ToolBarLabel.cs (+48/-0)
Pinta.Core/Extensions/ToolBarSlider.cs (+51/-0)
Pinta.Core/Extensions/ToolBarToggleButton.cs (+45/-0)
Pinta.Core/HistoryItems/AddLayerHistoryItem.cs (+65/-0)
Pinta.Core/HistoryItems/BaseHistoryItem.cs (+74/-0)
Pinta.Core/HistoryItems/ClippedSurfaceHistoryItem.cs (+82/-0)
Pinta.Core/HistoryItems/CompoundHistoryItem.cs (+75/-0)
Pinta.Core/HistoryItems/DeleteLayerHistoryItem.cs (+66/-0)
Pinta.Core/HistoryItems/FinishPixelsHistoryItem.cs (+98/-0)
Pinta.Core/HistoryItems/InvertHistoryItem.cs (+165/-0)
Pinta.Core/HistoryItems/MovePixelsHistoryItem.cs (+112/-0)
Pinta.Core/HistoryItems/PasteHistoryItem.cs (+103/-0)
Pinta.Core/HistoryItems/ResizeHistoryItem.cs (+110/-0)
Pinta.Core/HistoryItems/SelectionHistoryItem.cs (+79/-0)
Pinta.Core/HistoryItems/SimpleHistoryItem.cs (+89/-0)
Pinta.Core/HistoryItems/SwapLayersHistoryItem.cs (+73/-0)
Pinta.Core/HistoryItems/UpdateLayerPropertiesHistoryItem.cs (+70/-0)
Pinta.Core/ImageFormats/FormatDescriptor.cs (+82/-0)
Pinta.Core/ImageFormats/GdkPixbufFormat.cs (+86/-0)
Pinta.Core/ImageFormats/IImageExporter.cs (+35/-0)
Pinta.Core/ImageFormats/IImageImporter.cs (+35/-0)
Pinta.Core/ImageFormats/JpegFormat.cs (+49/-0)
Pinta.Core/ImageFormats/OraFormat.cs (+208/-0)
Pinta.Core/ImageFormats/TgaExporter.cs (+118/-0)
Pinta.Core/Makefile.am (+125/-0)
Pinta.Core/Managers/ActionManager.cs (+161/-0)
Pinta.Core/Managers/ChromeManager.cs (+148/-0)
Pinta.Core/Managers/EffectsManager.cs (+141/-0)
Pinta.Core/Managers/FontManager.cs (+87/-0)
Pinta.Core/Managers/HistoryManager.cs (+103/-0)
Pinta.Core/Managers/ImageConverterManager.cs (+159/-0)
Pinta.Core/Managers/LayerManager.cs (+267/-0)
Pinta.Core/Managers/LivePreviewManager.cs (+388/-0)
Pinta.Core/Managers/PaintBrushManager.cs (+68/-0)
Pinta.Core/Managers/PaletteManager.cs (+93/-0)
Pinta.Core/Managers/ResourceManager.cs (+44/-0)
Pinta.Core/Managers/SettingsManager.cs (+152/-0)
Pinta.Core/Managers/SystemManager.cs (+138/-0)
Pinta.Core/Managers/ToolManager.cs (+197/-0)
Pinta.Core/Managers/WorkspaceManager.cs (+317/-0)
Pinta.Core/Pinta.Core.csproj (+227/-0)
Pinta.Core/PintaCore.cs (+71/-0)
Pinta.Core/Properties/AssemblyInfo.cs (+26/-0)
Pinta.Core/Widgets/MenuButton.cs (+188/-0)
Pinta.Core/Widgets/ToolBarDropDownButton.cs (+100/-0)
Pinta.Effects/.gitignore (+4/-0)
Pinta.Effects/Adjustments/AutoLevelEffect.cs (+45/-0)
Pinta.Effects/Adjustments/BlackAndWhiteEffect.cs (+37/-0)
Pinta.Effects/Adjustments/BrightnessContrastEffect.cs (+178/-0)
Pinta.Effects/Adjustments/CurvesEffect.cs (+137/-0)
Pinta.Effects/Adjustments/HueSaturationEffect.cs (+81/-0)
Pinta.Effects/Adjustments/InvertColorsEffect.cs (+37/-0)
Pinta.Effects/Adjustments/LevelsEffect.cs (+78/-0)
Pinta.Effects/Adjustments/PosterizeEffect.cs (+72/-0)
Pinta.Effects/Adjustments/SepiaEffect.cs (+50/-0)
Pinta.Effects/CoreEffectsExtension.cs (+62/-0)
Pinta.Effects/Dialogs/Effects.CurvesDialog.cs (+408/-0)
Pinta.Effects/Dialogs/Effects.LevelsDialog.cs (+526/-0)
Pinta.Effects/Dialogs/Effects.PosterizeDialog.cs (+84/-0)
Pinta.Effects/Effects/AddNoiseEffect.cs (+182/-0)
Pinta.Effects/Effects/BulgeEffect.cs (+113/-0)
Pinta.Effects/Effects/CloudsEffect.cs (+224/-0)
Pinta.Effects/Effects/EdgeDetectEffect.cs (+90/-0)
Pinta.Effects/Effects/EmbossEffect.cs (+146/-0)
Pinta.Effects/Effects/FragmentEffect.cs (+121/-0)
Pinta.Effects/Effects/FrostedGlassEffect.cs (+165/-0)
Pinta.Effects/Effects/GaussianBlurEffect.cs (+269/-0)
Pinta.Effects/Effects/GlowEffect.cs (+88/-0)
Pinta.Effects/Effects/InkSketchEffect.cs (+172/-0)
Pinta.Effects/Effects/JuliaFractalEffect.cs (+143/-0)
Pinta.Effects/Effects/LocalHistogramEffect.cs (+545/-0)
Pinta.Effects/Effects/MandelbrotFractalEffect.cs (+173/-0)
Pinta.Effects/Effects/MedianEffect.cs (+80/-0)
Pinta.Effects/Effects/MotionBlurEffect.cs (+122/-0)
Pinta.Effects/Effects/OilPaintingEffect.cs (+183/-0)
Pinta.Effects/Effects/OutlineEffect.cs (+152/-0)
Pinta.Effects/Effects/PencilSketchEffect.cs (+106/-0)
Pinta.Effects/Effects/PixelateEffect.cs (+122/-0)
Pinta.Effects/Effects/PolarInversionEffect.cs (+72/-0)
Pinta.Effects/Effects/RadialBlurEffect.cs (+170/-0)
Pinta.Effects/Effects/RedEyeRemoveEffect.cs (+82/-0)
Pinta.Effects/Effects/ReduceNoiseEffect.cs (+101/-0)
Pinta.Effects/Effects/ReliefEffect.cs (+90/-0)
Pinta.Effects/Effects/SharpenEffect.cs (+67/-0)
Pinta.Effects/Effects/SoftenPortraitEffect.cs (+128/-0)
Pinta.Effects/Effects/TileEffect.cs (+146/-0)
Pinta.Effects/Effects/TwistEffect.cs (+137/-0)
Pinta.Effects/Effects/UnfocusEffect.cs (+105/-0)
Pinta.Effects/Effects/WarpEffect.cs (+191/-0)
Pinta.Effects/Effects/ZoomBlurEffect.cs (+140/-0)
Pinta.Effects/Makefile.am (+70/-0)
Pinta.Effects/Pinta.Effects.csproj (+167/-0)
Pinta.Effects/Properties/AssemblyInfo.cs (+42/-0)
Pinta.Effects/Utilities/EffectHelper.cs (+66/-0)
Pinta.Effects/gtk-gui/Pinta.Effects.CurvesDialog.cs (+234/-0)
Pinta.Effects/gtk-gui/Pinta.Effects.LevelsDialog.cs (+566/-0)
Pinta.Effects/gtk-gui/Pinta.Effects.PosterizeDialog.cs (+141/-0)
Pinta.Effects/gtk-gui/generated.cs (+29/-0)
Pinta.Effects/gtk-gui/gui.stetic (+1069/-0)
Pinta.Gui.Widgets/.gitignore (+3/-0)
Pinta.Gui.Widgets/DialogAttributes.cs (+101/-0)
Pinta.Gui.Widgets/Dialogs/SimpleEffectDialog.cs (+426/-0)
Pinta.Gui.Widgets/Makefile.am (+49/-0)
Pinta.Gui.Widgets/Pinta.Gui.Widgets.csproj (+134/-0)
Pinta.Gui.Widgets/Properties/AssemblyInfo.cs (+51/-0)
Pinta.Gui.Widgets/Widgets/AnglePickerGraphic.cs (+179/-0)
Pinta.Gui.Widgets/Widgets/AnglePickerWidget.cs (+90/-0)
Pinta.Gui.Widgets/Widgets/Canvas/CanvasRenderer.cs (+306/-0)
Pinta.Gui.Widgets/Widgets/Canvas/GridRenderer.cs (+86/-0)
Pinta.Gui.Widgets/Widgets/Canvas/PintaCanvas.cs (+263/-0)
Pinta.Gui.Widgets/Widgets/ColorGradientWidget.cs (+293/-0)
Pinta.Gui.Widgets/Widgets/ColorPaletteWidget.cs (+197/-0)
Pinta.Gui.Widgets/Widgets/ColorPanelWidget.cs (+65/-0)
Pinta.Gui.Widgets/Widgets/ComboBoxWidget.cs (+72/-0)
Pinta.Gui.Widgets/Widgets/HScaleSpinButtonWidget.cs (+164/-0)
Pinta.Gui.Widgets/Widgets/HistogramWidget.cs (+176/-0)
Pinta.Gui.Widgets/Widgets/History/HistoryTreeView.cs (+134/-0)
Pinta.Gui.Widgets/Widgets/Layers/CellRendererSurface.cs (+132/-0)
Pinta.Gui.Widgets/Widgets/Layers/LayersListWidget.cs (+224/-0)
Pinta.Gui.Widgets/Widgets/OpenImages/OpenImagesListWidget.cs (+195/-0)
Pinta.Gui.Widgets/Widgets/PointPickerGraphic.cs (+193/-0)
Pinta.Gui.Widgets/Widgets/PointPickerWidget.cs (+147/-0)
Pinta.Gui.Widgets/Widgets/ReseedButtonWidget.cs (+56/-0)
Pinta.Gui.Widgets/Widgets/ToolBoxWidget.cs (+59/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.AnglePickerWidget.cs (+140/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.ColorGradientWidget.cs (+29/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.ColorPanelWidget.cs (+28/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.ComboBoxWidget.cs (+74/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.HScaleSpinButtonWidget.cs (+130/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.HistogramWidget.cs (+19/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.PointPickerWidget.cs (+206/-0)
Pinta.Gui.Widgets/gtk-gui/Pinta.Gui.Widgets.ReseedButtonWidget.cs (+89/-0)
Pinta.Gui.Widgets/gtk-gui/generated.cs (+115/-0)
Pinta.Gui.Widgets/gtk-gui/gui.stetic (+654/-0)
Pinta.Install.proj (+234/-0)
Pinta.Resources/.gitignore (+2/-0)
Pinta.Resources/Makefile.am (+166/-0)
Pinta.Resources/Pinta.Resources.csproj (+547/-0)
Pinta.Resources/Properties/AssemblyInfo.cs (+26/-0)
Pinta.Resources/ResourceManager.cs (+44/-0)
Pinta.Tools/.gitignore (+4/-0)
Pinta.Tools/Brushes/CircleBrush.cs (+64/-0)
Pinta.Tools/Brushes/GridBrush.cs (+64/-0)
Pinta.Tools/Brushes/PaintBrush.cs (+86/-0)
Pinta.Tools/Brushes/PlainBrush.cs (+65/-0)
Pinta.Tools/Brushes/SplatterBrush.cs (+86/-0)
Pinta.Tools/Brushes/SquaresBrush.cs (+60/-0)
Pinta.Tools/CoreToolsExtension.cs (+50/-0)
Pinta.Tools/Makefile.am (+55/-0)
Pinta.Tools/Pinta.Tools.csproj (+149/-0)
Pinta.Tools/Properties/AssemblyInfo.cs (+42/-0)
Pinta.Tools/Tools/BaseBrushTool.cs (+165/-0)
Pinta.Tools/Tools/CloneStampTool.cs (+160/-0)
Pinta.Tools/Tools/ColorPickerTool.cs (+130/-0)
Pinta.Tools/Tools/EllipseSelectTool.cs (+61/-0)
Pinta.Tools/Tools/EllipseTool.cs (+82/-0)
Pinta.Tools/Tools/EraserTool.cs (+107/-0)
Pinta.Tools/Tools/FloodTool.cs (+362/-0)
Pinta.Tools/Tools/FreeformShapeTool.cs (+228/-0)
Pinta.Tools/Tools/GradientTool.cs (+221/-0)
Pinta.Tools/Tools/LassoSelectTool.cs (+125/-0)
Pinta.Tools/Tools/LineCurveTool.cs (+90/-0)
Pinta.Tools/Tools/MagicWandTool.cs (+133/-0)
Pinta.Tools/Tools/MoveSelectedTool.cs (+152/-0)
Pinta.Tools/Tools/MoveSelectionTool.cs (+107/-0)
Pinta.Tools/Tools/PaintBrushTool.cs (+165/-0)
Pinta.Tools/Tools/PaintBucketTool.cs (+104/-0)
Pinta.Tools/Tools/PanTool.cs (+84/-0)
Pinta.Tools/Tools/PencilTool.cs (+174/-0)
Pinta.Tools/Tools/RecolorTool.cs (+226/-0)
Pinta.Tools/Tools/RectangleSelectTool.cs (+62/-0)
Pinta.Tools/Tools/RectangleTool.cs (+76/-0)
Pinta.Tools/Tools/RoundedRectangleTool.cs (+148/-0)
Pinta.Tools/Tools/SelectTool.cs (+314/-0)
Pinta.Tools/Tools/ShapeTool.cs (+276/-0)
Pinta.Tools/Tools/TextTool/EditingMode.cs (+20/-0)
Pinta.Tools/Tools/TextTool/Position.cs (+35/-0)
Pinta.Tools/Tools/TextTool/TextAlignment.cs (+20/-0)
Pinta.Tools/Tools/TextTool/TextEngine.cs (+442/-0)
Pinta.Tools/Tools/TextTool/TextTool.cs (+719/-0)
Pinta.Tools/Tools/ToolControl/ToolControl.cs (+71/-0)
Pinta.Tools/Tools/ZoomTool.cs (+191/-0)
Pinta.sln (+75/-0)
Pinta/.gitignore (+4/-0)
Pinta/Actions/Edit/PasteIntoNewImageAction.cs (+81/-0)
Pinta/Actions/Edit/PasteIntoNewLayerAction.cs (+91/-0)
Pinta/Actions/Edit/ResizePaletteAction.cs (+61/-0)
Pinta/Actions/File/CloseDocumentAction.cs (+91/-0)
Pinta/Actions/File/ExitAction.cs (+67/-0)
Pinta/Actions/File/ModifyCompressionAction.cs (+62/-0)
Pinta/Actions/File/NewDocumentAction.cs (+75/-0)
Pinta/Actions/File/NewScreenshotAction.cs (+88/-0)
Pinta/Actions/File/OpenDocumentAction.cs (+85/-0)
Pinta/Actions/File/OpenRecentAction.cs (+55/-0)
Pinta/Actions/File/SaveDocumentAction.cs (+51/-0)
Pinta/Actions/File/SaveDocumentAsAction.cs (+51/-0)
Pinta/Actions/File/SaveDocumentImplementationAction.cs (+246/-0)
Pinta/Actions/Help/AboutDialogAction.cs (+60/-0)
Pinta/Actions/Help/ExtensionManagerAction.cs (+58/-0)
Pinta/Actions/IActionHandler.cs (+13/-0)
Pinta/Actions/Image/ResizeCanvasAction.cs (+62/-0)
Pinta/Actions/Image/ResizeImageAction.cs (+62/-0)
Pinta/Actions/Layers/LayerPropertiesAction.cs (+112/-0)
Pinta/Actions/Layers/RotateZoomLayerAction.cs (+90/-0)
Pinta/Actions/View/ToolBarToggledAction.cs (+52/-0)
Pinta/Actions/Window/CloseAllDocumentsAction.cs (+60/-0)
Pinta/Actions/Window/SaveAllDocumentsAction.cs (+60/-0)
Pinta/DialogHandlers.cs (+172/-0)
Pinta/Dialogs/AboutDialog.cs (+312/-0)
Pinta/Dialogs/AboutPintaTabPage.cs (+65/-0)
Pinta/Dialogs/ErrorDialog.cs (+205/-0)
Pinta/Dialogs/JpegCompressionDialog.cs (+64/-0)
Pinta/Dialogs/LayerPropertiesDialog.cs (+126/-0)
Pinta/Dialogs/NewImageDialog.cs (+58/-0)
Pinta/Dialogs/ProgressDialog.cs (+79/-0)
Pinta/Dialogs/ResizeCanvasDialog.cs (+279/-0)
Pinta/Dialogs/ResizeImageDialog.cs (+128/-0)
Pinta/Dialogs/SpinButtonEntryDialog.cs (+64/-0)
Pinta/Dialogs/VersionInformationTabPage.cs (+94/-0)
Pinta/DockLibrary/AutoHideBox.cs (+403/-0)
Pinta/DockLibrary/DockBar.cs (+176/-0)
Pinta/DockLibrary/DockBarItem.cs (+397/-0)
Pinta/DockLibrary/DockContainer.cs (+451/-0)
Pinta/DockLibrary/DockFrame.cs (+700/-0)
Pinta/DockLibrary/DockFrameTopLevel.cs (+61/-0)
Pinta/DockLibrary/DockGroup.cs (+1138/-0)
Pinta/DockLibrary/DockGroupItem.cs (+418/-0)
Pinta/DockLibrary/DockGroupType.cs (+41/-0)
Pinta/DockLibrary/DockItem.cs (+518/-0)
Pinta/DockLibrary/DockItemBehavior.cs (+48/-0)
Pinta/DockLibrary/DockItemContainer.cs (+424/-0)
Pinta/DockLibrary/DockItemStatus.cs (+42/-0)
Pinta/DockLibrary/DockItemToolbar.cs (+181/-0)
Pinta/DockLibrary/DockLayout.cs (+107/-0)
Pinta/DockLibrary/DockObject.cs (+284/-0)
Pinta/DockLibrary/DockPosition.cs (+45/-0)
Pinta/DockLibrary/HslColor.cs (+158/-0)
Pinta/DockLibrary/PlaceholderWindow.cs (+143/-0)
Pinta/DockLibrary/ShadedContainer.cs (+351/-0)
Pinta/DockLibrary/TabStrip.cs (+407/-0)
Pinta/ExtensionPoints.cs (+45/-0)
Pinta/Extensions/GtkExtensions.cs (+62/-0)
Pinta/IgeMacMenu.cs (+94/-0)
Pinta/Main.cs (+132/-0)
Pinta/MainWindow.cs (+382/-0)
Pinta/Makefile.am (+74/-0)
Pinta/Options.cs (+1101/-0)
Pinta/Pads/CanvasPad.cs (+175/-0)
Pinta/Pads/ColorPalettePad.cs (+57/-0)
Pinta/Pads/HistoryPad.cs (+57/-0)
Pinta/Pads/IDockPad.cs (+11/-0)
Pinta/Pads/LayersPad.cs (+63/-0)
Pinta/Pads/OpenImagesPad.cs (+59/-0)
Pinta/Pads/ToolBoxPad.cs (+55/-0)
Pinta/Pinta.csproj (+213/-0)
Pinta/Properties/AssemblyInfo.cs (+26/-0)
Pinta/WindowShell.cs (+102/-0)
Pinta/gtk-gui/Pinta.LayerPropertiesDialog.cs (+170/-0)
Pinta/gtk-gui/Pinta.NewImageDialog.cs (+208/-0)
Pinta/gtk-gui/Pinta.ProgressDialog.cs (+74/-0)
Pinta/gtk-gui/Pinta.ResizeCanvasDialog.cs (+588/-0)
Pinta/gtk-gui/Pinta.ResizeImageDialog.cs (+267/-0)
Pinta/gtk-gui/generated.cs (+115/-0)
Pinta/gtk-gui/gui.stetic (+1467/-0)
Pinta/pinta.in (+3/-0)
aclocal.m4 (+1788/-0)
configure (+7423/-0)
configure.ac (+68/-0)
debian/changelog (+186/-0)
debian/compat (+1/-0)
debian/control (+32/-0)
debian/copyright (+566/-0)
debian/rules (+10/-0)
debian/source/format (+1/-0)
debian/watch (+4/-0)
install-sh (+520/-0)
license-mit.txt (+21/-0)
license-pdn.txt (+20/-0)
missing (+376/-0)
pinta.in (+2/-0)
pinta.pc.in (+9/-0)
po/Makefile (+217/-0)
po/Makefile.in (+217/-0)
po/Makefile.in.in (+217/-0)
po/POTFILES (+1/-0)
po/POTFILES.in (+1/-0)
po/af.po (+1635/-0)
po/ar.po (+1671/-0)
po/bg.po (+1662/-0)
po/br.po (+1678/-0)
po/bs.po (+1667/-0)
po/ca.po (+1642/-0)
po/cs.po (+1665/-0)
po/da.po (+1676/-0)
po/de.po (+1697/-0)
po/el.po (+1668/-0)
po/en_AU.po (+1667/-0)
po/en_CA.po (+1667/-0)
po/en_GB.po (+1675/-0)
po/eo.po (+1671/-0)
po/es.po (+1684/-0)
po/et.po (+1635/-0)
po/eu.po (+1681/-0)
po/fi.po (+1671/-0)
po/fil.po (+1636/-0)
po/fo.po (+1650/-0)
po/fr.po (+1693/-0)
po/ga.po (+1639/-0)
po/gl.po (+1686/-0)
po/he.po (+1664/-0)
po/hi.po (+1634/-0)
po/hr.po (+1670/-0)
po/hu.po (+1673/-0)
po/hy.po (+1635/-0)
po/id.po (+1674/-0)
po/it.po (+1699/-0)
po/ja.po (+1641/-0)
po/ko.po (+1639/-0)
po/la.po (+1635/-0)
po/lt.po (+1655/-0)
po/lv.po (+1671/-0)
po/messages.in (+173/-0)
po/messages.pot (+1628/-0)
po/ms.po (+1673/-0)
po/nb.po (+1677/-0)
po/nl.po (+1676/-0)
po/nn.po (+1659/-0)
po/oc.po (+1635/-0)
po/pl.po (+1703/-0)
po/pt.po (+1685/-0)
po/pt_BR.po (+1693/-0)
po/ro.po (+1679/-0)
po/ru.po (+1692/-0)
po/sk.po (+1668/-0)
po/sl.po (+1669/-0)
po/sq.po (+1635/-0)
po/sr.po (+1667/-0)
po/sv.po (+1676/-0)
po/th.po (+1637/-0)
po/tr.po (+1675/-0)
po/uk.po (+1674/-0)
po/vi.po (+1638/-0)
po/zh_CN.po (+1638/-0)
po/zh_TW.po (+1638/-0)
readme.md (+76/-0)
todo.txt (+7/-0)
xdg/Makefile (+467/-0)
xdg/Makefile.am (+15/-0)
xdg/Makefile.in (+467/-0)
xdg/pinta.1 (+29/-0)
xdg/pinta.desktop.in (+12/-0)
xdg/pinta.xpm (+286/-0)
xdg/scalable/pinta.svg (+546/-0)
Conflict adding file Makefile.am.  Moved existing file to Makefile.am.moved.
Conflict adding file Pinta.Core.  Moved existing file to Pinta.Core.moved.
Conflict adding file Pinta.Effects.  Moved existing file to Pinta.Effects.moved.
Conflict adding file Pinta.Gui.Widgets.  Moved existing file to Pinta.Gui.Widgets.moved.
Conflict adding file Pinta.Install.proj.  Moved existing file to Pinta.Install.proj.moved.
Conflict adding file Pinta.Resources.  Moved existing file to Pinta.Resources.moved.
Conflict adding file Pinta.Tools.  Moved existing file to Pinta.Tools.moved.
Conflict adding file Pinta.  Moved existing file to Pinta.moved.
Conflict adding file Pinta.sln.  Moved existing file to Pinta.sln.moved.
Conflict adding file configure.ac.  Moved existing file to configure.ac.moved.
Conflict adding file license-mit.txt.  Moved existing file to license-mit.txt.moved.
Conflict adding file license-pdn.txt.  Moved existing file to license-pdn.txt.moved.
Conflict adding file pinta.in.  Moved existing file to pinta.in.moved.
Conflict adding file pinta.pc.in.  Moved existing file to pinta.pc.in.moved.
Conflict adding file po.  Moved existing file to po.moved.
Conflict adding file readme.md.  Moved existing file to readme.md.moved.
Conflict adding file xdg.  Moved existing file to xdg.moved.
To merge this branch: bzr merge lp:~paolorotolo/pinta/fix-for-1093971
Reviewer Review Type Date Requested Status
Pinta Maintainers Pending
Review via email: mp+144515@code.launchpad.net

Description of the change

Add gnome-icon-theme-full to depends (LP: #1093971)

To post a comment you must log in.
Revision history for this message
Cameron White (cameronwhite91) wrote :

I'm not sure this is right place to merge these changes. This repository is just a mirror of Pinta's Github repository, and is only used for the daily builds PPA. Based on Marc's comment on the bug report, I think you should be proposing this change to the raring branch of lp:ubuntu/pinta

Unmerged revisions

14. By Paolo Rotolo

* Add gnome-icon-theme-full to depends (LP: #1093971)

13. By Iain Lane

* [2c6b414] Imported Upstream version 1.2
  - Individual layers can now be rotated arbitrarily
  - Added specific mouse cursors for tools (pencil, paintbucket, etc)
  - Autocrop of image
  - Gradient tool now takes advantage of multiple cores to speed up
    rendering time
  - Added image preview to the images pad
  - Added white text background option
  - Show image previews in the Open File dialog
* [7e1f9e8] Update BDs to require Mono 2.8 per upstream

12. By Jo Shields

* [236a231] Update debian/rules for DH8-compatible "--with cli"
* [51033d9] Fix typo in clean override rule
* [87189a7] Add a get-out so "make cleanall" doesn't fail the build on a
  pristine tree

11. By Iain Lane

* [a2af0ce] Imported Upstream version 1.1
* [6b57160] Wrap too-long changelog line — silence, Lintian!
* [1e6d30f] Update copyright to newer DEP5ness
* [3879389] Update watch file for new upstream download location
* Remove upstreamed patches
  + [16a2b1b] remove-targetversion patch
  + [0114794] unversion-lib-references
* Add new build dependencies required by this release
  + [1cc97d9] mono-addins
  + [b698368] intltool
* [b698368] Remove references to other programs in long description
* [bd76c1d] BD on intltool for required by upstream

10. By Iain Lane

[92d659c] Depend on gnome-icon-theme since Pinta will crash without the icons
(LP: #846396)

9. By Jo Shields

No change rebuild against Mono's CLR 4.0 class library

8. By Iain Lane

* Upload to unstable
* [1b878e8] Update to use my d.o email address
* [22d952c] Alter BDs and patches so we can build against both 2.0 and 4.0

7. By Rico Tzschichholz

New upstream release version 0.7

6. By Maia Everett

* Add myself to uploaders.
* Add cairo_1.9_flush_markdirty.patch:
  - Fix rendering with Cairo 1.9 (Closes: #588886)
* Add tools_exceptions_and_history_corruption.patch:
  - Fix exceptions and data loss when clicking two mouse buttons
    while drawing
* Add double_save_exception.patch:
  - Fix exception when trying to save after doing "save as"
* Add tool_toolbar_fixed_size.patch:
  - Force tool toolbar to fixed size
* Bump Standards-Version to 3.9.1, no changes needed.

5. By Jo Shields

[ Jo Shields ]
* New upstream release
* +DFSG release of Pinta 0.4. Deleted files:
  + ./Pinta.Gui.Widgets/bin/Debug/Pinta.Gui.Widgets.dll
* debian/rules:
  + Switch to entirely minimal DH7 rules file, since the Automake
    wrapper for xbuild handles things we were having to do by hand
* debian/pinta.sh,
  debian/pinta.desktop,
  debian/pinta.xpm,
  debian/pinta.install:
  + Upstream now takes care of providing an icon and a .desktop file,
    and DH7 takes care of putting everything where it should be, so
    all these files have been deleted
* debian/copyright:
  + Updated (thanks to Maia Kozheva <email address hidden>)

[ Iain Lane ]
* [a8be0d2] Remove BD on libglade2.0-cil-dev; no longer necessary
* [41bfc27] debian/watch: Mangle version for +dfsg
* [9c1ad07] Standards-Version → 3.9.0, no changes required
* [0232079] Work around buggy upstream make clean target, fixing
  double build

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'Makefile.am'
--- Makefile.am 1970-01-01 00:00:00 +0000
+++ Makefile.am 2013-01-23 15:01:21 +0000
@@ -0,0 +1,117 @@
1SUBDIRS = xdg
2
3BINDIR = $(srcdir)/bin
4
5PINTA_ASSEMBLY_PC = $(srcdir)/$(PACKAGE_NAME).pc
6
7BINFILES = \
8 $(BINDIR)/Pinta.exe \
9 $(BINDIR)/Pinta.Core.dll \
10 $(BINDIR)/Pinta.Gui.Widgets.dll \
11 $(BINDIR)/Pinta.Resources.dll \
12 $(BINDIR)/Pinta.Effects.dll \
13 $(BINDIR)/Pinta.Tools.dll
14
15RELEASE_FILE = $(PACKAGE)-$(VERSION)
16
17#magic automake variables
18
19pkgconfigdir = $(libdir)/pkgconfig
20pkgconfig_DATA = $(PINTA_ASSEMBLY_PC)
21
22#end
23
24# target: all - Default target: build
25all: build
26
27# target: run - Launch the uninstalled copy
28run:
29 $(MONO) bin/Pinta.exe
30
31# target: help - Display callable targets.
32help:
33 egrep "^# target:" Makefile | sed 's/^# target:/make/'
34
35# target: build - Build Pinta.
36build: Pinta.sln
37 cd $(srcdir) && $(XBUILD) Pinta.sln
38 cd $(srcdir) && $(XBUILD) Pinta.Install.proj /target:CompileTranslations
39
40# target: list - List source files.
41list:
42 if ! git status > /dev/null 2> /dev/null ;\
43 then \
44 find . -type f -name *.cs | sed 's|./||' ;\
45 else \
46 git ls-files | grep '\.cs' ;\
47 fi
48
49#target: updatepot - update the messages.pot file
50updatepot: build
51 find . -type f -name *.cs | sed 's|./||' > files.list
52 grep -v System.ComponentModel.Composition files.list > files2.list
53 xgettext --from-code=UTF-8 -f files2.list -o po/messages.pot
54 cat po/messages.in >> po/messages.pot
55 rm files.list
56 rm files2.list
57
58# target: clean - Default clean command: cleanobj and cleanbin
59clean: cleanobj cleanbin
60
61# target: distclean - Removes configure files.
62distclean: clean
63 rm -f Makefile pinta config.status config.cache config.log configure.lineno config.status.lineno pinta.pc
64
65# target: cleanall - Removes build files.
66cleanall: distclean
67 rm -rf autom4te.cache
68 rm -f configure aclocal.m4 missing install-sh Makefile.in
69
70# target: cleanbin - Removes built files.
71cleanbin:
72 rm -rvf $(BINDIR)/*
73
74# target: cleanobj - Removes temporary build files.
75cleanobj:
76 find $(srcdir)/ -type d -name obj | xargs rm -rvf
77
78# target: install - Installs Pinta.
79install: pinta $(BINFILES)
80 cd $(srcdir) && $(XBUILD) /target:Install /property:InstallPrefix=$(DESTDIR)$(prefix) \
81 /property:BinDir=$(DESTDIR)$(bindir) /property:LibDir=$(DESTDIR)$(libdir) \
82 /property:DataRootDir=$(DESTDIR)$(datarootdir) /property:ManDir=$(DESTDIR)$(mandir) \
83 /property:LocaleDir=$(DESTDIR)$(localedir) Pinta.Install.proj
84 $(INSTALL_SCRIPT) pinta $(DESTDIR)$(bindir)/$(PACKAGE)
85
86# target: uninstall - Uninstalls Pinta.
87uninstall:
88 $(XBUILD) /target:Uninstall /property:InstallPrefix=$(DESTDIR)$(prefix) Pinta.Install.proj
89
90# target: release - Default release type: releasetar
91release: releasetar
92
93# target: releasetar - Make a release tarball.
94releasetar: $(BINFILES)
95 cd $(BINDIR) && tar -czf ../$(RELEASE_FILE).tgz --exclude=*mdb *
96
97# target: releasezip - Make a release zip file.
98releasezip: $(BINFILES)
99 cd $(BINDIR) && zip -r ../$(RELEASE_FILE).zip * -x "*.mdb"
100
101EXTRA_DIST = Pinta Pinta.Core Pinta.Effects Pinta.Gui.Widgets Pinta.Resources Pinta.Tools po xdg license-mit.txt \
102 license-pdn.txt todo.txt Pinta.sln Pinta.Install.proj pinta.pc.in readme.md intltool-extract.in \
103 intltool-merge.in intltool-update.in
104
105CLEANFILES = \
106 intltool-extract \
107 intltool-update \
108 intltool-merge
109
110DISTCLEANFILES = intltool-extract \
111 intltool-merge \
112 intltool-update \
113 po/.intltool-merge-cache
114
115
116
117.PHONY: install uninstall cleanall cleanbin cleanobj release releasetar releasezip
0118
=== renamed file 'Makefile.am' => 'Makefile.am.moved'
=== added file 'Makefile.in'
--- Makefile.in 1970-01-01 00:00:00 +0000
+++ Makefile.in 2013-01-23 15:01:21 +0000
@@ -0,0 +1,849 @@
1# Makefile.in generated by automake 1.11.1 from Makefile.am.
2# @configure_input@
3
4# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
5# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
6# Inc.
7# This Makefile.in is free software; the Free Software Foundation
8# gives unlimited permission to copy and/or distribute it,
9# with or without modifications, as long as this notice is preserved.
10
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
13# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
14# PARTICULAR PURPOSE.
15
16@SET_MAKE@
17
18VPATH = @srcdir@
19pkgdatadir = $(datadir)/@PACKAGE@
20pkgincludedir = $(includedir)/@PACKAGE@
21pkglibdir = $(libdir)/@PACKAGE@
22pkglibexecdir = $(libexecdir)/@PACKAGE@
23am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
24install_sh_DATA = $(install_sh) -c -m 644
25install_sh_PROGRAM = $(install_sh) -c
26install_sh_SCRIPT = $(install_sh) -c
27INSTALL_HEADER = $(INSTALL_DATA)
28transform = $(program_transform_name)
29NORMAL_INSTALL = :
30PRE_INSTALL = :
31POST_INSTALL = :
32NORMAL_UNINSTALL = :
33PRE_UNINSTALL = :
34POST_UNINSTALL = :
35subdir = .
36DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \
37 $(srcdir)/Makefile.in $(srcdir)/pinta.in $(srcdir)/pinta.pc.in \
38 $(top_srcdir)/configure install-sh missing
39ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
40am__aclocal_m4_deps = $(top_srcdir)/configure.ac
41am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
42 $(ACLOCAL_M4)
43am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
44 configure.lineno config.status.lineno
45mkinstalldirs = $(install_sh) -d
46CONFIG_CLEAN_FILES = pinta.pc pinta
47CONFIG_CLEAN_VPATH_FILES =
48SOURCES =
49DIST_SOURCES =
50RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
51 html-recursive info-recursive install-data-recursive \
52 install-dvi-recursive install-exec-recursive \
53 install-html-recursive install-info-recursive \
54 install-pdf-recursive install-ps-recursive install-recursive \
55 installcheck-recursive installdirs-recursive pdf-recursive \
56 ps-recursive uninstall-recursive
57am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
58am__vpath_adj = case $$p in \
59 $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
60 *) f=$$p;; \
61 esac;
62am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
63am__install_max = 40
64am__nobase_strip_setup = \
65 srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
66am__nobase_strip = \
67 for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
68am__nobase_list = $(am__nobase_strip_setup); \
69 for p in $$list; do echo "$$p $$p"; done | \
70 sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
71 $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
72 if (++n[$$2] == $(am__install_max)) \
73 { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
74 END { for (dir in files) print dir, files[dir] }'
75am__base_list = \
76 sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
77 sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
78am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
79DATA = $(pkgconfig_DATA)
80RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
81 distclean-recursive maintainer-clean-recursive
82AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
83 $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
84 distdir dist dist-all distcheck
85ETAGS = etags
86CTAGS = ctags
87DIST_SUBDIRS = $(SUBDIRS)
88DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
89distdir = $(PACKAGE)-$(VERSION)
90top_distdir = $(distdir)
91am__remove_distdir = \
92 { test ! -d "$(distdir)" \
93 || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
94 && rm -fr "$(distdir)"; }; }
95am__relativize = \
96 dir0=`pwd`; \
97 sed_first='s,^\([^/]*\)/.*$$,\1,'; \
98 sed_rest='s,^[^/]*/*,,'; \
99 sed_last='s,^.*/\([^/]*\)$$,\1,'; \
100 sed_butlast='s,/*[^/]*$$,,'; \
101 while test -n "$$dir1"; do \
102 first=`echo "$$dir1" | sed -e "$$sed_first"`; \
103 if test "$$first" != "."; then \
104 if test "$$first" = ".."; then \
105 dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
106 dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
107 else \
108 first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
109 if test "$$first2" = "$$first"; then \
110 dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
111 else \
112 dir2="../$$dir2"; \
113 fi; \
114 dir0="$$dir0"/"$$first"; \
115 fi; \
116 fi; \
117 dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
118 done; \
119 reldir="$$dir2"
120DIST_ARCHIVES = $(distdir).tar.gz
121GZIP_ENV = --best
122distuninstallcheck_listfiles = find . -type f -print
123distcleancheck_listfiles = find . -type f -print
124ACLOCAL = @ACLOCAL@
125ALL_LINGUAS = @ALL_LINGUAS@
126AMTAR = @AMTAR@
127AUTOCONF = @AUTOCONF@
128AUTOHEADER = @AUTOHEADER@
129AUTOMAKE = @AUTOMAKE@
130AWK = @AWK@
131CATALOGS = @CATALOGS@
132CATOBJEXT = @CATOBJEXT@
133CC = @CC@
134CCDEPMODE = @CCDEPMODE@
135CFLAGS = @CFLAGS@
136CPP = @CPP@
137CPPFLAGS = @CPPFLAGS@
138CYGPATH_W = @CYGPATH_W@
139DATADIRNAME = @DATADIRNAME@
140DEFS = @DEFS@
141DEPDIR = @DEPDIR@
142ECHO_C = @ECHO_C@
143ECHO_N = @ECHO_N@
144ECHO_T = @ECHO_T@
145EGREP = @EGREP@
146EXEEXT = @EXEEXT@
147GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
148GLIB_SHARP_20_CFLAGS = @GLIB_SHARP_20_CFLAGS@
149GLIB_SHARP_20_LIBS = @GLIB_SHARP_20_LIBS@
150GMOFILES = @GMOFILES@
151GMSGFMT = @GMSGFMT@
152GREP = @GREP@
153GTK_SHARP_20_CFLAGS = @GTK_SHARP_20_CFLAGS@
154GTK_SHARP_20_LIBS = @GTK_SHARP_20_LIBS@
155INSTALL = @INSTALL@
156INSTALL_DATA = @INSTALL_DATA@
157INSTALL_PROGRAM = @INSTALL_PROGRAM@
158INSTALL_SCRIPT = @INSTALL_SCRIPT@
159INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
160INSTOBJEXT = @INSTOBJEXT@
161INTLLIBS = @INTLLIBS@
162INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
163INTLTOOL_MERGE = @INTLTOOL_MERGE@
164INTLTOOL_PERL = @INTLTOOL_PERL@
165INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
166LDFLAGS = @LDFLAGS@
167LIBOBJS = @LIBOBJS@
168LIBS = @LIBS@
169LTLIBOBJS = @LTLIBOBJS@
170MAKEINFO = @MAKEINFO@
171MKDIR_P = @MKDIR_P@
172MKINSTALLDIRS = @MKINSTALLDIRS@
173MONO = @MONO@
174MONO_CAIRO_CFLAGS = @MONO_CAIRO_CFLAGS@
175MONO_CAIRO_LIBS = @MONO_CAIRO_LIBS@
176MONO_CFLAGS = @MONO_CFLAGS@
177MONO_LIBS = @MONO_LIBS@
178MSGFMT = @MSGFMT@
179MSGFMT_OPTS = @MSGFMT_OPTS@
180MSGMERGE = @MSGMERGE@
181OBJEXT = @OBJEXT@
182PACKAGE = @PACKAGE@
183PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
184PACKAGE_NAME = @PACKAGE_NAME@
185PACKAGE_STRING = @PACKAGE_STRING@
186PACKAGE_TARNAME = @PACKAGE_TARNAME@
187PACKAGE_URL = @PACKAGE_URL@
188PACKAGE_VERSION = @PACKAGE_VERSION@
189PATH_SEPARATOR = @PATH_SEPARATOR@
190PKG_CONFIG = @PKG_CONFIG@
191PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
192PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
193POFILES = @POFILES@
194POSUB = @POSUB@
195PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
196PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
197SET_MAKE = @SET_MAKE@
198SHELL = @SHELL@
199STRIP = @STRIP@
200USE_NLS = @USE_NLS@
201VERSION = @VERSION@
202XBUILD = @XBUILD@
203XGETTEXT = @XGETTEXT@
204abs_builddir = @abs_builddir@
205abs_srcdir = @abs_srcdir@
206abs_top_builddir = @abs_top_builddir@
207abs_top_srcdir = @abs_top_srcdir@
208ac_ct_CC = @ac_ct_CC@
209am__include = @am__include@
210am__leading_dot = @am__leading_dot@
211am__quote = @am__quote@
212am__tar = @am__tar@
213am__untar = @am__untar@
214bindir = @bindir@
215build_alias = @build_alias@
216builddir = @builddir@
217datadir = @datadir@
218datarootdir = @datarootdir@
219docdir = @docdir@
220dvidir = @dvidir@
221exec_prefix = @exec_prefix@
222host_alias = @host_alias@
223htmldir = @htmldir@
224includedir = @includedir@
225infodir = @infodir@
226install_sh = @install_sh@
227libdir = @libdir@
228libexecdir = @libexecdir@
229localedir = @localedir@
230localstatedir = @localstatedir@
231mandir = @mandir@
232mkdir_p = @mkdir_p@
233oldincludedir = @oldincludedir@
234pdfdir = @pdfdir@
235pintalocaledir = @pintalocaledir@
236prefix = @prefix@
237program_transform_name = @program_transform_name@
238psdir = @psdir@
239sbindir = @sbindir@
240sharedstatedir = @sharedstatedir@
241srcdir = @srcdir@
242sysconfdir = @sysconfdir@
243target_alias = @target_alias@
244top_build_prefix = @top_build_prefix@
245top_builddir = @top_builddir@
246top_srcdir = @top_srcdir@
247SUBDIRS = xdg
248BINDIR = $(srcdir)/bin
249PINTA_ASSEMBLY_PC = $(srcdir)/$(PACKAGE_NAME).pc
250BINFILES = \
251 $(BINDIR)/Pinta.exe \
252 $(BINDIR)/Pinta.Core.dll \
253 $(BINDIR)/Pinta.Gui.Widgets.dll \
254 $(BINDIR)/Pinta.Resources.dll \
255 $(BINDIR)/Pinta.Effects.dll \
256 $(BINDIR)/Pinta.Tools.dll
257
258RELEASE_FILE = $(PACKAGE)-$(VERSION)
259
260#magic automake variables
261pkgconfigdir = $(libdir)/pkgconfig
262pkgconfig_DATA = $(PINTA_ASSEMBLY_PC)
263EXTRA_DIST = Pinta Pinta.Core Pinta.Effects Pinta.Gui.Widgets Pinta.Resources Pinta.Tools po xdg license-mit.txt \
264 license-pdn.txt todo.txt Pinta.sln Pinta.Install.proj pinta.pc.in readme.md intltool-extract.in \
265 intltool-merge.in intltool-update.in
266
267CLEANFILES = \
268 intltool-extract \
269 intltool-update \
270 intltool-merge
271
272DISTCLEANFILES = intltool-extract \
273 intltool-merge \
274 intltool-update \
275 po/.intltool-merge-cache
276
277all: all-recursive
278
279.SUFFIXES:
280am--refresh:
281 @:
282$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
283 @for dep in $?; do \
284 case '$(am__configure_deps)' in \
285 *$$dep*) \
286 echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
287 $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
288 && exit 0; \
289 exit 1;; \
290 esac; \
291 done; \
292 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
293 $(am__cd) $(top_srcdir) && \
294 $(AUTOMAKE) --foreign Makefile
295.PRECIOUS: Makefile
296Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
297 @case '$?' in \
298 *config.status*) \
299 echo ' $(SHELL) ./config.status'; \
300 $(SHELL) ./config.status;; \
301 *) \
302 echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
303 cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
304 esac;
305
306$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
307 $(SHELL) ./config.status --recheck
308
309$(top_srcdir)/configure: $(am__configure_deps)
310 $(am__cd) $(srcdir) && $(AUTOCONF)
311$(ACLOCAL_M4): $(am__aclocal_m4_deps)
312 $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
313$(am__aclocal_m4_deps):
314pinta.pc: $(top_builddir)/config.status $(srcdir)/pinta.pc.in
315 cd $(top_builddir) && $(SHELL) ./config.status $@
316pinta: $(top_builddir)/config.status $(srcdir)/pinta.in
317 cd $(top_builddir) && $(SHELL) ./config.status $@
318install-pkgconfigDATA: $(pkgconfig_DATA)
319 @$(NORMAL_INSTALL)
320 test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
321 @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
322 for p in $$list; do \
323 if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
324 echo "$$d$$p"; \
325 done | $(am__base_list) | \
326 while read files; do \
327 echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
328 $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
329 done
330
331uninstall-pkgconfigDATA:
332 @$(NORMAL_UNINSTALL)
333 @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
334 files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
335 test -n "$$files" || exit 0; \
336 echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \
337 cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files
338
339# This directory's subdirectories are mostly independent; you can cd
340# into them and run `make' without going through this Makefile.
341# To change the values of `make' variables: instead of editing Makefiles,
342# (1) if the variable is set in `config.status', edit `config.status'
343# (which will cause the Makefiles to be regenerated when you run `make');
344# (2) otherwise, pass the desired values on the `make' command line.
345$(RECURSIVE_TARGETS):
346 @fail= failcom='exit 1'; \
347 for f in x $$MAKEFLAGS; do \
348 case $$f in \
349 *=* | --[!k]*);; \
350 *k*) failcom='fail=yes';; \
351 esac; \
352 done; \
353 dot_seen=no; \
354 target=`echo $@ | sed s/-recursive//`; \
355 list='$(SUBDIRS)'; for subdir in $$list; do \
356 echo "Making $$target in $$subdir"; \
357 if test "$$subdir" = "."; then \
358 dot_seen=yes; \
359 local_target="$$target-am"; \
360 else \
361 local_target="$$target"; \
362 fi; \
363 ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
364 || eval $$failcom; \
365 done; \
366 if test "$$dot_seen" = "no"; then \
367 $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
368 fi; test -z "$$fail"
369
370$(RECURSIVE_CLEAN_TARGETS):
371 @fail= failcom='exit 1'; \
372 for f in x $$MAKEFLAGS; do \
373 case $$f in \
374 *=* | --[!k]*);; \
375 *k*) failcom='fail=yes';; \
376 esac; \
377 done; \
378 dot_seen=no; \
379 case "$@" in \
380 distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
381 *) list='$(SUBDIRS)' ;; \
382 esac; \
383 rev=''; for subdir in $$list; do \
384 if test "$$subdir" = "."; then :; else \
385 rev="$$subdir $$rev"; \
386 fi; \
387 done; \
388 rev="$$rev ."; \
389 target=`echo $@ | sed s/-recursive//`; \
390 for subdir in $$rev; do \
391 echo "Making $$target in $$subdir"; \
392 if test "$$subdir" = "."; then \
393 local_target="$$target-am"; \
394 else \
395 local_target="$$target"; \
396 fi; \
397 ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
398 || eval $$failcom; \
399 done && test -z "$$fail"
400tags-recursive:
401 list='$(SUBDIRS)'; for subdir in $$list; do \
402 test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
403 done
404ctags-recursive:
405 list='$(SUBDIRS)'; for subdir in $$list; do \
406 test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
407 done
408
409ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
410 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
411 unique=`for i in $$list; do \
412 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
413 done | \
414 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
415 END { if (nonempty) { for (i in files) print i; }; }'`; \
416 mkid -fID $$unique
417tags: TAGS
418
419TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
420 $(TAGS_FILES) $(LISP)
421 set x; \
422 here=`pwd`; \
423 if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
424 include_option=--etags-include; \
425 empty_fix=.; \
426 else \
427 include_option=--include; \
428 empty_fix=; \
429 fi; \
430 list='$(SUBDIRS)'; for subdir in $$list; do \
431 if test "$$subdir" = .; then :; else \
432 test ! -f $$subdir/TAGS || \
433 set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
434 fi; \
435 done; \
436 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
437 unique=`for i in $$list; do \
438 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
439 done | \
440 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
441 END { if (nonempty) { for (i in files) print i; }; }'`; \
442 shift; \
443 if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
444 test -n "$$unique" || unique=$$empty_fix; \
445 if test $$# -gt 0; then \
446 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
447 "$$@" $$unique; \
448 else \
449 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
450 $$unique; \
451 fi; \
452 fi
453ctags: CTAGS
454CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
455 $(TAGS_FILES) $(LISP)
456 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
457 unique=`for i in $$list; do \
458 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
459 done | \
460 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
461 END { if (nonempty) { for (i in files) print i; }; }'`; \
462 test -z "$(CTAGS_ARGS)$$unique" \
463 || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
464 $$unique
465
466GTAGS:
467 here=`$(am__cd) $(top_builddir) && pwd` \
468 && $(am__cd) $(top_srcdir) \
469 && gtags -i $(GTAGS_ARGS) "$$here"
470
471distclean-tags:
472 -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
473
474distdir: $(DISTFILES)
475 $(am__remove_distdir)
476 test -d "$(distdir)" || mkdir "$(distdir)"
477 @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
478 topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
479 list='$(DISTFILES)'; \
480 dist_files=`for file in $$list; do echo $$file; done | \
481 sed -e "s|^$$srcdirstrip/||;t" \
482 -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
483 case $$dist_files in \
484 */*) $(MKDIR_P) `echo "$$dist_files" | \
485 sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
486 sort -u` ;; \
487 esac; \
488 for file in $$dist_files; do \
489 if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
490 if test -d $$d/$$file; then \
491 dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
492 if test -d "$(distdir)/$$file"; then \
493 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
494 fi; \
495 if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
496 cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
497 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
498 fi; \
499 cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
500 else \
501 test -f "$(distdir)/$$file" \
502 || cp -p $$d/$$file "$(distdir)/$$file" \
503 || exit 1; \
504 fi; \
505 done
506 @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
507 if test "$$subdir" = .; then :; else \
508 test -d "$(distdir)/$$subdir" \
509 || $(MKDIR_P) "$(distdir)/$$subdir" \
510 || exit 1; \
511 fi; \
512 done
513 @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
514 if test "$$subdir" = .; then :; else \
515 dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
516 $(am__relativize); \
517 new_distdir=$$reldir; \
518 dir1=$$subdir; dir2="$(top_distdir)"; \
519 $(am__relativize); \
520 new_top_distdir=$$reldir; \
521 echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
522 echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
523 ($(am__cd) $$subdir && \
524 $(MAKE) $(AM_MAKEFLAGS) \
525 top_distdir="$$new_top_distdir" \
526 distdir="$$new_distdir" \
527 am__remove_distdir=: \
528 am__skip_length_check=: \
529 am__skip_mode_fix=: \
530 distdir) \
531 || exit 1; \
532 fi; \
533 done
534 -test -n "$(am__skip_mode_fix)" \
535 || find "$(distdir)" -type d ! -perm -755 \
536 -exec chmod u+rwx,go+rx {} \; -o \
537 ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
538 ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
539 ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
540 || chmod -R a+r "$(distdir)"
541dist-gzip: distdir
542 tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
543 $(am__remove_distdir)
544
545dist-bzip2: distdir
546 tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
547 $(am__remove_distdir)
548
549dist-lzma: distdir
550 tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
551 $(am__remove_distdir)
552
553dist-xz: distdir
554 tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
555 $(am__remove_distdir)
556
557dist-tarZ: distdir
558 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
559 $(am__remove_distdir)
560
561dist-shar: distdir
562 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
563 $(am__remove_distdir)
564
565dist-zip: distdir
566 -rm -f $(distdir).zip
567 zip -rq $(distdir).zip $(distdir)
568 $(am__remove_distdir)
569
570dist dist-all: distdir
571 tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
572 $(am__remove_distdir)
573
574# This target untars the dist file and tries a VPATH configuration. Then
575# it guarantees that the distribution is self-contained by making another
576# tarfile.
577distcheck: dist
578 case '$(DIST_ARCHIVES)' in \
579 *.tar.gz*) \
580 GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
581 *.tar.bz2*) \
582 bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
583 *.tar.lzma*) \
584 lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
585 *.tar.xz*) \
586 xz -dc $(distdir).tar.xz | $(am__untar) ;;\
587 *.tar.Z*) \
588 uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
589 *.shar.gz*) \
590 GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
591 *.zip*) \
592 unzip $(distdir).zip ;;\
593 esac
594 chmod -R a-w $(distdir); chmod a+w $(distdir)
595 mkdir $(distdir)/_build
596 mkdir $(distdir)/_inst
597 chmod a-w $(distdir)
598 test -d $(distdir)/_build || exit 0; \
599 dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
600 && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
601 && am__cwd=`pwd` \
602 && $(am__cd) $(distdir)/_build \
603 && ../configure --srcdir=.. --prefix="$$dc_install_base" \
604 $(DISTCHECK_CONFIGURE_FLAGS) \
605 && $(MAKE) $(AM_MAKEFLAGS) \
606 && $(MAKE) $(AM_MAKEFLAGS) dvi \
607 && $(MAKE) $(AM_MAKEFLAGS) check \
608 && $(MAKE) $(AM_MAKEFLAGS) install \
609 && $(MAKE) $(AM_MAKEFLAGS) installcheck \
610 && $(MAKE) $(AM_MAKEFLAGS) uninstall \
611 && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
612 distuninstallcheck \
613 && chmod -R a-w "$$dc_install_base" \
614 && ({ \
615 (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
616 && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
617 && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
618 && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
619 distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
620 } || { rm -rf "$$dc_destdir"; exit 1; }) \
621 && rm -rf "$$dc_destdir" \
622 && $(MAKE) $(AM_MAKEFLAGS) dist \
623 && rm -rf $(DIST_ARCHIVES) \
624 && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
625 && cd "$$am__cwd" \
626 || exit 1
627 $(am__remove_distdir)
628 @(echo "$(distdir) archives ready for distribution: "; \
629 list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
630 sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
631distuninstallcheck:
632 @$(am__cd) '$(distuninstallcheck_dir)' \
633 && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
634 || { echo "ERROR: files left after uninstall:" ; \
635 if test -n "$(DESTDIR)"; then \
636 echo " (check DESTDIR support)"; \
637 fi ; \
638 $(distuninstallcheck_listfiles) ; \
639 exit 1; } >&2
640distcleancheck: distclean
641 @if test '$(srcdir)' = . ; then \
642 echo "ERROR: distcleancheck can only run from a VPATH build" ; \
643 exit 1 ; \
644 fi
645 @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
646 || { echo "ERROR: files left in build directory after distclean:" ; \
647 $(distcleancheck_listfiles) ; \
648 exit 1; } >&2
649check-am: all-am
650check: check-recursive
651all-am: Makefile $(DATA)
652installdirs: installdirs-recursive
653installdirs-am:
654 for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
655 test -z "$$dir" || $(MKDIR_P) "$$dir"; \
656 done
657install-exec: install-exec-recursive
658install-data: install-data-recursive
659
660install-am: all-am
661 @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
662
663installcheck: installcheck-recursive
664install-strip:
665 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
666 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
667 `test -z '$(STRIP)' || \
668 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
669mostlyclean-generic:
670
671clean-generic:
672 -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
673
674distclean-generic:
675 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
676 -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
677 -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
678
679maintainer-clean-generic:
680 @echo "This command is intended for maintainers to use"
681 @echo "it deletes files that may require special tools to rebuild."
682clean-am: clean-generic mostlyclean-am
683
684distclean-am: clean-am distclean-generic distclean-tags
685
686dvi: dvi-recursive
687
688dvi-am:
689
690html: html-recursive
691
692html-am:
693
694info: info-recursive
695
696info-am:
697
698install-data-am: install-pkgconfigDATA
699
700install-dvi: install-dvi-recursive
701
702install-dvi-am:
703
704install-exec-am:
705
706install-html: install-html-recursive
707
708install-html-am:
709
710install-info: install-info-recursive
711
712install-info-am:
713
714install-man:
715
716install-pdf: install-pdf-recursive
717
718install-pdf-am:
719
720install-ps: install-ps-recursive
721
722install-ps-am:
723
724installcheck-am:
725
726maintainer-clean: maintainer-clean-recursive
727 -rm -f $(am__CONFIG_DISTCLEAN_FILES)
728 -rm -rf $(top_srcdir)/autom4te.cache
729 -rm -f Makefile
730maintainer-clean-am: distclean-am maintainer-clean-generic
731
732mostlyclean: mostlyclean-recursive
733
734mostlyclean-am: mostlyclean-generic
735
736pdf: pdf-recursive
737
738pdf-am:
739
740ps: ps-recursive
741
742ps-am:
743
744uninstall-am: uninstall-pkgconfigDATA
745
746.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
747 install-am install-strip tags-recursive
748
749.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
750 all all-am am--refresh check check-am clean clean-generic \
751 ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
752 dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \
753 distclean distclean-generic distclean-tags distcleancheck \
754 distdir distuninstallcheck dvi dvi-am html html-am info \
755 info-am install install-am install-data install-data-am \
756 install-dvi install-dvi-am install-exec install-exec-am \
757 install-html install-html-am install-info install-info-am \
758 install-man install-pdf install-pdf-am install-pkgconfigDATA \
759 install-ps install-ps-am install-strip installcheck \
760 installcheck-am installdirs installdirs-am maintainer-clean \
761 maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
762 pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
763 uninstall-pkgconfigDATA
764
765
766#end
767
768# target: all - Default target: build
769all: build
770
771# target: run - Launch the uninstalled copy
772run:
773 $(MONO) bin/Pinta.exe
774
775# target: help - Display callable targets.
776help:
777 egrep "^# target:" Makefile | sed 's/^# target:/make/'
778
779# target: build - Build Pinta.
780build: Pinta.sln
781 cd $(srcdir) && $(XBUILD) Pinta.sln
782 cd $(srcdir) && $(XBUILD) Pinta.Install.proj /target:CompileTranslations
783
784# target: list - List source files.
785list:
786 if ! git status > /dev/null 2> /dev/null ;\
787 then \
788 find . -type f -name *.cs | sed 's|./||' ;\
789 else \
790 git ls-files | grep '\.cs' ;\
791 fi
792
793#target: updatepot - update the messages.pot file
794updatepot: build
795 find . -type f -name *.cs | sed 's|./||' > files.list
796 grep -v System.ComponentModel.Composition files.list > files2.list
797 xgettext --from-code=UTF-8 -f files2.list -o po/messages.pot
798 cat po/messages.in >> po/messages.pot
799 rm files.list
800 rm files2.list
801
802# target: clean - Default clean command: cleanobj and cleanbin
803clean: cleanobj cleanbin
804
805# target: distclean - Removes configure files.
806distclean: clean
807 rm -f Makefile pinta config.status config.cache config.log configure.lineno config.status.lineno pinta.pc
808
809# target: cleanall - Removes build files.
810cleanall: distclean
811 rm -rf autom4te.cache
812 rm -f configure aclocal.m4 missing install-sh Makefile.in
813
814# target: cleanbin - Removes built files.
815cleanbin:
816 rm -rvf $(BINDIR)/*
817
818# target: cleanobj - Removes temporary build files.
819cleanobj:
820 find $(srcdir)/ -type d -name obj | xargs rm -rvf
821
822# target: install - Installs Pinta.
823install: pinta $(BINFILES)
824 cd $(srcdir) && $(XBUILD) /target:Install /property:InstallPrefix=$(DESTDIR)$(prefix) \
825 /property:BinDir=$(DESTDIR)$(bindir) /property:LibDir=$(DESTDIR)$(libdir) \
826 /property:DataRootDir=$(DESTDIR)$(datarootdir) /property:ManDir=$(DESTDIR)$(mandir) \
827 /property:LocaleDir=$(DESTDIR)$(localedir) Pinta.Install.proj
828 $(INSTALL_SCRIPT) pinta $(DESTDIR)$(bindir)/$(PACKAGE)
829
830# target: uninstall - Uninstalls Pinta.
831uninstall:
832 $(XBUILD) /target:Uninstall /property:InstallPrefix=$(DESTDIR)$(prefix) Pinta.Install.proj
833
834# target: release - Default release type: releasetar
835release: releasetar
836
837# target: releasetar - Make a release tarball.
838releasetar: $(BINFILES)
839 cd $(BINDIR) && tar -czf ../$(RELEASE_FILE).tgz --exclude=*mdb *
840
841# target: releasezip - Make a release zip file.
842releasezip: $(BINFILES)
843 cd $(BINDIR) && zip -r ../$(RELEASE_FILE).zip * -x "*.mdb"
844
845.PHONY: install uninstall cleanall cleanbin cleanobj release releasetar releasezip
846
847# Tell versions [3.59,3.63) of GNU make to not export all variables.
848# Otherwise a system limit (for SysV at least) may be exceeded.
849.NOEXPORT:
0850
=== added directory 'Pinta'
=== added directory 'Pinta.Core'
=== renamed directory 'Pinta.Core' => 'Pinta.Core.moved'
=== added file 'Pinta.Core/.gitignore'
--- Pinta.Core/.gitignore 1970-01-01 00:00:00 +0000
+++ Pinta.Core/.gitignore 2013-01-23 15:01:21 +0000
@@ -0,0 +1,3 @@
1/bin/
2/obj/
3*.user
0\ No newline at end of file4\ No newline at end of file
15
=== added directory 'Pinta.Core/Actions'
=== added file 'Pinta.Core/Actions/AdjustmentsActions.cs'
--- Pinta.Core/Actions/AdjustmentsActions.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Actions/AdjustmentsActions.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,57 @@
1//
2// AdjustmentsActions.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using System.Collections.Generic;
29using System.Threading;
30using Cairo;
31
32namespace Pinta.Core
33{
34 public class AdjustmentsActions
35 {
36 public List<Gtk.Action> Actions { get; private set; }
37
38 public AdjustmentsActions ()
39 {
40 Actions = new List<Gtk.Action> ();
41 }
42
43 #region Initialization
44 public void CreateMainMenu (Gtk.Menu menu)
45 {
46 }
47 #endregion
48
49 #region Public Methods
50 public void ToggleActionsSensitive (bool sensitive)
51 {
52 foreach (Gtk.Action a in Actions)
53 a.Sensitive = sensitive;
54 }
55 #endregion
56 }
57}
058
=== added file 'Pinta.Core/Actions/EditActions.cs'
--- Pinta.Core/Actions/EditActions.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Actions/EditActions.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,433 @@
1//
2// EditActions.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using Gtk;
29using Cairo;
30using Mono.Unix;
31
32namespace Pinta.Core
33{
34 public class EditActions
35 {
36 public Gtk.Action Undo { get; private set; }
37 public Gtk.Action Redo { get; private set; }
38 public Gtk.Action Cut { get; private set; }
39 public Gtk.Action Copy { get; private set; }
40 public Gtk.Action Paste { get; private set; }
41 public Gtk.Action PasteIntoNewLayer { get; private set; }
42 public Gtk.Action PasteIntoNewImage { get; private set; }
43 public Gtk.Action EraseSelection { get; private set; }
44 public Gtk.Action FillSelection { get; private set; }
45 public Gtk.Action InvertSelection { get; private set; }
46 public Gtk.Action SelectAll { get; private set; }
47 public Gtk.Action Deselect { get; private set; }
48 public Gtk.Action LoadPalette { get; private set; }
49 public Gtk.Action SavePalette { get; private set; }
50 public Gtk.Action ResetPalette { get; private set; }
51 public Gtk.Action ResizePalette { get; private set; }
52
53 private string lastPaletteDir = null;
54
55 public EditActions ()
56 {
57 Gtk.IconFactory fact = new Gtk.IconFactory ();
58 fact.Add ("Menu.Edit.Deselect.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.Deselect.png")));
59 fact.Add ("Menu.Edit.EraseSelection.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.EraseSelection.png")));
60 fact.Add ("Menu.Edit.FillSelection.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.FillSelection.png")));
61 fact.Add ("Menu.Edit.InvertSelection.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.InvertSelection.png")));
62 fact.Add ("Menu.Edit.SelectAll.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Edit.SelectAll.png")));
63 fact.AddDefault ();
64
65 Undo = new Gtk.Action ("Undo", Catalog.GetString ("Undo"), null, Stock.Undo);
66 Redo = new Gtk.Action ("Redo", Catalog.GetString ("Redo"), null, Stock.Redo);
67 Cut = new Gtk.Action ("Cut", Catalog.GetString ("Cut"), null, Stock.Cut);
68 Copy = new Gtk.Action ("Copy", Catalog.GetString ("Copy"), null, Stock.Copy);
69 Paste = new Gtk.Action ("Paste", Catalog.GetString ("Paste"), null, Stock.Paste);
70 PasteIntoNewLayer = new Gtk.Action ("PasteIntoNewLayer", Catalog.GetString ("Paste Into New Layer"), null, Stock.Paste);
71 PasteIntoNewImage = new Gtk.Action ("PasteIntoNewImage", Catalog.GetString ("Paste Into New Image"), null, Stock.Paste);
72 EraseSelection = new Gtk.Action ("EraseSelection", Catalog.GetString ("Delete Selection"), null, "Menu.Edit.EraseSelection.png");
73 FillSelection = new Gtk.Action ("FillSelection", Catalog.GetString ("Fill Selection"), null, "Menu.Edit.FillSelection.png");
74 InvertSelection = new Gtk.Action ("InvertSelection", Catalog.GetString ("Invert Selection"), null, "Menu.Edit.InvertSelection.png");
75 SelectAll = new Gtk.Action ("SelectAll", Catalog.GetString ("Select All"), null, Stock.SelectAll);
76 Deselect = new Gtk.Action ("Deselect", Catalog.GetString ("Deselect All"), null, "Menu.Edit.Deselect.png");
77
78 LoadPalette = new Gtk.Action ("LoadPalette", Catalog.GetString ("Open..."), null, Stock.Open);
79 SavePalette = new Gtk.Action ("SavePalette", Catalog.GetString ("Save As..."), null, Stock.Save);
80 ResetPalette = new Gtk.Action ("ResetPalette", Catalog.GetString ("Reset to Default"), null, Stock.RevertToSaved);
81 ResizePalette = new Gtk.Action ("ResizePalette", Catalog.GetString ("Set Number of Colors"), null, "Menu.Image.Resize.png");
82
83 Undo.IsImportant = true;
84 Undo.Sensitive = false;
85 Redo.Sensitive = false;
86 InvertSelection.Sensitive = false;
87 Deselect.Sensitive = false;
88 EraseSelection.Sensitive = false;
89 FillSelection.Sensitive = false;
90 }
91
92 #region Initialization
93 public void CreateMainMenu (Gtk.Menu menu)
94 {
95 menu.Append (Undo.CreateAcceleratedMenuItem (Gdk.Key.Z, Gdk.ModifierType.ControlMask));
96
97 ImageMenuItem redo = Redo.CreateAcceleratedMenuItem (Gdk.Key.Z, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask);
98 redo.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.Y, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
99 menu.Append (redo);
100
101 menu.AppendSeparator ();
102 menu.Append (Cut.CreateAcceleratedMenuItem (Gdk.Key.X, Gdk.ModifierType.ControlMask));
103 menu.Append (Copy.CreateAcceleratedMenuItem (Gdk.Key.C, Gdk.ModifierType.ControlMask));
104 menu.Append (Paste.CreateAcceleratedMenuItem (Gdk.Key.V, Gdk.ModifierType.ControlMask));
105 menu.Append (PasteIntoNewLayer.CreateAcceleratedMenuItem (Gdk.Key.V, Gdk.ModifierType.ShiftMask | Gdk.ModifierType.ControlMask));
106 menu.Append (PasteIntoNewImage.CreateAcceleratedMenuItem (Gdk.Key.V, Gdk.ModifierType.Mod1Mask | Gdk.ModifierType.ControlMask));
107
108 menu.AppendSeparator ();
109 menu.Append (SelectAll.CreateAcceleratedMenuItem (Gdk.Key.A, Gdk.ModifierType.ControlMask));
110
111 ImageMenuItem deslect = Deselect.CreateAcceleratedMenuItem (Gdk.Key.A, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask);
112 deslect.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.D, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
113 menu.Append (deslect);
114
115 menu.AppendSeparator ();
116 menu.Append (EraseSelection.CreateAcceleratedMenuItem (Gdk.Key.Delete, Gdk.ModifierType.None));
117 menu.Append (FillSelection.CreateAcceleratedMenuItem (Gdk.Key.BackSpace, Gdk.ModifierType.None));
118 //menu.Append (InvertSelection.CreateAcceleratedMenuItem (Gdk.Key.I, Gdk.ModifierType.ControlMask));
119
120 menu.AppendSeparator ();
121 Gtk.Action menu_action = new Gtk.Action ("Palette", Mono.Unix.Catalog.GetString ("Palette"), null, null);
122 Menu palette_menu = (Menu) menu.AppendItem (menu_action.CreateSubMenuItem ()).Submenu;
123 palette_menu.Append (LoadPalette.CreateMenuItem ());
124 palette_menu.Append (SavePalette.CreateMenuItem ());
125 palette_menu.Append (ResetPalette.CreateMenuItem ());
126 palette_menu.Append (ResizePalette.CreateMenuItem ());
127 }
128
129 public void CreateHistoryWindowToolBar (Gtk.Toolbar toolbar)
130 {
131 toolbar.AppendItem (Undo.CreateToolBarItem ());
132 toolbar.AppendItem (Redo.CreateToolBarItem ());
133 }
134
135 public void RegisterHandlers ()
136 {
137 Deselect.Activated += HandlePintaCoreActionsEditDeselectActivated;
138 EraseSelection.Activated += HandlePintaCoreActionsEditEraseSelectionActivated;
139 SelectAll.Activated += HandlePintaCoreActionsEditSelectAllActivated;
140 FillSelection.Activated += HandlePintaCoreActionsEditFillSelectionActivated;
141 Paste.Activated += HandlerPintaCoreActionsEditPasteActivated;
142 Copy.Activated += HandlerPintaCoreActionsEditCopyActivated;
143 Undo.Activated += HandlerPintaCoreActionsEditUndoActivated;
144 Redo.Activated += HandlerPintaCoreActionsEditRedoActivated;
145 Cut.Activated += HandlerPintaCoreActionsEditCutActivated;
146 LoadPalette.Activated += HandlerPintaCoreActionsEditLoadPaletteActivated;
147 SavePalette.Activated += HandlerPintaCoreActionsEditSavePaletteActivated;
148 ResetPalette.Activated += HandlerPintaCoreActionsEditResetPaletteActivated;
149
150 PintaCore.Workspace.ActiveDocumentChanged += WorkspaceActiveDocumentChanged;
151 }
152 #endregion
153
154 #region Action Handlers
155 private void HandlePintaCoreActionsEditFillSelectionActivated (object sender, EventArgs e)
156 {
157 Document doc = PintaCore.Workspace.ActiveDocument;
158
159 PintaCore.Tools.Commit ();
160
161 Cairo.ImageSurface old = doc.CurrentLayer.Surface.Clone ();
162
163 using (var g = new Cairo.Context (doc.CurrentLayer.Surface)) {
164 g.AppendPath (doc.SelectionPath);
165 g.FillRule = FillRule.EvenOdd;
166
167 g.Color = PintaCore.Palette.PrimaryColor;
168 g.Fill ();
169 }
170
171 doc.Workspace.Invalidate ();
172 doc.History.PushNewItem (new SimpleHistoryItem ("Menu.Edit.FillSelection.png", Catalog.GetString ("Fill Selection"), old, doc.CurrentLayerIndex));
173 }
174
175 private void HandlePintaCoreActionsEditSelectAllActivated (object sender, EventArgs e)
176 {
177 Document doc = PintaCore.Workspace.ActiveDocument;
178
179 PintaCore.Tools.Commit ();
180
181 SelectionHistoryItem hist = new SelectionHistoryItem (Stock.SelectAll, Catalog.GetString ("Select All"));
182 hist.TakeSnapshot ();
183
184 doc.ResetSelectionPath ();
185 doc.ShowSelection = true;
186
187 doc.History.PushNewItem (hist);
188 doc.Workspace.Invalidate ();
189 }
190
191 private void HandlePintaCoreActionsEditEraseSelectionActivated (object sender, EventArgs e)
192 {
193 Document doc = PintaCore.Workspace.ActiveDocument;
194
195 PintaCore.Tools.Commit ();
196
197 Cairo.ImageSurface old = doc.CurrentLayer.Surface.Clone ();
198
199 using (var g = new Cairo.Context (doc.CurrentLayer.Surface)) {
200 g.AppendPath (doc.SelectionPath);
201 g.FillRule = FillRule.EvenOdd;
202
203 g.Operator = Cairo.Operator.Clear;
204 g.Fill ();
205 }
206
207 doc.Workspace.Invalidate ();
208
209 if (sender is string && (sender as string) == "Cut")
210 doc.History.PushNewItem (new SimpleHistoryItem (Stock.Cut, Catalog.GetString ("Cut"), old, doc.CurrentLayerIndex));
211 else
212 doc.History.PushNewItem (new SimpleHistoryItem ("Menu.Edit.EraseSelection.png", Catalog.GetString ("Erase Selection"), old, doc.CurrentLayerIndex));
213 }
214
215 private void HandlePintaCoreActionsEditDeselectActivated (object sender, EventArgs e)
216 {
217 Document doc = PintaCore.Workspace.ActiveDocument;
218
219 PintaCore.Tools.Commit ();
220
221 SelectionHistoryItem hist = new SelectionHistoryItem ("Menu.Edit.Deselect.png", Catalog.GetString ("Deselect"));
222 hist.TakeSnapshot ();
223
224 doc.ResetSelectionPath ();
225
226 doc.History.PushNewItem (hist);
227 doc.Workspace.Invalidate ();
228 }
229
230 private void HandlerPintaCoreActionsEditPasteActivated (object sender, EventArgs e)
231 {
232 Document doc = PintaCore.Workspace.ActiveDocument;
233
234 PintaCore.Tools.Commit ();
235
236 Gtk.Clipboard cb = Gtk.Clipboard.Get (Gdk.Atom.Intern ("CLIPBOARD", false));
237
238 Path p;
239
240 // Don't dispose this, as we're going to give it to the history
241 Gdk.Pixbuf image = cb.WaitForImage ();
242
243 if (image == null)
244 return;
245
246 Gdk.Size canvas_size = PintaCore.Workspace.ImageSize;
247
248 // If the image being pasted is larger than the canvas size, allow the user to optionally resize the canvas
249 if (image.Width > canvas_size.Width || image.Height > canvas_size.Height)
250 {
251 string message = Catalog.GetString ("The image being pasted is larger than the canvas size. What would you like to do?");
252
253 var enlarge_dialog = new MessageDialog (PintaCore.Chrome.MainWindow, DialogFlags.Modal, MessageType.Question, ButtonsType.None, message);
254 enlarge_dialog.AddButton (Catalog.GetString ("Expand canvas"), ResponseType.Accept);
255 enlarge_dialog.AddButton (Catalog.GetString ("Don't change canvas size"), ResponseType.Reject);
256 enlarge_dialog.AddButton (Stock.Cancel, ResponseType.Cancel);
257 enlarge_dialog.DefaultResponse = ResponseType.Accept;
258
259 ResponseType response = (ResponseType)enlarge_dialog.Run ();
260 enlarge_dialog.Destroy ();
261
262 if (response == ResponseType.Accept)
263 {
264 PintaCore.Workspace.ResizeCanvas (image.Width, image.Height, Pinta.Core.Anchor.Center);
265 PintaCore.Actions.View.UpdateCanvasScale ();
266 }
267 else if (response == ResponseType.Cancel || response == ResponseType.DeleteEvent)
268 {
269 return;
270 }
271 }
272
273 // Copy the paste to the temp layer
274 doc.CreateSelectionLayer ();
275 doc.ShowSelectionLayer = true;
276
277 using (Cairo.Context g = new Cairo.Context (doc.SelectionLayer.Surface)) {
278 g.DrawPixbuf (image, new Cairo.Point (0, 0));
279 p = g.CreateRectanglePath (new Rectangle (0, 0, image.Width, image.Height));
280 }
281
282 PintaCore.Tools.SetCurrentTool (Catalog.GetString ("Move Selected Pixels"));
283
284 Path old_path = doc.SelectionPath;
285 bool old_show_selection = doc.ShowSelection;
286
287 doc.SelectionPath = p;
288 doc.ShowSelection = true;
289
290 doc.Workspace.Invalidate ();
291
292 doc.History.PushNewItem (new PasteHistoryItem (image, old_path, old_show_selection));
293 }
294
295 private void HandlerPintaCoreActionsEditCopyActivated (object sender, EventArgs e)
296 {
297 Document doc = PintaCore.Workspace.ActiveDocument;
298
299 PintaCore.Tools.Commit ();
300
301 ImageSurface src = doc.GetClippedLayer (doc.CurrentLayerIndex);
302
303 Gdk.Rectangle rect = doc.GetSelectedBounds (true);
304
305 ImageSurface dest = new ImageSurface (Format.Argb32, rect.Width, rect.Height);
306
307 using (Context g = new Context (dest)) {
308 g.SetSourceSurface (src, -rect.X, -rect.Y);
309 g.Paint ();
310 }
311
312 Gtk.Clipboard cb = Gtk.Clipboard.Get (Gdk.Atom.Intern ("CLIPBOARD", false));
313 cb.Image = dest.ToPixbuf ();
314
315 (src as IDisposable).Dispose ();
316 (dest as IDisposable).Dispose ();
317 }
318
319 private void HandlerPintaCoreActionsEditCutActivated (object sender, EventArgs e)
320 {
321 Document doc = PintaCore.Workspace.ActiveDocument;
322
323 PintaCore.Tools.Commit ();
324
325 // Copy selection
326 HandlerPintaCoreActionsEditCopyActivated (sender, e);
327
328 // Erase selection
329 HandlePintaCoreActionsEditEraseSelectionActivated ("Cut", e);
330 }
331
332 private void HandlerPintaCoreActionsEditUndoActivated (object sender, EventArgs e)
333 {
334 Document doc = PintaCore.Workspace.ActiveDocument;
335 doc.History.Undo ();
336 }
337
338 private void HandlerPintaCoreActionsEditRedoActivated (object sender, EventArgs e)
339 {
340 Document doc = PintaCore.Workspace.ActiveDocument;
341 doc.History.Redo ();
342 }
343
344 private void HandlerPintaCoreActionsEditLoadPaletteActivated (object sender, EventArgs e)
345 {
346 var fcd = new Gtk.FileChooserDialog (Catalog.GetString ("Open Palette File"), PintaCore.Chrome.MainWindow,
347 FileChooserAction.Open, Gtk.Stock.Cancel, Gtk.ResponseType.Cancel,
348 Gtk.Stock.Open, Gtk.ResponseType.Ok);
349
350 FileFilter ff = new FileFilter ();
351 ff.AddPattern ("*.txt");
352 ff.AddPattern ("*.gpl");
353 ff.Name = Catalog.GetString ("Palette files (*.txt, *.gpl)");
354 fcd.AddFilter (ff);
355
356 FileFilter ff2 = new FileFilter ();
357 ff2.Name = Catalog.GetString ("All files");
358 ff2.AddPattern ("*.*");
359 fcd.AddFilter (ff2);
360
361 fcd.AlternativeButtonOrder = new int[] { (int) ResponseType.Ok, (int) ResponseType.Cancel };
362
363 if (lastPaletteDir != null)
364 fcd.SetCurrentFolder (lastPaletteDir);
365
366 int response = fcd.Run ();
367
368 if (response == (int) Gtk.ResponseType.Ok) {
369 try {
370 lastPaletteDir = fcd.CurrentFolder;
371 PintaCore.Palette.CurrentPalette.Load (fcd.Filename);
372 } catch {
373 MessageDialog md = new MessageDialog (PintaCore.Chrome.MainWindow, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, Catalog.GetString ("Could not open palette file: {0}.\nPlease verify that you are trying to open a valid GIMP or Paint.NET palette."), fcd.Filename);
374 md.Title = Catalog.GetString ("Error");
375
376 md.Run ();
377 md.Destroy ();
378 }
379 }
380
381 fcd.Destroy ();
382 }
383
384 private void HandlerPintaCoreActionsEditSavePaletteActivated (object sender, EventArgs e)
385 {
386 var fcd = new Gtk.FileChooserDialog (Catalog.GetString ("Save Palette File"), PintaCore.Chrome.MainWindow,
387 FileChooserAction.Save, Gtk.Stock.Cancel, Gtk.ResponseType.Cancel,
388 Gtk.Stock.Save, Gtk.ResponseType.Ok);
389
390 FileFilter ffPDN = new FileFilter ();
391 ffPDN.AddPattern ("*.txt");
392 ffPDN.Name = Catalog.GetString ("Paint.NET palette (*.txt)");
393 fcd.AddFilter (ffPDN);
394
395 FileFilter ffGIMP = new FileFilter ();
396 ffGIMP.AddPattern ("*.gpl");
397 ffGIMP.Name = Catalog.GetString ("GIMP palette (*.gpl)");
398 fcd.AddFilter (ffGIMP);
399
400 fcd.AlternativeButtonOrder = new int[] { (int) ResponseType.Ok, (int) ResponseType.Cancel };
401
402 if (lastPaletteDir != null)
403 fcd.SetCurrentFolder (lastPaletteDir);
404
405 int response = fcd.Run ();
406
407 if (response == (int) Gtk.ResponseType.Ok) {
408 Palette.FileFormat format = (fcd.Filter == ffPDN) ? Palette.FileFormat.PDN : Palette.FileFormat.GIMP;
409 PintaCore.Palette.CurrentPalette.Save (fcd.Filename, format);
410 }
411
412 fcd.Destroy ();
413 }
414
415 private void HandlerPintaCoreActionsEditResetPaletteActivated (object sender, EventArgs e)
416 {
417 PintaCore.Palette.CurrentPalette.LoadDefault ();
418 }
419
420 private void WorkspaceActiveDocumentChanged (object sender, EventArgs e)
421 {
422 if (!PintaCore.Workspace.HasOpenDocuments) {
423 Undo.Sensitive = false;
424 Redo.Sensitive = false;
425 return;
426 }
427
428 Redo.Sensitive = PintaCore.Workspace.ActiveWorkspace.History.CanRedo;
429 Undo.Sensitive = PintaCore.Workspace.ActiveWorkspace.History.CanUndo;
430 }
431 #endregion
432 }
433}
0434
=== added file 'Pinta.Core/Actions/EffectsActions.cs'
--- Pinta.Core/Actions/EffectsActions.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Actions/EffectsActions.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,93 @@
1//
2// EffectsActions.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using Gtk;
29using System.Collections.Generic;
30
31namespace Pinta.Core
32{
33 public class EffectsActions
34 {
35 private Menu effects_menu;
36 private Dictionary<Gtk.Action, MenuItem> menu_items;
37
38 public Dictionary<string, Gtk.Menu> Menus { get; private set; }
39 public List<Gtk.Action> Actions { get; private set; }
40
41 public EffectsActions ()
42 {
43 Actions = new List<Gtk.Action> ();
44 Menus = new Dictionary<string,Menu> ();
45 menu_items = new Dictionary<Gtk.Action, MenuItem> ();
46 }
47
48 #region Initialization
49 public void CreateMainMenu (Gtk.Menu menu)
50 {
51 effects_menu = menu;
52 }
53
54 public void AddEffect (string category, Gtk.Action action)
55 {
56 if (!Menus.ContainsKey (category)) {
57 Gtk.Action menu_action = new Gtk.Action (category, Mono.Unix.Catalog.GetString (category), null, null);
58 Menu category_menu = (Menu)effects_menu.AppendMenuItemSorted ((MenuItem)(menu_action.CreateSubMenuItem ())).Submenu;
59
60 Menus.Add (category, category_menu);
61 }
62
63 Actions.Add (action);
64 var menu_item = (MenuItem)action.CreateMenuItem ();
65
66 Menu m = Menus[category];
67 m.AppendMenuItemSorted (menu_item);
68
69 menu_items.Add (action, menu_item);
70 }
71
72 // TODO: Remove menu category if empty
73 internal void RemoveEffect (string category, Gtk.Action action)
74 {
75 if (!Menus.ContainsKey (category))
76 return;
77 if (!menu_items.ContainsKey (action))
78 return;
79
80 var menu = Menus[category];
81 menu.Remove (menu_items[action]);
82 }
83 #endregion
84
85 #region Public Methods
86 public void ToggleActionsSensitive (bool sensitive)
87 {
88 foreach (Gtk.Action a in Actions)
89 a.Sensitive = sensitive;
90 }
91 #endregion
92 }
93}
094
=== added file 'Pinta.Core/Actions/FileActions.cs'
--- Pinta.Core/Actions/FileActions.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Actions/FileActions.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,131 @@
1//
2// FileActions.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using System.Collections.Generic;
29using System.IO;
30using Gdk;
31using Gtk;
32using Mono.Unix;
33
34namespace Pinta.Core
35{
36 public class FileActions
37 {
38 public Gtk.Action New { get; private set; }
39 public Gtk.Action NewScreenshot { get; private set; }
40 public Gtk.Action Open { get; private set; }
41 public Gtk.RecentAction OpenRecent { get; private set; }
42 public Gtk.Action Close { get; private set; }
43 public Gtk.Action Save { get; private set; }
44 public Gtk.Action SaveAs { get; private set; }
45 public Gtk.Action Print { get; private set; }
46 public Gtk.Action Exit { get; private set; }
47
48 public event EventHandler BeforeQuit;
49 public event EventHandler<ModifyCompressionEventArgs> ModifyCompression;
50 public event EventHandler<DocumentCancelEventArgs> SaveDocument;
51
52 public FileActions ()
53 {
54 New = new Gtk.Action ("New", Catalog.GetString ("New..."), null, Stock.New);
55 NewScreenshot = new Gtk.Action ("NewScreenshot", Catalog.GetString ("New Screenshot..."), null, Stock.Fullscreen);
56 Open = new Gtk.Action ("Open", Catalog.GetString ("Open..."), null, Stock.Open);
57 OpenRecent = new RecentAction ("OpenRecent", Catalog.GetString ("Open Recent"), null, Stock.Open, RecentManager.Default);
58
59 RecentFilter recentFilter = new RecentFilter ();
60 recentFilter.AddApplication ("Pinta");
61
62 (OpenRecent as RecentAction).AddFilter (recentFilter);
63
64 Close = new Gtk.Action ("Close", Catalog.GetString ("Close"), null, Stock.Close);
65 Save = new Gtk.Action ("Save", Catalog.GetString ("Save"), null, Stock.Save);
66 SaveAs = new Gtk.Action ("SaveAs", Catalog.GetString ("Save As..."), null, Stock.SaveAs);
67 Print = new Gtk.Action ("Print", Catalog.GetString ("Print"), null, Stock.Print);
68 Exit = new Gtk.Action ("Exit", Catalog.GetString ("Quit"), null, Stock.Quit);
69
70 New.ShortLabel = Catalog.GetString ("New");
71 Open.ShortLabel = Catalog.GetString ("Open");
72 Open.IsImportant = true;
73 Save.IsImportant = true;
74
75 Close.Sensitive = false;
76 Print.Sensitive = false;
77 }
78
79 #region Initialization
80 public void CreateMainMenu (Gtk.Menu menu)
81 {
82 menu.Append (New.CreateAcceleratedMenuItem (Gdk.Key.N, Gdk.ModifierType.ControlMask));
83 menu.Append (NewScreenshot.CreateMenuItem ());
84 menu.Append (Open.CreateAcceleratedMenuItem (Gdk.Key.O, Gdk.ModifierType.ControlMask));
85 menu.Append (OpenRecent.CreateMenuItem ());
86 menu.AppendSeparator ();
87 menu.Append (Save.CreateAcceleratedMenuItem (Gdk.Key.S, Gdk.ModifierType.ControlMask));
88 menu.Append (SaveAs.CreateAcceleratedMenuItem (Gdk.Key.S, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
89 menu.AppendSeparator ();
90 //menu.Append (Print.CreateAcceleratedMenuItem (Gdk.Key.P, Gdk.ModifierType.ControlMask));
91 //menu.AppendSeparator ();
92 menu.Append (Close.CreateAcceleratedMenuItem (Gdk.Key.W, Gdk.ModifierType.ControlMask));
93 menu.Append (Exit.CreateAcceleratedMenuItem (Gdk.Key.Q, Gdk.ModifierType.ControlMask));
94 }
95
96 public void RegisterHandlers ()
97 {
98 }
99 #endregion
100
101 #region Event Invokers
102 public void RaiseBeforeQuit ()
103 {
104 if (BeforeQuit != null)
105 BeforeQuit (this, EventArgs.Empty);
106 }
107
108 internal bool RaiseSaveDocument (Document document, bool saveAs)
109 {
110 DocumentCancelEventArgs e = new DocumentCancelEventArgs (document, saveAs);
111
112 if (SaveDocument == null)
113 throw new InvalidOperationException ("GUI is not handling PintaCore.Workspace.SaveDocument");
114 else
115 SaveDocument (this, e);
116
117 return !e.Cancel;
118 }
119
120 internal int RaiseModifyCompression (int defaultCompression)
121 {
122 ModifyCompressionEventArgs e = new ModifyCompressionEventArgs (defaultCompression);
123
124 if (ModifyCompression != null)
125 ModifyCompression (this, e);
126
127 return e.Cancel ? -1 : e.Quality;
128 }
129 #endregion
130 }
131}
0132
=== added file 'Pinta.Core/Actions/HelpActions.cs'
--- Pinta.Core/Actions/HelpActions.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Actions/HelpActions.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,93 @@
1//
2// HelpActions.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using System.Diagnostics;
29using System.Reflection;
30using Gtk;
31using Mono.Unix;
32
33namespace Pinta.Core
34{
35 public class HelpActions
36 {
37 public Gtk.Action ExtensionManager { get; private set; }
38 public Gtk.Action Website { get; private set; }
39 public Gtk.Action Bugs { get; private set; }
40 public Gtk.Action Translate { get; private set; }
41 public Gtk.Action About { get; private set; }
42
43 public HelpActions ()
44 {
45 Gtk.IconFactory fact = new Gtk.IconFactory ();
46 fact.Add ("Menu.Help.Bug.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Help.Bug.png")));
47 fact.Add ("Menu.Help.Website.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Help.Website.png")));
48 fact.Add ("Menu.Help.Translate.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Help.Translate.png")));
49 fact.Add ("Menu.Help.Extensions.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Help.Extensions.png")));
50 fact.AddDefault ();
51
52 ExtensionManager = new Gtk.Action ("ExtensionManager", Catalog.GetString ("Extension Manager"), null, "Menu.Help.Extensions.png");
53 Website = new Gtk.Action ("Website", Catalog.GetString ("Pinta Website"), null, "Menu.Help.Website.png");
54 Bugs = new Gtk.Action ("Bugs", Catalog.GetString ("File a Bug"), null, "Menu.Help.Bug.png");
55 Translate = new Gtk.Action ("Translate", Catalog.GetString ("Translate This Application"), null, "Menu.Help.Translate.png");
56 About = new Gtk.Action ("About", Catalog.GetString ("About"), null, Stock.About);
57 }
58
59 #region Initialization
60 public void CreateMainMenu (Gtk.Menu menu)
61 {
62 menu.Append (ExtensionManager.CreateMenuItem ());
63 menu.Append (Website.CreateMenuItem ());
64 menu.Append (Bugs.CreateMenuItem ());
65 menu.Append (Translate.CreateMenuItem ());
66 menu.AppendSeparator ();
67 menu.Append (About.CreateMenuItem ());
68 }
69
70 public void RegisterHandlers ()
71 {
72 Website.Activated += new EventHandler (Website_Activated);
73 Bugs.Activated += new EventHandler (Bugs_Activated);
74 Translate.Activated += Translate_Activated;
75 }
76
77 private void Bugs_Activated (object sender, EventArgs e)
78 {
79 Process.Start ("https://bugs.launchpad.net/pinta");
80 }
81
82 private void Translate_Activated (object sender, EventArgs e)
83 {
84 Process.Start ("https://translations.launchpad.net/pinta");
85 }
86
87 private void Website_Activated (object sender, EventArgs e)
88 {
89 Process.Start ("http://www.pinta-project.com");
90 }
91 #endregion
92 }
93}
094
=== added file 'Pinta.Core/Actions/ImageActions.cs'
--- Pinta.Core/Actions/ImageActions.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Actions/ImageActions.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,301 @@
1//
2// ImageActions.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using Mono.Unix;
29
30namespace Pinta.Core
31{
32 public class ImageActions
33 {
34 public Gtk.Action CropToSelection { get; private set; }
35 public Gtk.Action AutoCrop { get; private set; }
36 public Gtk.Action Resize { get; private set; }
37 public Gtk.Action CanvasSize { get; private set; }
38 public Gtk.Action FlipHorizontal { get; private set; }
39 public Gtk.Action FlipVertical { get; private set; }
40 public Gtk.Action RotateCW { get; private set; }
41 public Gtk.Action RotateCCW { get; private set; }
42 public Gtk.Action Rotate180 { get; private set; }
43 public Gtk.Action Flatten { get; private set; }
44
45 public ImageActions ()
46 {
47 Gtk.IconFactory fact = new Gtk.IconFactory ();
48 fact.Add ("Menu.Image.CanvasSize.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.CanvasSize.png")));
49 fact.Add ("Menu.Image.Crop.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.Crop.png")));
50 fact.Add ("Menu.Image.Flatten.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.Flatten.png")));
51 fact.Add ("Menu.Image.FlipHorizontal.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.FlipHorizontal.png")));
52 fact.Add ("Menu.Image.FlipVertical.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.FlipVertical.png")));
53 fact.Add ("Menu.Image.Resize.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.Resize.png")));
54 fact.Add ("Menu.Image.Rotate180CW.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.Rotate180CW.png")));
55 fact.Add ("Menu.Image.Rotate90CCW.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.Rotate90CCW.png")));
56 fact.Add ("Menu.Image.Rotate90CW.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Image.Rotate90CW.png")));
57 fact.AddDefault ();
58
59 CropToSelection = new Gtk.Action ("CropToSelection", Catalog.GetString ("Crop to Selection"), null, "Menu.Image.Crop.png");
60 AutoCrop = new Gtk.Action ("AutoCrop", Catalog.GetString ("Auto Crop"), null, "Menu.Image.Crop.png");
61 Resize = new Gtk.Action ("Resize", Catalog.GetString ("Resize Image..."), null, "Menu.Image.Resize.png");
62 CanvasSize = new Gtk.Action ("CanvasSize", Catalog.GetString ("Resize Canvas..."), null, "Menu.Image.CanvasSize.png");
63 FlipHorizontal = new Gtk.Action ("FlipHorizontal", Catalog.GetString ("Flip Horizontal"), null, "Menu.Image.FlipHorizontal.png");
64 FlipVertical = new Gtk.Action ("FlipVertical", Catalog.GetString ("Flip Vertical"), null, "Menu.Image.FlipVertical.png");
65 RotateCW = new Gtk.Action ("RotateCW", Catalog.GetString ("Rotate 90° Clockwise"), null, "Menu.Image.Rotate90CW.png");
66 RotateCCW = new Gtk.Action ("RotateCCW", Catalog.GetString ("Rotate 90° Counter-Clockwise"), null, "Menu.Image.Rotate90CCW.png");
67 Rotate180 = new Gtk.Action ("Rotate180", Catalog.GetString ("Rotate 180°"), null, "Menu.Image.Rotate180CW.png");
68 Flatten = new Gtk.Action ("Flatten", Catalog.GetString ("Flatten"), null, "Menu.Image.Flatten.png");
69
70 CropToSelection.Sensitive = false;
71 }
72
73 #region Initialization
74 public void CreateMainMenu (Gtk.Menu menu)
75 {
76 menu.Append (CropToSelection.CreateAcceleratedMenuItem (Gdk.Key.X, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
77 menu.Append (AutoCrop.CreateAcceleratedMenuItem (Gdk.Key.X, Gdk.ModifierType.Mod1Mask | Gdk.ModifierType.ControlMask));
78 menu.Append (Resize.CreateAcceleratedMenuItem (Gdk.Key.R, Gdk.ModifierType.ControlMask));
79 menu.Append (CanvasSize.CreateAcceleratedMenuItem (Gdk.Key.R, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
80 menu.AppendSeparator ();
81 menu.Append (FlipHorizontal.CreateMenuItem ());
82 menu.Append (FlipVertical.CreateMenuItem ());
83 menu.AppendSeparator ();
84 menu.Append (RotateCW.CreateAcceleratedMenuItem (Gdk.Key.H, Gdk.ModifierType.ControlMask));
85 menu.Append (RotateCCW.CreateAcceleratedMenuItem (Gdk.Key.G, Gdk.ModifierType.ControlMask));
86 menu.Append (Rotate180.CreateAcceleratedMenuItem (Gdk.Key.J, Gdk.ModifierType.ControlMask));
87 menu.AppendSeparator ();
88 menu.Append (Flatten.CreateAcceleratedMenuItem (Gdk.Key.F, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
89 }
90
91 public void RegisterHandlers ()
92 {
93 FlipHorizontal.Activated += HandlePintaCoreActionsImageFlipHorizontalActivated;
94 FlipVertical.Activated += HandlePintaCoreActionsImageFlipVerticalActivated;
95 Rotate180.Activated += HandlePintaCoreActionsImageRotate180Activated;
96 Flatten.Activated += HandlePintaCoreActionsImageFlattenActivated;
97 RotateCW.Activated += HandlePintaCoreActionsImageRotateCWActivated;
98 RotateCCW.Activated += HandlePintaCoreActionsImageRotateCCWActivated;
99 CropToSelection.Activated += HandlePintaCoreActionsImageCropToSelectionActivated;
100 AutoCrop.Activated += HandlePintaCoreActionsImageAutoCropActivated;
101 }
102 #endregion
103
104 #region Action Handlers
105 private void HandlePintaCoreActionsImageRotateCCWActivated (object sender, EventArgs e)
106 {
107 Document doc = PintaCore.Workspace.ActiveDocument;
108
109 PintaCore.Tools.Commit ();
110 doc.RotateImageCCW ();
111
112 doc.ResetSelectionPath ();
113
114 doc.History.PushNewItem (new InvertHistoryItem (InvertType.Rotate90CCW));
115 }
116
117 private void HandlePintaCoreActionsImageRotateCWActivated (object sender, EventArgs e)
118 {
119 Document doc = PintaCore.Workspace.ActiveDocument;
120
121 PintaCore.Tools.Commit ();
122 doc.RotateImageCW ();
123
124 doc.ResetSelectionPath ();
125
126 doc.History.PushNewItem (new InvertHistoryItem (InvertType.Rotate90CW));
127 }
128
129 private void HandlePintaCoreActionsImageFlattenActivated (object sender, EventArgs e)
130 {
131 Document doc = PintaCore.Workspace.ActiveDocument;
132
133 PintaCore.Tools.Commit ();
134
135 CompoundHistoryItem hist = new CompoundHistoryItem ("Menu.Image.Flatten.png", Catalog.GetString ("Flatten"));
136 SimpleHistoryItem h1 = new SimpleHistoryItem (string.Empty, string.Empty, doc.Layers[0].Surface.Clone (), 0);
137
138 hist.Push (h1);
139
140 for (int i = 1; i < doc.Layers.Count; i++)
141 hist.Push (new DeleteLayerHistoryItem (string.Empty, string.Empty, doc.Layers[i], i));
142
143 doc.FlattenImage ();
144
145 doc.History.PushNewItem (hist);
146 }
147
148 private void HandlePintaCoreActionsImageRotate180Activated (object sender, EventArgs e)
149 {
150 Document doc = PintaCore.Workspace.ActiveDocument;
151
152 PintaCore.Tools.Commit ();
153 doc.RotateImage180 ();
154
155 doc.ResetSelectionPath ();
156
157 doc.History.PushNewItem (new InvertHistoryItem (InvertType.Rotate180));
158 }
159
160 private void HandlePintaCoreActionsImageFlipVerticalActivated (object sender, EventArgs e)
161 {
162 Document doc = PintaCore.Workspace.ActiveDocument;
163
164 PintaCore.Tools.Commit ();
165 doc.FlipImageVertical ();
166
167 doc.History.PushNewItem (new InvertHistoryItem (InvertType.FlipVertical));
168 }
169
170 private void HandlePintaCoreActionsImageFlipHorizontalActivated (object sender, EventArgs e)
171 {
172 Document doc = PintaCore.Workspace.ActiveDocument;
173
174 PintaCore.Tools.Commit ();
175 doc.FlipImageHorizontal ();
176
177 doc.History.PushNewItem (new InvertHistoryItem (InvertType.FlipHorizontal));
178 }
179
180 private void HandlePintaCoreActionsImageCropToSelectionActivated (object sender, EventArgs e)
181 {
182 Document doc = PintaCore.Workspace.ActiveDocument;
183
184 PintaCore.Tools.Commit ();
185
186 Gdk.Rectangle rect = doc.GetSelectedBounds (true);
187
188 CropImageToRectangle (doc, rect);
189 }
190
191 private void HandlePintaCoreActionsImageAutoCropActivated (object sender, EventArgs e)
192 {
193 Document doc = PintaCore.Workspace.ActiveDocument;
194
195 PintaCore.Tools.Commit ();
196
197 Cairo.ImageSurface image = doc.CurrentLayer.Surface;
198 Gdk.Rectangle rect = image.GetBounds ();
199
200 Cairo.Color borderColor = image.GetPixel (0, 0);
201 bool cropSide = true;
202 int depth = -1;
203
204 //From the top down
205 while (cropSide) {
206 depth++;
207 for (int i = 0; i < image.Width; i++) {
208 if (!borderColor.Equals(image.GetPixel (i, depth))) {
209 cropSide = false;
210 break;
211 }
212 }
213 //Check if the image is blank/mono-coloured, only need to do it on this scan
214 if (depth == image.Height)
215 return;
216 }
217
218 rect = new Gdk.Rectangle (rect.X, rect.Y + depth, rect.Width, rect.Height - depth);
219
220 depth = image.Height;
221 cropSide = true;
222 //From the bottom up
223 while (cropSide) {
224 depth--;
225 for (int i = 0; i < image.Width; i++) {
226 if (!borderColor.Equals(image.GetPixel (i, depth))) {
227 cropSide = false;
228 break;
229 }
230 }
231
232 }
233
234 rect = new Gdk.Rectangle (rect.X, rect.Y, rect.Width, depth - rect.Y);
235
236 depth = 0;
237 cropSide = true;
238 //From left to right
239 while (cropSide) {
240 depth++;
241 for (int i = 0; i < image.Height; i++) {
242 if (!borderColor.Equals(image.GetPixel (depth, i))) {
243 cropSide = false;
244 break;
245 }
246 }
247
248 }
249
250 rect = new Gdk.Rectangle (rect.X + depth, rect.Y, rect.Width - depth, rect.Height);
251
252 depth = image.Width;
253 cropSide = true;
254 //From right to left
255 while (cropSide) {
256 depth--;
257 for (int i = 0; i < image.Height; i++) {
258 if (!borderColor.Equals(image.GetPixel (depth, i))) {
259 cropSide = false;
260 break;
261 }
262 }
263
264 }
265
266 rect = new Gdk.Rectangle (rect.X, rect.Y, depth - rect.X, rect.Height);
267
268 CropImageToRectangle (doc, rect);
269 }
270 #endregion
271
272 static void CropImageToRectangle (Document doc, Gdk.Rectangle rect)
273 {
274 ResizeHistoryItem hist = new ResizeHistoryItem (doc.ImageSize);
275
276 hist.Icon = "Menu.Image.Crop.png";
277 hist.Text = Catalog.GetString ("Crop to Selection");
278 hist.TakeSnapshotOfImage ();
279 hist.RestorePath = doc.SelectionPath.Clone ();
280
281 PintaCore.Chrome.Canvas.GdkWindow.FreezeUpdates ();
282
283 double original_scale = doc.Workspace.Scale;
284 doc.ImageSize = rect.Size;
285 doc.Workspace.CanvasSize = rect.Size;
286 doc.Workspace.Scale = original_scale;
287
288 PintaCore.Actions.View.UpdateCanvasScale ();
289
290 PintaCore.Chrome.Canvas.GdkWindow.ThawUpdates ();
291
292 foreach (var layer in doc.Layers)
293 layer.Crop (rect, doc.SelectionPath);
294
295 doc.History.PushNewItem (hist);
296 doc.ResetSelectionPath ();
297
298 doc.Workspace.Invalidate ();
299 }
300 }
301}
0302
=== added file 'Pinta.Core/Actions/LayerActions.cs'
--- Pinta.Core/Actions/LayerActions.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Actions/LayerActions.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,292 @@
1//
2// LayerActions.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using Gdk;
29using Gtk;
30using Mono.Unix;
31using System.IO;
32
33namespace Pinta.Core
34{
35 public class LayerActions
36 {
37 public Gtk.Action AddNewLayer { get; private set; }
38 public Gtk.Action DeleteLayer { get; private set; }
39 public Gtk.Action DuplicateLayer { get; private set; }
40 public Gtk.Action MergeLayerDown { get; private set; }
41 public Gtk.Action ImportFromFile { get; private set; }
42 public Gtk.Action FlipHorizontal { get; private set; }
43 public Gtk.Action FlipVertical { get; private set; }
44 public Gtk.Action RotateZoom { get; private set; }
45 public Gtk.Action MoveLayerUp { get; private set; }
46 public Gtk.Action MoveLayerDown { get; private set; }
47 public Gtk.Action Properties { get; private set; }
48
49 public LayerActions ()
50 {
51 Gtk.IconFactory fact = new Gtk.IconFactory ();
52 fact.Add ("Menu.Layers.AddNewLayer.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.AddNewLayer.png")));
53 fact.Add ("Menu.Layers.DeleteLayer.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.DeleteLayer.png")));
54 fact.Add ("Menu.Layers.DuplicateLayer.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.DuplicateLayer.png")));
55 fact.Add ("Menu.Layers.MergeLayerDown.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.MergeLayerDown.png")));
56 fact.Add ("Menu.Layers.MoveLayerDown.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.MoveLayerDown.png")));
57 fact.Add ("Menu.Layers.MoveLayerUp.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.MoveLayerUp.png")));
58 fact.Add ("Menu.Layers.FlipHorizontal.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.FlipHorizontal.png")));
59 fact.Add ("Menu.Layers.FlipVertical.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.FlipVertical.png")));
60 fact.Add ("Menu.Layers.ImportFromFile.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.ImportFromFile.png")));
61 fact.Add ("Menu.Layers.LayerProperties.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.LayerProperties.png")));
62 fact.Add ("Menu.Layers.RotateZoom.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.Layers.RotateZoom.png")));
63 fact.AddDefault ();
64
65 AddNewLayer = new Gtk.Action ("AddNewLayer", Catalog.GetString ("Add New Layer"), null, "Menu.Layers.AddNewLayer.png");
66 DeleteLayer = new Gtk.Action ("DeleteLayer", Catalog.GetString ("Delete Layer"), null, "Menu.Layers.DeleteLayer.png");
67 DuplicateLayer = new Gtk.Action ("DuplicateLayer", Catalog.GetString ("Duplicate Layer"), null, "Menu.Layers.DuplicateLayer.png");
68 MergeLayerDown = new Gtk.Action ("MergeLayerDown", Catalog.GetString ("Merge Layer Down"), null, "Menu.Layers.MergeLayerDown.png");
69 ImportFromFile = new Gtk.Action ("ImportFromFile", Catalog.GetString ("Import from File..."), null, "Menu.Layers.ImportFromFile.png");
70 FlipHorizontal = new Gtk.Action ("FlipHorizontal", Catalog.GetString ("Flip Horizontal"), null, "Menu.Layers.FlipHorizontal.png");
71 FlipVertical = new Gtk.Action ("FlipVertical", Catalog.GetString ("Flip Vertical"), null, "Menu.Layers.FlipVertical.png");
72 RotateZoom = new Gtk.Action ("RotateZoom", Catalog.GetString ("Rotate / Zoom Layer..."), null, "Menu.Layers.RotateZoom.png");
73 MoveLayerUp = new Gtk.Action ("MoveLayerUp", Catalog.GetString ("Move Layer Up"), null, "Menu.Layers.MoveLayerUp.png");
74 MoveLayerDown = new Gtk.Action ("MoveLayerDown", Catalog.GetString ("Move Layer Down"), null, "Menu.Layers.MoveLayerDown.png");
75 Properties = new Gtk.Action ("Properties", Catalog.GetString ("Layer Properties..."), null, "Menu.Layers.LayerProperties.png");
76
77 RotateZoom.Sensitive = false;
78 }
79
80 #region Initialization
81 public void CreateMainMenu (Gtk.Menu menu)
82 {
83 menu.Append (AddNewLayer.CreateAcceleratedMenuItem (Gdk.Key.N, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
84 menu.Append (DeleteLayer.CreateAcceleratedMenuItem (Gdk.Key.Delete, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
85 menu.Append (DuplicateLayer.CreateAcceleratedMenuItem (Gdk.Key.D, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
86 menu.Append (MergeLayerDown.CreateAcceleratedMenuItem (Gdk.Key.M, Gdk.ModifierType.ControlMask));
87 menu.Append (ImportFromFile.CreateMenuItem ());
88 menu.AppendSeparator ();
89 menu.Append (FlipHorizontal.CreateMenuItem ());
90 menu.Append (FlipVertical.CreateMenuItem ());
91 menu.Append (RotateZoom.CreateMenuItem ());
92 menu.AppendSeparator ();
93 menu.Append (Properties.CreateAcceleratedMenuItem (Gdk.Key.F4, Gdk.ModifierType.None));
94 }
95
96 public void CreateLayerWindowToolBar (Gtk.Toolbar toolbar)
97 {
98 toolbar.AppendItem (AddNewLayer.CreateToolBarItem ());
99 toolbar.AppendItem (DeleteLayer.CreateToolBarItem ());
100 toolbar.AppendItem (DuplicateLayer.CreateToolBarItem ());
101 toolbar.AppendItem (MergeLayerDown.CreateToolBarItem ());
102 toolbar.AppendItem (MoveLayerUp.CreateToolBarItem ());
103 toolbar.AppendItem (MoveLayerDown.CreateToolBarItem ());
104 toolbar.AppendItem (Properties.CreateToolBarItem ());
105 }
106
107 public void RegisterHandlers ()
108 {
109 AddNewLayer.Activated += HandlePintaCoreActionsLayersAddNewLayerActivated;
110 DeleteLayer.Activated += HandlePintaCoreActionsLayersDeleteLayerActivated;
111 DuplicateLayer.Activated += HandlePintaCoreActionsLayersDuplicateLayerActivated;
112 MergeLayerDown.Activated += HandlePintaCoreActionsLayersMergeLayerDownActivated;
113 MoveLayerDown.Activated += HandlePintaCoreActionsLayersMoveLayerDownActivated;
114 MoveLayerUp.Activated += HandlePintaCoreActionsLayersMoveLayerUpActivated;
115 FlipHorizontal.Activated += HandlePintaCoreActionsLayersFlipHorizontalActivated;
116 FlipVertical.Activated += HandlePintaCoreActionsLayersFlipVerticalActivated;
117 ImportFromFile.Activated += HandlePintaCoreActionsLayersImportFromFileActivated;
118
119 PintaCore.Layers.LayerAdded += EnableOrDisableLayerActions;
120 PintaCore.Layers.LayerRemoved += EnableOrDisableLayerActions;
121 PintaCore.Layers.SelectedLayerChanged += EnableOrDisableLayerActions;
122
123 EnableOrDisableLayerActions (null, EventArgs.Empty);
124 }
125 #endregion
126
127 #region Action Handlers
128 private void EnableOrDisableLayerActions (object sender, EventArgs e)
129 {
130 if (PintaCore.Workspace.HasOpenDocuments && PintaCore.Workspace.ActiveDocument.Layers.Count > 1) {
131 PintaCore.Actions.Layers.DeleteLayer.Sensitive = true;
132 PintaCore.Actions.Image.Flatten.Sensitive = true;
133 } else {
134 PintaCore.Actions.Layers.DeleteLayer.Sensitive = false;
135 PintaCore.Actions.Image.Flatten.Sensitive = false;
136 }
137
138 if (PintaCore.Workspace.HasOpenDocuments && PintaCore.Workspace.ActiveDocument.CurrentLayerIndex > 0) {
139 PintaCore.Actions.Layers.MergeLayerDown.Sensitive = true;
140 PintaCore.Actions.Layers.MoveLayerDown.Sensitive = true;
141 } else {
142 PintaCore.Actions.Layers.MergeLayerDown.Sensitive = false;
143 PintaCore.Actions.Layers.MoveLayerDown.Sensitive = false;
144 }
145
146 if (PintaCore.Workspace.HasOpenDocuments && PintaCore.Workspace.ActiveDocument.CurrentLayerIndex < PintaCore.Workspace.ActiveDocument.Layers.Count - 1)
147 PintaCore.Actions.Layers.MoveLayerUp.Sensitive = true;
148 else
149 PintaCore.Actions.Layers.MoveLayerUp.Sensitive = false;
150 }
151
152 private void HandlePintaCoreActionsLayersImportFromFileActivated (object sender, EventArgs e)
153 {
154 Document doc = PintaCore.Workspace.ActiveDocument;
155 PintaCore.Tools.Commit ();
156
157 Gtk.FileChooserDialog fcd = new Gtk.FileChooserDialog (Catalog.GetString ("Open Image File"), null, FileChooserAction.Open, Gtk.Stock.Cancel, Gtk.ResponseType.Cancel, Gtk.Stock.Open, Gtk.ResponseType.Ok);
158
159 fcd.SetCurrentFolder (PintaCore.System.LastDialogDirectory);
160 fcd.AlternativeButtonOrder = new int[] { (int) ResponseType.Ok, (int) ResponseType.Cancel };
161
162 fcd.AddImagePreview ();
163
164 int response = fcd.Run ();
165
166 if (response == (int)Gtk.ResponseType.Ok) {
167
168 string file = fcd.Filename;
169 PintaCore.System.LastDialogDirectory = fcd.CurrentFolder;
170
171 // Open the image and add it to the layers
172 Layer layer = doc.AddNewLayer (System.IO.Path.GetFileName (file));
173
174 using (var fs = new FileStream (file, FileMode.Open))
175 using (Pixbuf bg = new Pixbuf (fs))
176 using (Cairo.Context g = new Cairo.Context (layer.Surface)) {
177 CairoHelper.SetSourcePixbuf (g, bg, 0, 0);
178 g.Paint ();
179 }
180
181 doc.SetCurrentLayer (layer);
182
183 AddLayerHistoryItem hist = new AddLayerHistoryItem ("Menu.Layers.ImportFromFile.png", Catalog.GetString ("Import From File"), doc.Layers.IndexOf (layer));
184 doc.History.PushNewItem (hist);
185
186 doc.Workspace.Invalidate ();
187 }
188
189 fcd.Destroy ();
190 }
191
192 private void HandlePintaCoreActionsLayersFlipVerticalActivated (object sender, EventArgs e)
193 {
194 Document doc = PintaCore.Workspace.ActiveDocument;
195 PintaCore.Tools.Commit ();
196
197 doc.CurrentLayer.FlipVertical ();
198 doc.Workspace.Invalidate ();
199 doc.History.PushNewItem (new InvertHistoryItem (InvertType.FlipLayerVertical, doc.CurrentLayerIndex));
200 }
201
202 private void HandlePintaCoreActionsLayersFlipHorizontalActivated (object sender, EventArgs e)
203 {
204 Document doc = PintaCore.Workspace.ActiveDocument;
205 PintaCore.Tools.Commit ();
206
207 doc.CurrentLayer.FlipHorizontal ();
208 doc.Workspace.Invalidate ();
209 doc.History.PushNewItem (new InvertHistoryItem (InvertType.FlipLayerHorizontal, doc.CurrentLayerIndex));
210 }
211
212 private void HandlePintaCoreActionsLayersMoveLayerUpActivated (object sender, EventArgs e)
213 {
214 Document doc = PintaCore.Workspace.ActiveDocument;
215 PintaCore.Tools.Commit ();
216
217 SwapLayersHistoryItem hist = new SwapLayersHistoryItem ("Menu.Layers.MoveLayerUp.png", Catalog.GetString ("Move Layer Up"), doc.CurrentLayerIndex, doc.CurrentLayerIndex + 1);
218
219 doc.MoveCurrentLayerUp ();
220 doc.History.PushNewItem (hist);
221 }
222
223 private void HandlePintaCoreActionsLayersMoveLayerDownActivated (object sender, EventArgs e)
224 {
225 Document doc = PintaCore.Workspace.ActiveDocument;
226 PintaCore.Tools.Commit ();
227
228 SwapLayersHistoryItem hist = new SwapLayersHistoryItem ("Menu.Layers.MoveLayerDown.png", Catalog.GetString ("Move Layer Down"), doc.CurrentLayerIndex, doc.CurrentLayerIndex - 1);
229
230 doc.MoveCurrentLayerDown ();
231 doc.History.PushNewItem (hist);
232 }
233
234 private void HandlePintaCoreActionsLayersMergeLayerDownActivated (object sender, EventArgs e)
235 {
236 Document doc = PintaCore.Workspace.ActiveDocument;
237 PintaCore.Tools.Commit ();
238
239 CompoundHistoryItem hist = new CompoundHistoryItem ("Menu.Layers.MergeLayerDown.png", Catalog.GetString ("Merge Layer Down"));
240 DeleteLayerHistoryItem h1 = new DeleteLayerHistoryItem (string.Empty, string.Empty, doc.CurrentLayer, doc.CurrentLayerIndex);
241 SimpleHistoryItem h2 = new SimpleHistoryItem (string.Empty, string.Empty, doc.Layers[doc.CurrentLayerIndex - 1].Surface.Clone (), doc.CurrentLayerIndex - 1);
242
243 hist.Push (h1);
244 hist.Push (h2);
245
246 doc.MergeCurrentLayerDown ();
247
248 doc.History.PushNewItem (hist);
249 }
250
251 private void HandlePintaCoreActionsLayersDuplicateLayerActivated (object sender, EventArgs e)
252 {
253 Document doc = PintaCore.Workspace.ActiveDocument;
254 PintaCore.Tools.Commit ();
255
256 Layer l = doc.DuplicateCurrentLayer ();
257
258 // Make new layer the current layer
259 doc.SetCurrentLayer (l);
260
261 AddLayerHistoryItem hist = new AddLayerHistoryItem ("Menu.Layers.DuplicateLayer.png", Catalog.GetString ("Duplicate Layer"), doc.Layers.IndexOf (l));
262 doc.History.PushNewItem (hist);
263 }
264
265 private void HandlePintaCoreActionsLayersDeleteLayerActivated (object sender, EventArgs e)
266 {
267 Document doc = PintaCore.Workspace.ActiveDocument;
268 PintaCore.Tools.Commit ();
269
270 DeleteLayerHistoryItem hist = new DeleteLayerHistoryItem ("Menu.Layers.DeleteLayer.png", Catalog.GetString ("Delete Layer"), doc.CurrentLayer, doc.CurrentLayerIndex);
271
272 doc.DeleteLayer (doc.CurrentLayerIndex, false);
273
274 doc.History.PushNewItem (hist);
275 }
276
277 private void HandlePintaCoreActionsLayersAddNewLayerActivated (object sender, EventArgs e)
278 {
279 Document doc = PintaCore.Workspace.ActiveDocument;
280 PintaCore.Tools.Commit ();
281
282 Layer l = doc.AddNewLayer (string.Empty);
283
284 // Make new layer the current layer
285 doc.SetCurrentLayer (l);
286
287 AddLayerHistoryItem hist = new AddLayerHistoryItem ("Menu.Layers.AddNewLayer.png", Catalog.GetString ("Add New Layer"), doc.Layers.IndexOf (l));
288 doc.History.PushNewItem (hist);
289 }
290 #endregion
291 }
292}
0293
=== added file 'Pinta.Core/Actions/ViewActions.cs'
--- Pinta.Core/Actions/ViewActions.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Actions/ViewActions.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,276 @@
1//
2// ViewActions.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using Mono.Unix;
29using Gtk;
30
31namespace Pinta.Core
32{
33 public class ViewActions
34 {
35 public Gtk.Action ZoomIn { get; private set; }
36 public Gtk.Action ZoomOut { get; private set; }
37 public Gtk.Action ZoomToWindow { get; private set; }
38 public Gtk.Action ZoomToSelection { get; private set; }
39 public Gtk.Action ActualSize { get; private set; }
40 public Gtk.ToggleAction ToolBar { get; private set; }
41 public Gtk.ToggleAction PixelGrid { get; private set; }
42 public Gtk.ToggleAction Rulers { get; private set; }
43 public Gtk.RadioAction Pixels { get; private set; }
44 public Gtk.RadioAction Inches { get; private set; }
45 public Gtk.RadioAction Centimeters { get; private set; }
46 public Gtk.Action Fullscreen { get; private set; }
47
48 public ToolBarComboBox ZoomComboBox { get; private set; }
49 public string[] ZoomCollection { get; private set; }
50
51 private string old_zoom_text = "";
52 private bool zoom_to_window_activated = false;
53
54 public bool ZoomToWindowActivated {
55 get { return zoom_to_window_activated; }
56 set
57 {
58 zoom_to_window_activated = value;
59 old_zoom_text = ZoomComboBox.ComboBox.ActiveText;
60 }
61 }
62
63 public ViewActions ()
64 {
65 Gtk.IconFactory fact = new Gtk.IconFactory ();
66 fact.Add ("Menu.View.ActualSize.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.ActualSize.png")));
67 fact.Add ("Menu.View.Grid.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.Grid.png")));
68 fact.Add ("Menu.View.Rulers.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.Rulers.png")));
69 fact.Add ("Menu.View.ZoomIn.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.ZoomIn.png")));
70 fact.Add ("Menu.View.ZoomOut.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.ZoomOut.png")));
71 fact.Add ("Menu.View.ZoomToSelection.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.ZoomToSelection.png")));
72 fact.Add ("Menu.View.ZoomToWindow.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Menu.View.ZoomToWindow.png")));
73 fact.AddDefault ();
74
75 ZoomIn = new Gtk.Action ("ZoomIn", Catalog.GetString ("Zoom In"), null, Stock.ZoomIn);
76 ZoomOut = new Gtk.Action ("ZoomOut", Catalog.GetString ("Zoom Out"), null, Stock.ZoomOut);
77 ZoomToWindow = new Gtk.Action ("ZoomToWindow", Catalog.GetString ("Best Fit"), null, Stock.ZoomFit);
78 ZoomToSelection = new Gtk.Action ("ZoomToSelection", Catalog.GetString ("Zoom to Selection"), null, "Menu.View.ZoomToSelection.png");
79 ActualSize = new Gtk.Action ("ActualSize", Catalog.GetString ("Normal Size"), null, Stock.Zoom100);
80 ToolBar = new Gtk.ToggleAction ("Toolbar", Catalog.GetString ("Toolbar"), null, null);
81 PixelGrid = new Gtk.ToggleAction ("PixelGrid", Catalog.GetString ("Pixel Grid"), null, "Menu.View.Grid.png");
82 Rulers = new Gtk.ToggleAction ("Rulers", Catalog.GetString ("Rulers"), null, "Menu.View.Rulers.png");
83 Pixels = new Gtk.RadioAction ("Pixels", Catalog.GetString ("Pixels"), null, null, 0);
84 Inches = new Gtk.RadioAction ("Inches", Catalog.GetString ("Inches"), null, null, 1);
85 Centimeters = new Gtk.RadioAction ("Centimeters", Catalog.GetString ("Centimeters"), null, null, 2);
86 Fullscreen = new Gtk.Action ("Fullscreen", Catalog.GetString ("Fullscreen"), null, Stock.Fullscreen);
87
88 ZoomCollection = new string[] { "3600%", "2400%", "1600%", "1200%", "800%", "700%", "600%", "500%", "400%", "300%", "200%", "175%", "150%", "125%", "100%", "66%", "50%", "33%", "25%", "16%", "12%", "8%", "5%", Catalog.GetString ("Window") };
89 ZoomComboBox = new ToolBarComboBox (75, DefaultZoomIndex(), true, ZoomCollection);
90
91 // Make sure these are the same group so only one will be selected at a time
92 Inches.Group = Pixels.Group;
93 Centimeters.Group = Pixels.Group;
94 }
95
96 #region Initialization
97 public void CreateMainMenu (Gtk.Menu menu)
98 {
99 MenuItem show_pad = (MenuItem)menu.Children[0];
100 menu.Remove (show_pad);
101
102 menu.Append (ToolBar.CreateMenuItem ());
103 menu.Append (PixelGrid.CreateMenuItem ());
104 menu.Append (Rulers.CreateMenuItem ());
105 menu.AppendSeparator ();
106
107 ImageMenuItem zoomin = ZoomIn.CreateAcceleratedMenuItem (Gdk.Key.plus, Gdk.ModifierType.ControlMask);
108 zoomin.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.equal, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
109 zoomin.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.KP_Add, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
110 menu.Append (zoomin);
111
112 ImageMenuItem zoomout = ZoomOut.CreateAcceleratedMenuItem (Gdk.Key.minus, Gdk.ModifierType.ControlMask);
113 zoomout.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.underscore, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
114 zoomout.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.KP_Subtract, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
115 menu.Append (zoomout);
116
117 ImageMenuItem actualsize = ActualSize.CreateAcceleratedMenuItem (Gdk.Key.Key_0, Gdk.ModifierType.ControlMask);
118 actualsize.AddAccelerator ("activate", PintaCore.Actions.AccelGroup, new AccelKey (Gdk.Key.A, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask, AccelFlags.Visible));
119 menu.Append (actualsize);
120 menu.Append (ZoomToWindow.CreateAcceleratedMenuItem (Gdk.Key.B, Gdk.ModifierType.ControlMask));
121 //menu.Append (ZoomToSelection.CreateAcceleratedMenuItem (Gdk.Key.B, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
122 menu.Append (Fullscreen.CreateAcceleratedMenuItem (Gdk.Key.F11, Gdk.ModifierType.None));
123
124 menu.AppendSeparator ();
125
126 Gtk.Action unit_action = new Gtk.Action ("RulerUnits", Mono.Unix.Catalog.GetString ("Ruler Units"), null, null);
127 Menu unit_menu = (Menu)menu.AppendItem (unit_action.CreateSubMenuItem ()).Submenu;
128 unit_menu.Append (Pixels.CreateMenuItem ());
129 unit_menu.Append (Inches.CreateMenuItem ());
130 unit_menu.Append (Centimeters.CreateMenuItem ());
131
132 menu.AppendSeparator ();
133 menu.Append (show_pad);
134 }
135
136 public void CreateToolBar (Gtk.Toolbar toolbar)
137 {
138 toolbar.AppendItem (new Gtk.SeparatorToolItem ());
139 toolbar.AppendItem (ZoomOut.CreateToolBarItem ());
140 toolbar.AppendItem (ZoomComboBox);
141 toolbar.AppendItem (ZoomIn.CreateToolBarItem ());
142 }
143
144 public void RegisterHandlers ()
145 {
146 ZoomIn.Activated += HandlePintaCoreActionsViewZoomInActivated;
147 ZoomOut.Activated += HandlePintaCoreActionsViewZoomOutActivated;
148 ZoomComboBox.ComboBox.Changed += HandlePintaCoreActionsViewZoomComboBoxComboBoxChanged;
149 (ZoomComboBox.ComboBox as Gtk.ComboBoxEntry).Entry.FocusOutEvent += new Gtk.FocusOutEventHandler (ComboBox_FocusOutEvent);
150 (ZoomComboBox.ComboBox as Gtk.ComboBoxEntry).Entry.FocusInEvent += new Gtk.FocusInEventHandler (Entry_FocusInEvent);
151 ActualSize.Activated += HandlePintaCoreActionsViewActualSizeActivated;
152
153 PixelGrid.Toggled += delegate (object sender, EventArgs e) {
154 PintaCore.Workspace.Invalidate ();
155 };
156
157 var isFullscreen = false;
158
159 Fullscreen.Activated += (foo, bar) => {
160 if (!isFullscreen)
161 PintaCore.Chrome.MainWindow.Fullscreen ();
162 else
163 PintaCore.Chrome.MainWindow.Unfullscreen ();
164
165 isFullscreen = !isFullscreen;
166 };
167 }
168
169 private string temp_zoom;
170 private bool suspend_zoom_change;
171
172 private void Entry_FocusInEvent (object o, Gtk.FocusInEventArgs args)
173 {
174 temp_zoom = PintaCore.Actions.View.ZoomComboBox.ComboBox.ActiveText;
175 }
176
177 private void ComboBox_FocusOutEvent (object o, Gtk.FocusOutEventArgs args)
178 {
179 string text = PintaCore.Actions.View.ZoomComboBox.ComboBox.ActiveText;
180 double percent;
181
182 if (!TryParsePercent (text, out percent)) {
183 (PintaCore.Actions.View.ZoomComboBox.ComboBox as Gtk.ComboBoxEntry).Entry.Text = temp_zoom;
184 return;
185 }
186
187 if (percent > 3600)
188 PintaCore.Actions.View.ZoomComboBox.ComboBox.Active = 0;
189 }
190 #endregion
191
192 /// <summary>
193 /// Converts the string representation of a percent (with or without a '%' sign) to a numeric value
194 /// </summary>
195 public static bool TryParsePercent (string text, out double percent)
196 {
197 return double.TryParse (text.Trim ('%'), out percent);
198 }
199
200 public void SuspendZoomUpdate ()
201 {
202 suspend_zoom_change = true;
203 }
204
205 public void ResumeZoomUpdate ()
206 {
207 suspend_zoom_change = false;
208 }
209
210 public void UpdateCanvasScale ()
211 {
212 string text = PintaCore.Actions.View.ZoomComboBox.ComboBox.ActiveText;
213
214 // stay in "Zoom to Window" mode if this function was called without the zoom level being changed by the user (e.g. if the
215 // image was rotated or cropped) and "Zoom to Window" mode is active
216 if (text == Catalog.GetString ("Window") || (ZoomToWindowActivated && old_zoom_text == text))
217 {
218 PintaCore.Actions.View.ZoomToWindow.Activate ();
219 ZoomToWindowActivated = true;
220 return;
221 }
222 else
223 {
224 ZoomToWindowActivated = false;
225 }
226
227 double percent;
228
229 if (!TryParsePercent (text, out percent))
230 return;
231
232 percent = Math.Min (percent, 3600);
233 percent = percent / 100.0;
234
235 PintaCore.Workspace.Scale = percent;
236 }
237
238 #region Action Handlers
239 private void HandlePintaCoreActionsViewActualSizeActivated (object sender, EventArgs e)
240 {
241 int default_zoom = DefaultZoomIndex ();
242 if (ZoomComboBox.ComboBox.Active != default_zoom)
243 {
244 ZoomComboBox.ComboBox.Active = default_zoom;
245 UpdateCanvasScale ();
246 }
247 }
248
249 private void HandlePintaCoreActionsViewZoomComboBoxComboBoxChanged (object sender, EventArgs e)
250 {
251 if (suspend_zoom_change)
252 return;
253
254 PintaCore.Workspace.ActiveDocument.Workspace.ZoomManually ();
255 }
256
257 private void HandlePintaCoreActionsViewZoomOutActivated (object sender, EventArgs e)
258 {
259 PintaCore.Workspace.ActiveDocument.Workspace.ZoomOut ();
260 }
261
262 private void HandlePintaCoreActionsViewZoomInActivated (object sender, EventArgs e)
263 {
264 PintaCore.Workspace.ActiveDocument.Workspace.ZoomIn ();
265 }
266 #endregion
267
268 /// <summary>
269 /// Returns the index in the ZoomCollection of the default zoom level
270 /// </summary>
271 private int DefaultZoomIndex()
272 {
273 return Array.IndexOf(ZoomCollection, "100%");
274 }
275 }
276}
0\ No newline at end of file277\ No newline at end of file
1278
=== added file 'Pinta.Core/Actions/WindowActions.cs'
--- Pinta.Core/Actions/WindowActions.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Actions/WindowActions.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,153 @@
1//
2// WindowActions.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using System.Linq;
29using Gtk;
30using Mono.Unix;
31using System.Collections.Generic;
32
33namespace Pinta.Core
34{
35 public class WindowActions
36 {
37 private Menu window_menu;
38 private Dictionary<RadioAction, CheckMenuItem> action_menu_items;
39
40 public Gtk.Action SaveAll { get; private set; }
41 public Gtk.Action CloseAll { get; private set; }
42
43 public WindowActions ()
44 {
45 SaveAll = new Gtk.Action ("SaveAll", Catalog.GetString ("Save All"), null, Stock.Save);
46 CloseAll = new Gtk.Action ("CloseAll", Catalog.GetString ("Close All"), null, Stock.Close);
47
48 OpenWindows = new List<RadioAction> ();
49 action_menu_items = new Dictionary<RadioAction,CheckMenuItem> ();
50 }
51
52 public List<RadioAction> OpenWindows { get; private set; }
53
54 #region Initialization
55 public void CreateMainMenu (Gtk.Menu menu)
56 {
57 window_menu = menu;
58
59 menu.Append (SaveAll.CreateAcceleratedMenuItem (Gdk.Key.L, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
60 menu.Append (CloseAll.CreateAcceleratedMenuItem (Gdk.Key.W, Gdk.ModifierType.ControlMask | Gdk.ModifierType.ShiftMask));
61 menu.AppendSeparator ();
62 }
63 #endregion
64
65 #region Public Methods
66 public RadioAction AddDocument (Document doc)
67 {
68 RadioAction action = new RadioAction (doc.Guid.ToString (), doc.Filename, string.Empty, null, 0);
69
70 // Tie these all together as a radio group
71 if (OpenWindows.Count > 0)
72 action.Group = OpenWindows[0].Group;
73
74 action.Active = true;
75 action.Activated += (o, e) => { if ((o as Gtk.ToggleAction).Active) PintaCore.Workspace.SetActiveDocumentInternal (doc); };
76
77 OpenWindows.Add (action);
78 CheckMenuItem menuitem;
79
80 // We only assign accelerators up to Alt-9
81 if (OpenWindows.Count < 10)
82 menuitem = action.CreateAcceleratedMenuItem (IntegerToNumKey (OpenWindows.Count), Gdk.ModifierType.Mod1Mask);
83 else
84 menuitem = (CheckMenuItem)action.CreateMenuItem ();
85
86 action_menu_items.Add (action, menuitem);
87 window_menu.Add (menuitem);
88
89 doc.Renamed += (o, e) => { UpdateMenuLabel (action, o as Document); };
90 doc.IsDirtyChanged += (o, e) => { UpdateMenuLabel (action, o as Document); };
91
92 return action;
93 }
94
95 public void RemoveDocument (Document doc)
96 {
97 // Remove from our list of actions
98 RadioAction act = OpenWindows.Where (p => p.Name == doc.Guid.ToString ()).FirstOrDefault ();
99 OpenWindows.Remove (act);
100
101 // Remove all the menu items from the menu
102 foreach (var item in action_menu_items.Values) {
103 window_menu.Remove (item);
104 item.Dispose ();
105 }
106
107 action_menu_items.Clear ();
108
109 // Recreate all of our menu items
110 // I tried simply changing the accelerators, but could
111 // no get it to work.
112 CheckMenuItem menuitem;
113
114 for (int i = 0; i < OpenWindows.Count; i++) {
115 RadioAction action = OpenWindows[i];
116
117 if (i < 9)
118 menuitem = action.CreateAcceleratedMenuItem (IntegerToNumKey (i + 1), Gdk.ModifierType.Mod1Mask);
119 else
120 menuitem = (CheckMenuItem)action.CreateMenuItem ();
121
122 action_menu_items.Add (action, menuitem);
123 window_menu.Add (menuitem);
124 }
125 }
126 #endregion
127
128 #region Private Methods
129 private Gdk.Key IntegerToNumKey (int i)
130 {
131 switch (i) {
132 case 1: return Gdk.Key.Key_1;
133 case 2: return Gdk.Key.Key_2;
134 case 3: return Gdk.Key.Key_3;
135 case 4: return Gdk.Key.Key_4;
136 case 5: return Gdk.Key.Key_5;
137 case 6: return Gdk.Key.Key_6;
138 case 7: return Gdk.Key.Key_7;
139 case 8: return Gdk.Key.Key_8;
140 case 9: return Gdk.Key.Key_9;
141 }
142
143 throw new ArgumentOutOfRangeException (string.Format ("IntegerToNumKey does not support: {0}", i));
144 }
145
146 private void UpdateMenuLabel (RadioAction action, Document doc)
147 {
148 action.Label = string.Format ("{0}{1}", doc.Filename, doc.IsDirty ? "*" : string.Empty);
149 PintaCore.Workspace.ResetTitle ();
150 }
151 #endregion
152 }
153}
0154
=== added directory 'Pinta.Core/Classes'
=== added file 'Pinta.Core/Classes/Anchor.cs'
--- Pinta.Core/Classes/Anchor.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Classes/Anchor.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,43 @@
1//
2// Anchor.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28
29namespace Pinta.Core
30{
31 public enum Anchor
32 {
33 NW,
34 N,
35 NE,
36 E,
37 SE,
38 S,
39 SW,
40 W,
41 Center
42 }
43}
044
=== added file 'Pinta.Core/Classes/AsyncEffectRenderer.cs'
--- Pinta.Core/Classes/AsyncEffectRenderer.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Classes/AsyncEffectRenderer.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,361 @@
1//
2// AsyncEffectRenderer.cs
3//
4// Author:
5// Greg Lowe <greg@vis.net.nz>
6//
7// Copyright (c) 2010 Greg Lowe
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27#if (!LIVE_PREVIEW_DEBUG && DEBUG)
28#undef DEBUG
29#endif
30
31using System;
32using System.Collections.Generic;
33using System.Threading;
34using Debug = System.Diagnostics.Debug;
35
36namespace Pinta.Core
37{
38
39 // Only call methods on this class from a single thread (The UI thread).
40 internal abstract class AsyncEffectRenderer
41 {
42 Settings settings;
43
44 internal struct Settings {
45 internal int ThreadCount { get; set; }
46 internal int TileWidth { get; set; }
47 internal int TileHeight { get; set; }
48 internal int UpdateMillis { get; set; }
49 internal ThreadPriority ThreadPriority { get; set; }
50 }
51
52 BaseEffect effect;
53 Cairo.ImageSurface source_surface;
54 Cairo.ImageSurface dest_surface;
55 Gdk.Rectangle render_bounds;
56
57 bool is_rendering;
58 bool cancel_render_flag;
59 bool restart_render_flag;
60 int render_id;
61 int current_tile;
62 int total_tiles;
63 List<Exception> render_exceptions;
64
65 uint timer_tick_id;
66
67 object updated_lock;
68 bool is_updated;
69 int updated_x1;
70 int updated_y1;
71 int updated_x2;
72 int updated_y2;
73
74 internal AsyncEffectRenderer (Settings settings)
75 {
76 if (settings.ThreadCount < 1)
77 settings.ThreadCount = 1;
78
79 if (settings.TileWidth < 1)
80 throw new ArgumentException ("EffectRenderSettings.TileWidth");
81
82 if (settings.TileHeight < 1)
83 throw new ArgumentException ("EffectRenderSettings.TileHeight");
84
85 if (settings.UpdateMillis <= 0)
86 settings.UpdateMillis = 100;
87
88 effect = null;
89 source_surface = null;
90 dest_surface = null;
91 this.settings = settings;
92
93 is_rendering = false;
94 render_id = 0;
95 updated_lock = new object ();
96 is_updated = false;
97 render_exceptions = new List<Exception> ();
98
99 timer_tick_id = 0;
100 }
101
102 internal bool IsRendering {
103 get { return is_rendering; }
104 }
105
106 internal double Progress {
107 get {
108 if (total_tiles == 0 || current_tile < 0)
109 return 0;
110 else if (current_tile < total_tiles)
111 return (double)current_tile / (double)total_tiles;
112 else
113 return 1;
114 }
115 }
116
117 internal void Start (BaseEffect effect,
118 Cairo.ImageSurface source,
119 Cairo.ImageSurface dest,
120 Gdk.Rectangle renderBounds)
121 {
122 Debug.WriteLine ("AsyncEffectRenderer.Start ()");
123
124 if (effect == null)
125 throw new ArgumentNullException ("effect");
126
127 if (source == null)
128 throw new ArgumentNullException ("source");
129
130 if (dest == null)
131 throw new ArgumentNullException ("dest");
132
133 if (renderBounds.IsEmpty)
134 throw new ArgumentException ("renderBounds.IsEmpty");
135
136 // It is important the effect's properties don't change during rendering.
137 // So a copy is made for the render.
138 this.effect = effect.Clone();
139
140 this.source_surface = source;
141 this.dest_surface = dest;
142 this.render_bounds = renderBounds;
143
144 // If a render is already in progress, then cancel it,
145 // and start a new render.
146 if (IsRendering) {
147 cancel_render_flag = true;
148 restart_render_flag = true;
149 return;
150 }
151
152 StartRender ();
153 }
154
155 internal void Cancel ()
156 {
157 Debug.WriteLine ("AsyncEffectRenderer.Cancel ()");
158 cancel_render_flag = true;
159 restart_render_flag = false;
160
161 if (!IsRendering)
162 HandleRenderCompletion ();
163 }
164
165 protected abstract void OnUpdate (double progress, Gdk.Rectangle updatedBounds);
166
167 protected abstract void OnCompletion (bool canceled, Exception[] exceptions);
168
169 internal void Dispose ()
170 {
171 if (timer_tick_id > 0)
172 GLib.Source.Remove (timer_tick_id);
173 }
174
175 void StartRender ()
176 {
177 is_rendering = true;
178 cancel_render_flag = false;
179 restart_render_flag = false;
180 is_updated = false;
181
182 render_id++;
183 render_exceptions.Clear ();
184
185 current_tile = -1;
186
187 total_tiles = CalculateTotalTiles ();
188
189 Debug.WriteLine ("AsyncEffectRenderer.Start () Render " + render_id + " starting.");
190
191 // Copy the current render id.
192 int renderId = render_id;
193
194 // Start slave render threads.
195 int threadCount = settings.ThreadCount;
196 var slaves = new Thread[threadCount - 1];
197 for (int threadId = 1; threadId < threadCount; threadId++)
198 slaves[threadId - 1] = StartSlaveThread (renderId, threadId);
199
200 // Start the master render thread.
201 var master = new Thread (() => {
202
203 // Do part of the rendering on the master thread.
204 Render (renderId, 0);
205
206 // Wait for slave threads to complete.
207 foreach (var slave in slaves)
208 slave.Join ();
209
210 // Change back to the UI thread to notify of completion.
211 Gtk.Application.Invoke ((o,e) => HandleRenderCompletion ());
212 });
213
214 master.Priority = settings.ThreadPriority;
215 master.Start ();
216
217 // Start timer used to periodically fire update events on the UI thread.
218 timer_tick_id = GLib.Timeout.Add((uint) settings.UpdateMillis, HandleTimerTick);
219 }
220
221 Thread StartSlaveThread (int renderId, int threadId)
222 {
223 var slave = new Thread(() => {
224 Render (renderId, threadId);
225 });
226
227 slave.Priority = settings.ThreadPriority;
228 slave.Start ();
229
230 return slave;
231 }
232
233 // Runs on a background thread.
234 void Render (int renderId, int threadId)
235 {
236 // Fetch the next tile index and render it.
237 for (;;) {
238
239 int tileIndex = Interlocked.Increment (ref current_tile);
240
241 if (tileIndex >= total_tiles || cancel_render_flag)
242 return;
243
244 RenderTile (renderId, threadId, tileIndex);
245 }
246 }
247
248 // Runs on a background thread.
249 void RenderTile (int renderId, int threadId, int tileIndex)
250 {
251 Exception exception = null;
252 Gdk.Rectangle bounds = new Gdk.Rectangle ();
253
254 try {
255
256 bounds = GetTileBounds (tileIndex);
257
258 if (!cancel_render_flag) {
259 dest_surface.Flush ();
260 effect.Render (source_surface, dest_surface, new [] { bounds });
261 dest_surface.MarkDirty (bounds.ToCairoRectangle ());
262 }
263
264 } catch (Exception ex) {
265 exception = ex;
266 Debug.WriteLine ("AsyncEffectRenderer Error while rendering effect: " + effect.Name + " exception: " + ex.Message + "\n" + ex.StackTrace);
267 }
268
269 // Ignore completions of tiles after a cancel or from a previous render.
270 if (!IsRendering || renderId != render_id)
271 return;
272
273 // Update bounds to be shown on next expose.
274 lock (updated_lock) {
275 if (is_updated) {
276 updated_x1 = Math.Min (bounds.X, updated_x1);
277 updated_y1 = Math.Min (bounds.Y, updated_y1);
278 updated_x2 = Math.Max (bounds.X + bounds.Width, updated_x2);
279 updated_y2 = Math.Max (bounds.Y + bounds.Height, updated_y2);
280 } else {
281 is_updated = true;
282 updated_x1 = bounds.X;
283 updated_y1 = bounds.Y;
284 updated_x2 = bounds.X + bounds.Width;
285 updated_y2 = bounds.Y + bounds.Height;
286 }
287 }
288
289 if (exception != null) {
290 lock (render_exceptions) {
291 render_exceptions.Add (exception);
292 }
293 }
294 }
295
296 // Runs on a background thread.
297 Gdk.Rectangle GetTileBounds (int tileIndex)
298 {
299 int horizTileCount = (int)Math.Ceiling((float)render_bounds.Width
300 / (float)settings.TileWidth);
301
302 int x = ((tileIndex % horizTileCount) * settings.TileWidth) + render_bounds.X;
303 int y = ((tileIndex / horizTileCount) * settings.TileHeight) + render_bounds.Y;
304 int w = Math.Min(settings.TileWidth, render_bounds.Right - x);
305 int h = Math.Min(settings.TileHeight, render_bounds.Bottom - y);
306
307 return new Gdk.Rectangle (x, y, w, h);
308 }
309
310 int CalculateTotalTiles ()
311 {
312 return (int)(Math.Ceiling((float)render_bounds.Width / (float)settings.TileWidth)
313 * Math.Ceiling((float)render_bounds.Height / (float)settings.TileHeight));
314 }
315
316 // Called on the UI thread.
317 bool HandleTimerTick ()
318 {
319 Debug.WriteLine (DateTime.Now.ToString("HH:mm:ss:ffff") + " Timer tick.");
320
321 Gdk.Rectangle bounds;
322
323 lock (updated_lock) {
324
325 if (!is_updated)
326 return true;
327
328 is_updated = false;
329
330 bounds = new Gdk.Rectangle (updated_x1,
331 updated_y1,
332 updated_x2 - updated_x1,
333 updated_y2 - updated_y1);
334 }
335
336 if (IsRendering && !cancel_render_flag)
337 OnUpdate (Progress, bounds);
338
339 return true;
340 }
341
342 void HandleRenderCompletion ()
343 {
344 var exceptions = (render_exceptions == null || render_exceptions.Count == 0)
345 ? null
346 : render_exceptions.ToArray ();
347
348 HandleTimerTick ();
349
350 if (timer_tick_id > 0)
351 GLib.Source.Remove (timer_tick_id);
352
353 OnCompletion (cancel_render_flag, exceptions);
354
355 if (restart_render_flag)
356 StartRender ();
357 else
358 is_rendering = false;
359 }
360 }
361}
0362
=== added file 'Pinta.Core/Classes/BaseExtension.cs'
--- Pinta.Core/Classes/BaseExtension.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Classes/BaseExtension.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,41 @@
1//
2// BaseExtension.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27
28using System;
29
30namespace Pinta.Core
31{
32 public class BaseExtension
33 {
34 /// <summary>
35 /// Called during startup, perform any necessary initialization here
36 /// </summary>
37 public virtual void Initialize ()
38 {
39 }
40 }
41}
042
=== added file 'Pinta.Core/Classes/BasePaintBrush.cs'
--- Pinta.Core/Classes/BasePaintBrush.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Classes/BasePaintBrush.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,42 @@
1//
2// BasePaintBrush.cs
3//
4// Author:
5// Aaron Bockover <abockover@novell.com>
6//
7// Copyright (c) 2010 Novell, Inc.
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using Mono.Addins;
29
30namespace Pinta.Core
31{
32 [TypeExtensionPoint]
33 public abstract class BasePaintBrush
34 {
35 public abstract string Name { get; }
36
37 public virtual int Priority {
38 get { return 0; }
39 }
40 }
41}
42
043
=== added file 'Pinta.Core/Classes/BaseTool.cs'
--- Pinta.Core/Classes/BaseTool.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Classes/BaseTool.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,276 @@
1//
2// BaseTool.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using Cairo;
29using Gtk;
30using System.IO;
31using Mono.Unix;
32using Mono.Addins;
33
34namespace Pinta.Core
35{
36 public delegate void MouseHandler (double x, double y, Gdk.ModifierType state);
37
38 [TypeExtensionPoint]
39 public abstract class BaseTool
40 {
41 protected const int DEFAULT_BRUSH_WIDTH = 2;
42
43 protected static Point point_empty = new Point (-500, -500);
44
45 protected ToggleToolButton tool_item;
46 protected ToolItem tool_label;
47 protected ToolItem tool_image;
48 protected ToolItem tool_sep;
49 protected ToolBarDropDownButton antialiasing_button;
50 protected ToolBarDropDownButton alphablending_button;
51 public event MouseHandler MouseMoved;
52 public event MouseHandler MousePressed;
53 public event MouseHandler MouseReleased;
54
55 protected BaseTool ()
56 {
57 }
58
59 static BaseTool ()
60 {
61 Gtk.IconFactory fact = new Gtk.IconFactory ();
62 fact.Add ("Toolbar.AntiAliasingEnabledIcon.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Toolbar.AntiAliasingEnabledIcon.png")));
63 fact.Add ("Toolbar.AntiAliasingDisabledIcon.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Toolbar.AntiAliasingDisabledIcon.png")));
64 fact.Add ("Toolbar.BlendingEnabledIcon.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Toolbar.BlendingEnabledIcon.png")));
65 fact.Add ("Toolbar.BlendingOverwriteIcon.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Toolbar.BlendingOverwriteIcon.png")));
66 fact.Add ("Tools.FreeformShape.png", new Gtk.IconSet (PintaCore.Resources.GetIcon ("Tools.FreeformShape.png")));
67 fact.AddDefault ();
68 }
69
70 public virtual string Name { get { throw new ApplicationException ("Tool didn't override Name"); } }
71 public virtual string Icon { get { throw new ApplicationException ("Tool didn't override Icon"); } }
72 public virtual string ToolTip { get { throw new ApplicationException ("Tool didn't override ToolTip"); } }
73 public virtual string StatusBarText { get { return string.Empty; } }
74 public virtual ToggleToolButton ToolItem { get { if (tool_item == null) tool_item = CreateToolButton (); return tool_item; } }
75 public virtual bool Enabled { get { return true; } }
76 public virtual Gdk.Cursor DefaultCursor { get { return null; } }
77 public virtual Gdk.Key ShortcutKey { get { return (Gdk.Key)0; } }
78 public virtual bool UseAntialiasing { get { return ShowAntialiasingButton && (bool)antialiasing_button.SelectedItem.Tag; } }
79 public virtual bool UseAlphaBlending { get { return ShowAlphaBlendingButton && (bool)alphablending_button.SelectedItem.Tag; } }
80 public virtual int Priority { get { return 75; } }
81
82 protected virtual bool ShowAntialiasingButton { get { return false; } }
83 protected virtual bool ShowAlphaBlendingButton { get { return false; } }
84
85 #region Public Methods
86 public void DoMouseMove (object o, MotionNotifyEventArgs args, Cairo.PointD point)
87 {
88 if (MouseMoved != null)
89 MouseMoved (point.X, point.Y, args.Event.State);
90 OnMouseMove (o, args, point);
91 }
92
93 public void DoBuildToolBar (Toolbar tb)
94 {
95 OnBuildToolBar (tb);
96 BuildRasterizationToolItems (tb);
97 }
98
99 public void DoClearToolBar (Toolbar tb)
100 {
101 OnClearToolBar (tb);
102 }
103
104 public void DoMouseDown (DrawingArea canvas, ButtonPressEventArgs args, Cairo.PointD point)
105 {
106 if (MousePressed != null)
107 MousePressed (point.X, point.Y, args.Event.State);
108 OnMouseDown (canvas, args, point);
109 }
110
111 public void DoMouseUp (DrawingArea canvas, ButtonReleaseEventArgs args, Cairo.PointD point)
112 {
113 if (MouseReleased != null)
114 MouseReleased (point.X, point.Y, args.Event.State);
115 OnMouseUp (canvas, args, point);
116 }
117
118 public void DoCommit ()
119 {
120 OnCommit ();
121 }
122
123 public void DoActivated ()
124 {
125 OnActivated ();
126 }
127
128 public void DoDeactivated ()
129 {
130 OnDeactivated ();
131 }
132
133 // Return true if the key was consumed.
134 public void DoKeyPress (DrawingArea canvas, KeyPressEventArgs args)
135 {
136 OnKeyDown (canvas, args);
137 }
138
139 public void DoKeyRelease (DrawingArea canvas, KeyReleaseEventArgs args)
140 {
141 OnKeyUp (canvas, args);
142 }
143 #endregion
144
145 #region Protected Methods
146 protected virtual void OnMouseMove (object o, Gtk.MotionNotifyEventArgs args, Cairo.PointD point)
147 {
148 }
149
150 protected virtual void BuildRasterizationToolItems (Toolbar tb)
151 {
152 if (ShowAlphaBlendingButton || ShowAntialiasingButton)
153 tb.AppendItem (new SeparatorToolItem ());
154
155 if (ShowAntialiasingButton)
156 BuildAntialiasingTool (tb);
157 if (ShowAlphaBlendingButton)
158 BuildAlphaBlending (tb);
159 }
160
161 protected virtual void OnBuildToolBar (Toolbar tb)
162 {
163 if (tool_label == null)
164 tool_label = new ToolBarLabel (string.Format (" {0}: ", Catalog.GetString ("Tool")));
165
166 tb.AppendItem (tool_label);
167
168 if (tool_image == null)
169 tool_image = new ToolBarImage (Icon);
170
171 tb.AppendItem (tool_image);
172
173 if (tool_sep == null)
174 tool_sep = new SeparatorToolItem ();
175
176 tb.AppendItem (tool_sep);
177 }
178
179 protected virtual void OnClearToolBar (Toolbar tb)
180 {
181 while (tb.NItems > 0)
182 tb.Remove (tb.Children[tb.NItems - 1]);
183 }
184
185 protected virtual void OnMouseDown (DrawingArea canvas, Gtk.ButtonPressEventArgs args, Cairo.PointD point)
186 {
187 }
188
189 protected virtual void OnMouseUp (DrawingArea canvas, Gtk.ButtonReleaseEventArgs args, Cairo.PointD point)
190 {
191 }
192
193 protected virtual void OnKeyDown (DrawingArea canvas, Gtk.KeyPressEventArgs args)
194 {
195 }
196
197 protected virtual void OnKeyUp (DrawingArea canvas, Gtk.KeyReleaseEventArgs args)
198 {
199 }
200
201 /// <summary>
202 /// This is called whenever a menu option is called, for
203 /// tools that are in a temporary state while being used, and
204 /// need to commit their work when another option is selected.
205 /// </summary>
206 protected virtual void OnCommit ()
207 {
208 }
209
210 protected virtual void OnActivated ()
211 {
212 SetCursor (DefaultCursor);
213 }
214
215 protected virtual void OnDeactivated ()
216 {
217 SetCursor (null);
218 }
219
220 protected virtual ToggleToolButton CreateToolButton ()
221 {
222 Image i2 = new Image (PintaCore.Resources.GetIcon (Icon));
223 i2.Show ();
224
225 ToggleToolButton tool_item = new ToggleToolButton ();
226 tool_item.IconWidget = i2;
227 tool_item.Show ();
228 tool_item.Label = Name;
229
230 if (ShortcutKey != (Gdk.Key)0)
231 tool_item.TooltipText = string.Format ("{0}\n{2}: {1}\n\n{3}", Name, ShortcutKey.ToString ().ToUpperInvariant (), Catalog.GetString ("Shortcut key"), StatusBarText);
232 else
233 tool_item.TooltipText = Name;
234
235 return tool_item;
236 }
237
238 protected void SetCursor (Gdk.Cursor cursor)
239 {
240 PintaCore.Chrome.Canvas.GdkWindow.Cursor = cursor;
241 }
242 #endregion
243
244 #region Private Methods
245 private void BuildAlphaBlending (Toolbar tb)
246 {
247 if (alphablending_button != null) {
248 tb.AppendItem (alphablending_button);
249 return;
250 }
251
252 alphablending_button = new ToolBarDropDownButton ();
253
254 alphablending_button.AddItem (Catalog.GetString ("Normal Blending"), "Toolbar.BlendingEnabledIcon.png", true);
255 alphablending_button.AddItem (Catalog.GetString ("Overwrite"), "Toolbar.BlendingOverwriteIcon.png", false);
256
257 tb.AppendItem (alphablending_button);
258 }
259
260 private void BuildAntialiasingTool (Toolbar tb)
261 {
262 if (antialiasing_button != null) {
263 tb.AppendItem (antialiasing_button);
264 return;
265 }
266
267 antialiasing_button = new ToolBarDropDownButton ();
268
269 antialiasing_button.AddItem (Catalog.GetString ("Antialiasing On"), "Toolbar.AntiAliasingEnabledIcon.png", true);
270 antialiasing_button.AddItem (Catalog.GetString ("Antialiasing Off"), "Toolbar.AntiAliasingDisabledIcon.png", false);
271
272 tb.AppendItem (antialiasing_button);
273 }
274 #endregion
275 }
276}
0277
=== added file 'Pinta.Core/Classes/Document.cs'
--- Pinta.Core/Classes/Document.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Classes/Document.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,735 @@
1//
2// Document.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using System.Linq;
29using Mono.Unix;
30using Gdk;
31using System.Collections.Generic;
32using Cairo;
33using System.ComponentModel;
34
35namespace Pinta.Core
36{
37 // The differentiation between Document and DocumentWorkspace is
38 // somewhat arbitrary. In general:
39 // Document - Data about the image itself
40 // Workspace - Data about Pinta's state for the image
41 public class Document
42 {
43 private string filename;
44 private bool is_dirty;
45 private int layer_name_int = 2;
46 private int current_layer = -1;
47
48 // The layer for tools to use until their output is committed
49 private Layer tool_layer;
50 // The layer used for selections
51 private Layer selection_layer;
52
53 private int selection_layer_index;
54 private Path selection_path;
55 private bool show_selection;
56
57 public Document (Gdk.Size size)
58 {
59 Guid = Guid.NewGuid ();
60
61 Workspace = new DocumentWorkspace (this);
62 IsDirty = false;
63 HasFile = false;
64 ImageSize = size;
65
66 Layers = new List<Layer> ();
67
68 tool_layer = CreateLayer ("Tool Layer");
69 tool_layer.Hidden = true;
70
71 selection_layer = CreateLayer ("Selection Layer");
72 selection_layer.Hidden = true;
73
74 ResetSelectionPath ();
75 }
76
77 #region Public Properties
78 public Layer CurrentLayer {
79 get { return Layers[current_layer]; }
80 }
81
82 public int CurrentLayerIndex {
83 get { return current_layer; }
84 }
85
86 /// <summary>
87 /// Just the file name, like "dog.jpg".
88 /// </summary>
89 public string Filename {
90 get { return filename; }
91 set {
92 if (filename != value) {
93 filename = value;
94 OnRenamed ();
95 }
96 }
97 }
98
99 public Guid Guid { get; private set; }
100
101 public bool HasFile { get; set; }
102
103 public DocumentWorkspaceHistory History { get { return Workspace.History; } }
104
105 public Gdk.Size ImageSize { get; set; }
106
107 public bool IsDirty {
108 get { return is_dirty; }
109 set {
110 if (is_dirty != value) {
111 is_dirty = value;
112 OnIsDirtyChanged ();
113 }
114 }
115 }
116
117 public List<Layer> Layers { get; private set; }
118
119 /// <summary>
120 /// Just the directory name, like "C:\MyPictures".
121 /// </summary>
122 public string Pathname { get; set; }
123
124 /// <summary>
125 /// Directory and file name, like "C:\MyPictures\dog.jpg".
126 /// </summary>
127 public string PathAndFileName {
128 get { return System.IO.Path.Combine (Pathname, Filename); }
129 set {
130 if (string.IsNullOrEmpty (value)) {
131 Pathname = string.Empty;
132 Filename = string.Empty;
133 } else {
134 Pathname = System.IO.Path.GetDirectoryName (value);
135 Filename = System.IO.Path.GetFileName (value);
136 }
137 }
138 }
139
140 public Layer SelectionLayer {
141 get { return selection_layer; }
142 }
143
144 public Path SelectionPath {
145 get { return selection_path; }
146 set {
147 if (selection_path == value)
148 return;
149
150 selection_path = value;
151 }
152 }
153
154 public bool ShowSelection {
155 get { return show_selection; }
156 set {
157 show_selection = value;
158 PintaCore.Actions.Edit.Deselect.Sensitive = show_selection;
159 PintaCore.Actions.Edit.EraseSelection.Sensitive = show_selection;
160 PintaCore.Actions.Edit.FillSelection.Sensitive = show_selection;
161 PintaCore.Actions.Image.CropToSelection.Sensitive = show_selection;
162 }
163 }
164
165 public bool ShowSelectionLayer { get; set; }
166
167 public Layer ToolLayer {
168 get {
169 if (tool_layer.Surface.Width != ImageSize.Width || tool_layer.Surface.Height != ImageSize.Height) {
170 (tool_layer.Surface as IDisposable).Dispose ();
171 tool_layer = CreateLayer ("Tool Layer");
172 tool_layer.Hidden = true;
173 }
174
175 return tool_layer;
176 }
177 }
178
179 public DocumentWorkspace Workspace { get; private set; }
180 #endregion
181
182 #region Public Methods
183 // Adds a new layer above the current one
184 public Layer AddNewLayer (string name)
185 {
186 Layer layer;
187
188 if (string.IsNullOrEmpty (name))
189 layer = CreateLayer ();
190 else
191 layer = CreateLayer (name);
192
193 Layers.Insert (current_layer + 1, layer);
194
195 if (Layers.Count == 1)
196 current_layer = 0;
197
198 layer.PropertyChanged += RaiseLayerPropertyChangedEvent;
199
200 PintaCore.Layers.OnLayerAdded ();
201 return layer;
202 }
203
204 public Gdk.Rectangle ClampToImageSize (Gdk.Rectangle r)
205 {
206 int x = Utility.Clamp (r.X, 0, ImageSize.Width);
207 int y = Utility.Clamp (r.Y, 0, ImageSize.Height);
208 int width = Math.Min (r.Width, ImageSize.Width - x);
209 int height = Math.Min (r.Height, ImageSize.Height - y);
210
211 return new Gdk.Rectangle (x, y, width, height);
212 }
213
214 public void Clear ()
215 {
216 while (Layers.Count > 0) {
217 Layer l = Layers[Layers.Count - 1];
218 Layers.RemoveAt (Layers.Count - 1);
219 (l.Surface as IDisposable).Dispose ();
220 }
221
222 current_layer = -1;
223 PintaCore.Layers.OnLayerRemoved ();
224 }
225
226 // Clean up any native resources we had
227 public void Close ()
228 {
229 // Dispose all of our layers
230 while (Layers.Count > 0) {
231 Layer l = Layers[Layers.Count - 1];
232 Layers.RemoveAt (Layers.Count - 1);
233 (l.Surface as IDisposable).Dispose ();
234 }
235
236 current_layer = -1;
237
238 if (tool_layer != null)
239 (tool_layer.Surface as IDisposable).Dispose ();
240
241 if (selection_layer != null)
242 (selection_layer.Surface as IDisposable).Dispose ();
243
244 if (selection_path != null)
245 (selection_path as IDisposable).Dispose ();
246 }
247
248 public Context CreateClippedContext ()
249 {
250 Context g = new Context (CurrentLayer.Surface);
251
252 g.AppendPath (SelectionPath);
253 g.FillRule = Cairo.FillRule.EvenOdd;
254 g.Clip ();
255
256 return g;
257 }
258
259 public Context CreateClippedContext (bool antialias)
260 {
261 Context g = new Context (CurrentLayer.Surface);
262
263 g.AppendPath (SelectionPath);
264 g.FillRule = Cairo.FillRule.EvenOdd;
265 g.Clip ();
266
267 g.Antialias = antialias ? Antialias.Subpixel : Antialias.None;
268
269 return g;
270 }
271
272 public Context CreateClippedToolContext ()
273 {
274 Context g = new Context (ToolLayer.Surface);
275
276 g.AppendPath (SelectionPath);
277 g.FillRule = Cairo.FillRule.EvenOdd;
278 g.Clip ();
279
280 return g;
281 }
282
283 public Context CreateClippedToolContext (bool antialias)
284 {
285 Context g = new Context (ToolLayer.Surface);
286
287 g.AppendPath (SelectionPath);
288 g.FillRule = Cairo.FillRule.EvenOdd;
289 g.Clip ();
290
291 g.Antialias = antialias ? Antialias.Subpixel : Antialias.None;
292
293 return g;
294 }
295
296 public Layer CreateLayer ()
297 {
298 return CreateLayer (string.Format ("{0} {1}", Catalog.GetString ("Layer"), layer_name_int++));
299 }
300
301 public Layer CreateLayer (string name)
302 {
303 return CreateLayer (name, ImageSize.Width, ImageSize.Height);
304 }
305
306 public Layer CreateLayer (string name, int width, int height)
307 {
308 Cairo.ImageSurface surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, width, height);
309 Layer layer = new Layer (surface) { Name = name };
310
311 return layer;
312 }
313
314 public void CreateSelectionLayer ()
315 {
316 Layer old = selection_layer;
317
318 selection_layer = CreateLayer ();
319 selection_layer_index = current_layer + 1;
320
321 if (old != null)
322 (old.Surface as IDisposable).Dispose ();
323 }
324
325 // Delete the current layer
326 public void DeleteCurrentLayer ()
327 {
328 Layer layer = CurrentLayer;
329
330 Layers.RemoveAt (current_layer);
331
332 // Only change this if this wasn't already the bottom layer
333 if (current_layer > 0)
334 current_layer--;
335
336 layer.PropertyChanged -= RaiseLayerPropertyChangedEvent;
337
338 PintaCore.Layers.OnLayerRemoved ();
339 }
340
341 // Delete the layer
342 public void DeleteLayer (int index, bool dispose)
343 {
344 Layer layer = Layers[index];
345
346 Layers.RemoveAt (index);
347
348 if (dispose)
349 (layer.Surface as IDisposable).Dispose ();
350
351 // Only change this if this wasn't already the bottom layer
352 if (current_layer > 0)
353 current_layer--;
354
355 layer.PropertyChanged -= RaiseLayerPropertyChangedEvent;
356
357 PintaCore.Layers.OnLayerRemoved ();
358 }
359
360 public void DestroySelectionLayer ()
361 {
362 ShowSelectionLayer = false;
363 SelectionLayer.Clear ();
364 SelectionLayer.Offset = new PointD (0, 0);
365 }
366
367 // Duplicate current layer
368 public Layer DuplicateCurrentLayer ()
369 {
370 Layer source = CurrentLayer;
371 Layer layer = CreateLayer (string.Format ("{0} {1}", source.Name, Catalog.GetString ("copy")));
372
373 using (Cairo.Context g = new Cairo.Context (layer.Surface)) {
374 g.SetSource (source.Surface);
375 g.Paint ();
376 }
377
378 layer.Hidden = source.Hidden;
379 layer.Opacity = source.Opacity;
380 layer.Tiled = source.Tiled;
381
382 Layers.Insert (++current_layer, layer);
383
384 layer.PropertyChanged += RaiseLayerPropertyChangedEvent;
385
386 PintaCore.Layers.OnLayerAdded ();
387
388 return layer;
389 }
390
391 public void FinishSelection ()
392 {
393 // We don't have an uncommitted layer, abort
394 if (!ShowSelectionLayer)
395 return;
396
397 FinishPixelsHistoryItem hist = new FinishPixelsHistoryItem ();
398 hist.TakeSnapshot ();
399
400 Layer layer = SelectionLayer;
401
402 using (Cairo.Context g = new Cairo.Context (CurrentLayer.Surface)) {
403 g.Save ();
404
405 g.SetSourceSurface (layer.Surface, (int)layer.Offset.X, (int)layer.Offset.Y);
406 g.PaintWithAlpha (layer.Opacity);
407
408 g.Restore ();
409 }
410
411 DestroySelectionLayer ();
412 Workspace.Invalidate ();
413
414 Workspace.History.PushNewItem (hist);
415 }
416
417 // Flatten image
418 public void FlattenImage ()
419 {
420 if (Layers.Count < 2)
421 throw new InvalidOperationException ("Cannot flatten image because there is only one layer.");
422
423 Layer dest = Layers[0];
424
425 using (Cairo.Context g = new Cairo.Context (dest.Surface)) {
426 for (int i = 1; i < Layers.Count; i++) {
427 Layer source = Layers[i];
428 g.SetSource (source.Surface);
429 g.PaintWithAlpha (source.Opacity);
430 }
431 }
432
433 current_layer = 0;
434
435 while (Layers.Count > 1) {
436 Layer l = Layers[1];
437
438 Layers.RemoveAt (1);
439 }
440
441 PintaCore.Layers.OnLayerRemoved ();
442 Workspace.Invalidate ();
443 }
444
445 // Flip image horizontally
446 public void FlipImageHorizontal ()
447 {
448 foreach (var layer in Layers)
449 layer.FlipHorizontal ();
450
451 Workspace.Invalidate ();
452 }
453
454 // Flip image vertically
455 public void FlipImageVertical ()
456 {
457 foreach (var layer in Layers)
458 layer.FlipVertical ();
459
460 Workspace.Invalidate ();
461 }
462
463 public ImageSurface GetClippedLayer (int index)
464 {
465 Cairo.ImageSurface surf = new Cairo.ImageSurface (Cairo.Format.Argb32, ImageSize.Width, ImageSize.Height);
466
467 using (Cairo.Context g = new Cairo.Context (surf)) {
468 g.AppendPath (SelectionPath);
469 g.Clip ();
470
471 g.SetSource (Layers[index].Surface);
472 g.Paint ();
473 }
474
475 return surf;
476 }
477
478 public ImageSurface GetFlattenedImage ()
479 {
480 Cairo.ImageSurface surf = new Cairo.ImageSurface (Cairo.Format.Argb32, ImageSize.Width, ImageSize.Height);
481
482 using (Cairo.Context g = new Cairo.Context (surf)) {
483 foreach (var layer in GetLayersToPaint ()) {
484 g.SetSource (layer.Surface);
485 g.PaintWithAlpha (layer.Opacity);
486 }
487 }
488
489 return surf;
490 }
491
492 public List<Layer> GetLayersToPaint ()
493 {
494 List<Layer> paint = new List<Layer> ();
495
496 foreach (var layer in Layers) {
497 if (!layer.Hidden)
498 paint.Add (layer);
499
500 if (layer == CurrentLayer) {
501 if (!tool_layer.Hidden)
502 paint.Add (tool_layer);
503
504 if (ShowSelectionLayer)
505 paint.Add (selection_layer);
506 }
507 }
508
509 return paint;
510 }
511
512 /// <param name="canvasOnly">false for the whole selection, true for the part only on our canvas</param>
513 public Gdk.Rectangle GetSelectedBounds (bool canvasOnly)
514 {
515 var bounds = SelectionPath.GetBounds ();
516
517 if (canvasOnly)
518 bounds = ClampToImageSize (bounds);
519
520 return bounds;
521 }
522
523 public int IndexOf (Layer layer)
524 {
525 return Layers.IndexOf (layer);
526 }
527
528 // Adds a new layer above the current one
529 public void Insert (Layer layer, int index)
530 {
531 Layers.Insert (index, layer);
532
533 if (Layers.Count == 1)
534 current_layer = 0;
535
536 layer.PropertyChanged += RaiseLayerPropertyChangedEvent;
537
538 PintaCore.Layers.OnLayerAdded ();
539 }
540
541 // Flatten current layer
542 public void MergeCurrentLayerDown ()
543 {
544 if (current_layer == 0)
545 throw new InvalidOperationException ("Cannot flatten layer because current layer is the bottom layer.");
546
547 Layer source = CurrentLayer;
548 Layer dest = Layers[current_layer - 1];
549
550 using (Cairo.Context g = new Cairo.Context (dest.Surface)) {
551 g.SetSource (source.Surface);
552 g.PaintWithAlpha (source.Opacity);
553 }
554
555 DeleteCurrentLayer ();
556 }
557
558 // Move current layer down
559 public void MoveCurrentLayerDown ()
560 {
561 if (current_layer == 0)
562 throw new InvalidOperationException ("Cannot move layer down because current layer is the bottom layer.");
563
564 Layer layer = CurrentLayer;
565 Layers.RemoveAt (current_layer);
566 Layers.Insert (--current_layer, layer);
567
568 PintaCore.Layers.OnSelectedLayerChanged ();
569
570 Workspace.Invalidate ();
571 }
572
573 // Move current layer up
574 public void MoveCurrentLayerUp ()
575 {
576 if (current_layer == Layers.Count)
577 throw new InvalidOperationException ("Cannot move layer up because current layer is the top layer.");
578
579 Layer layer = CurrentLayer;
580 Layers.RemoveAt (current_layer);
581 Layers.Insert (++current_layer, layer);
582
583 PintaCore.Layers.OnSelectedLayerChanged ();
584
585 Workspace.Invalidate ();
586 }
587
588 public void ResetSelectionPath ()
589 {
590 Path old = SelectionPath;
591
592 using (Cairo.Context g = new Cairo.Context (selection_layer.Surface))
593 SelectionPath = g.CreateRectanglePath (new Cairo.Rectangle (0, 0, ImageSize.Width, ImageSize.Height));
594
595 if (old != null)
596 (old as IDisposable).Dispose ();
597
598 ShowSelection = false;
599 }
600
601 public void ResizeCanvas (int width, int height, Anchor anchor)
602 {
603 double scale;
604
605 if (ImageSize.Width == width && ImageSize.Height == height)
606 return;
607
608 PintaCore.Tools.Commit ();
609
610 ResizeHistoryItem hist = new ResizeHistoryItem (ImageSize);
611 hist.Icon = "Menu.Image.CanvasSize.png";
612 hist.Text = Catalog.GetString ("Resize Canvas");
613 hist.TakeSnapshotOfImage ();
614
615 scale = Workspace.Scale;
616
617 ImageSize = new Gdk.Size (width, height);
618
619 foreach (var layer in Layers)
620 layer.ResizeCanvas (width, height, anchor);
621
622 Workspace.History.PushNewItem (hist);
623
624 ResetSelectionPath ();
625
626 Workspace.Scale = scale;
627 }
628
629 public void ResizeImage (int width, int height)
630 {
631 double scale;
632
633 if (ImageSize.Width == width && ImageSize.Height == height)
634 return;
635
636 PintaCore.Tools.Commit ();
637
638 ResizeHistoryItem hist = new ResizeHistoryItem (ImageSize);
639 hist.TakeSnapshotOfImage ();
640
641 scale = Workspace.Scale;
642
643 ImageSize = new Gdk.Size (width, height);
644
645 foreach (var layer in Layers)
646 layer.Resize (width, height);
647
648 Workspace.History.PushNewItem (hist);
649
650 ResetSelectionPath ();
651
652 Workspace.Scale = scale;
653 }
654
655 // Rotate image 180 degrees (flip H+V)
656 public void RotateImage180 ()
657 {
658 RotateImage (180);
659 }
660
661 public void RotateImageCW ()
662 {
663 RotateImage (90);
664 }
665
666 public void RotateImageCCW ()
667 {
668 RotateImage (-90);
669 }
670
671 /// <summary>
672 /// Rotates the image by the specified angle (in degrees)
673 /// </summary>
674 private void RotateImage (double angle)
675 {
676 foreach (var layer in Layers)
677 {
678 layer.Rotate (angle);
679 }
680
681 ImageSize = Layer.RotateDimensions (ImageSize, angle);
682 Workspace.CanvasSize = Layer.RotateDimensions (Workspace.CanvasSize, angle);
683
684 PintaCore.Actions.View.UpdateCanvasScale ();
685 Workspace.Invalidate ();
686 }
687
688 // Returns true if successful, false if canceled
689 public bool Save (bool saveAs)
690 {
691 return PintaCore.Actions.File.RaiseSaveDocument (this, saveAs);
692 }
693
694 public void SetCurrentLayer (int i)
695 {
696 current_layer = i;
697
698 PintaCore.Layers.OnSelectedLayerChanged ();
699 }
700
701 public void SetCurrentLayer (Layer layer)
702 {
703 current_layer = Layers.IndexOf (layer);
704
705 PintaCore.Layers.OnSelectedLayerChanged ();
706 }
707 #endregion
708
709 #region Protected Methods
710 protected void OnIsDirtyChanged ()
711 {
712 if (IsDirtyChanged != null)
713 IsDirtyChanged (this, EventArgs.Empty);
714 }
715
716 protected void OnRenamed ()
717 {
718 if (Renamed != null)
719 Renamed (this, EventArgs.Empty);
720 }
721 #endregion
722
723 #region Private Methods
724 private void RaiseLayerPropertyChangedEvent (object sender, PropertyChangedEventArgs e)
725 {
726 PintaCore.Layers.RaiseLayerPropertyChangedEvent (sender, e);
727 }
728 #endregion
729
730 #region Public Events
731 public event EventHandler IsDirtyChanged;
732 public event EventHandler Renamed;
733 #endregion
734 }
735}
0736
=== added file 'Pinta.Core/Classes/DocumentWorkspace.cs'
--- Pinta.Core/Classes/DocumentWorkspace.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Classes/DocumentWorkspace.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,273 @@
1//
2// DocumentWorkspace.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using Gdk;
29using Mono.Unix;
30
31namespace Pinta.Core
32{
33 public class DocumentWorkspace
34 {
35 private Document document;
36 private Size canvas_size;
37 private enum ZoomType
38 {
39 ZoomIn,
40 ZoomOut,
41 ZoomManually
42 }
43
44 internal DocumentWorkspace (Document document)
45 {
46 this.document = document;
47 History = new DocumentWorkspaceHistory (document, this);
48 }
49
50 #region Public Properties
51 public bool CanvasFitsInWindow {
52 get {
53 Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.Canvas.Parent;
54
55 int window_x = view.Allocation.Width;
56 int window_y = view.Children[0].Allocation.Height;
57
58 if (CanvasSize.Width <= window_x && CanvasSize.Height <= window_y)
59 return true;
60
61 return false;
62 }
63 }
64
65 public Size CanvasSize {
66 get { return canvas_size; }
67 set {
68 if (canvas_size.Width != value.Width || canvas_size.Height != value.Height) {
69 canvas_size = value;
70 PintaCore.Workspace.OnCanvasSizeChanged ();
71 }
72 }
73 }
74
75 public DocumentWorkspaceHistory History { get; private set; }
76
77 public bool ImageFitsInWindow {
78 get {
79 Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.Canvas.Parent;
80
81 int window_x = view.Allocation.Width;
82 int window_y = view.Children[0].Allocation.Height;
83
84 if (document.ImageSize.Width <= window_x && document.ImageSize.Height <= window_y)
85 return true;
86
87 return false;
88 }
89 }
90
91 public Cairo.PointD Offset {
92 get { return new Cairo.PointD ((PintaCore.Chrome.Canvas.Allocation.Width - canvas_size.Width) / 2, (PintaCore.Chrome.Canvas.Allocation.Height - canvas_size.Height) / 2); }
93 }
94
95 public double Scale {
96 get { return (double)CanvasSize.Width / (double)document.ImageSize.Width; }
97 set {
98 if (value != (double)CanvasSize.Width / (double)document.ImageSize.Width || value != (double)CanvasSize.Height / (double)document.ImageSize.Height) {
99 int new_x = Math.Max ((int)(document.ImageSize.Width * value), 1);
100 int new_y = Math.Max ((int)((new_x * document.ImageSize.Height) / document.ImageSize.Width), 1);
101
102 CanvasSize = new Gdk.Size (new_x, new_y);
103 Invalidate ();
104 }
105 }
106 }
107
108 #endregion
109
110 #region Public Methods
111 public void Invalidate ()
112 {
113 PintaCore.Workspace.OnCanvasInvalidated (new CanvasInvalidatedEventArgs ());
114 }
115
116 public void Invalidate (Gdk.Rectangle rect)
117 {
118 rect = new Gdk.Rectangle ((int)((rect.X) * Scale + Offset.X), (int)((rect.Y) * Scale + Offset.Y), (int)(rect.Width * Scale), (int)(rect.Height * Scale));
119 PintaCore.Workspace.OnCanvasInvalidated (new CanvasInvalidatedEventArgs (rect));
120 }
121
122 public bool PointInCanvas (Cairo.PointD point)
123 {
124 if (point.X < 0 || point.Y < 0)
125 return false;
126
127 if (point.X >= document.ImageSize.Width || point.Y >= document.ImageSize.Height)
128 return false;
129
130 return true;
131 }
132
133 public void RecenterView (double x, double y)
134 {
135 Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.Canvas.Parent;
136
137 view.Hadjustment.Value = Utility.Clamp (x * Scale - view.Hadjustment.PageSize / 2, view.Hadjustment.Lower, view.Hadjustment.Upper);
138 view.Vadjustment.Value = Utility.Clamp (y * Scale - view.Vadjustment.PageSize / 2, view.Vadjustment.Lower, view.Vadjustment.Upper);
139 }
140
141 public void ScrollCanvas (int dx, int dy)
142 {
143 Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.Canvas.Parent;
144
145 view.Hadjustment.Value = Utility.Clamp (dx + view.Hadjustment.Value, view.Hadjustment.Lower, view.Hadjustment.Upper - view.Hadjustment.PageSize);
146 view.Vadjustment.Value = Utility.Clamp (dy + view.Vadjustment.Value, view.Vadjustment.Lower, view.Vadjustment.Upper - view.Vadjustment.PageSize);
147 }
148
149 public Cairo.PointD WindowPointToCanvas (double x, double y)
150 {
151 return new Cairo.PointD (Math.Floor ((x - Offset.X) / PintaCore.Workspace.Scale), Math.Floor ((y - Offset.Y) / PintaCore.Workspace.Scale));
152 }
153
154 public void ZoomIn ()
155 {
156 ZoomAndRecenterView (ZoomType.ZoomIn, new Cairo.PointD (-1, -1)); // Zoom in relative to the center of the viewport.
157 }
158
159 public void ZoomOut ()
160 {
161 ZoomAndRecenterView (ZoomType.ZoomOut, new Cairo.PointD (-1, -1)); // Zoom out relative to the center of the viewport.
162 }
163
164 public void ZoomInFromMouseScroll (Cairo.PointD point)
165 {
166 ZoomAndRecenterView (ZoomType.ZoomIn, point); // Zoom in relative to mouse position.
167 }
168
169 public void ZoomOutFromMouseScroll (Cairo.PointD point)
170 {
171 ZoomAndRecenterView (ZoomType.ZoomOut, point); // Zoom out relative to mouse position.
172 }
173
174 public void ZoomManually ()
175 {
176 ZoomAndRecenterView (ZoomType.ZoomManually, new Cairo.PointD (-1, -1));
177 }
178
179 public void ZoomToRectangle (Cairo.Rectangle rect)
180 {
181 double ratio;
182
183 if (document.ImageSize.Width / rect.Width <= document.ImageSize.Height / rect.Height)
184 ratio = document.ImageSize.Width / rect.Width;
185 else
186 ratio = document.ImageSize.Height / rect.Height;
187
188 (PintaCore.Actions.View.ZoomComboBox.ComboBox as Gtk.ComboBoxEntry).Entry.Text = String.Format ("{0:F}%", ratio * 100.0);
189 Gtk.Main.Iteration (); //Force update of scrollbar upper before recenter
190 RecenterView (rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
191 }
192 #endregion
193
194 #region Private Methods
195 private void ZoomAndRecenterView (ZoomType zoomType, Cairo.PointD point)
196 {
197 if (zoomType == ZoomType.ZoomOut && (CanvasSize.Width == 1 || CanvasSize.Height ==1))
198 return; //Can't zoom in past a 1x1 px canvas
199
200 double zoom;
201
202 if (!ViewActions.TryParsePercent (PintaCore.Actions.View.ZoomComboBox.ComboBox.ActiveText, out zoom))
203 zoom = Scale * 100;
204
205 zoom = Math.Min (zoom, 3600);
206
207 PintaCore.Chrome.Canvas.GdkWindow.FreezeUpdates ();
208 PintaCore.Actions.View.SuspendZoomUpdate ();
209
210 Gtk.Viewport view = (Gtk.Viewport)PintaCore.Chrome.Canvas.Parent;
211
212 bool adjustOnMousePosition = point.X >= 0.0 && point.Y >= 0.0;
213
214 double center_x = adjustOnMousePosition ?
215 point.X : view.Hadjustment.Value + (view.Hadjustment.PageSize / 2.0);
216 double center_y = adjustOnMousePosition ?
217 point.Y : view.Vadjustment.Value + (view.Vadjustment.PageSize / 2.0);
218
219 center_x = (center_x - Offset.X) / Scale;
220 center_y = (center_y - Offset.Y) / Scale;
221
222 if (zoomType == ZoomType.ZoomIn || zoomType == ZoomType.ZoomOut) {
223 int i = 0;
224
225 Predicate<string> UpdateZoomLevel = zoomInList =>
226 {
227 switch (zoomType) {
228 case ZoomType.ZoomIn:
229 if (zoomInList == Catalog.GetString ("Window") || int.Parse (zoomInList.Trim ('%')) <= zoom) {
230 PintaCore.Actions.View.ZoomComboBox.ComboBox.Active = i - 1;
231 return true;
232 }
233
234 break;
235
236 case ZoomType.ZoomOut:
237 if (zoomInList == Catalog.GetString ("Window"))
238 return true;
239
240 if (int.Parse (zoomInList.Trim ('%')) < zoom) {
241 PintaCore.Actions.View.ZoomComboBox.ComboBox.Active = i;
242 return true;
243 }
244
245 break;
246 }
247
248 return false;
249 };
250
251 foreach (string item in PintaCore.Actions.View.ZoomCollection) {
252 if (UpdateZoomLevel (item))
253 break;
254
255 i++;
256 }
257 }
258
259 PintaCore.Actions.View.UpdateCanvasScale ();
260
261 // Quick fix : need to manually update Upper limit because the value is not changing after updating the canvas scale.
262 // TODO : I think there is an event need to be fired so that those values updated automatically.
263 view.Hadjustment.Upper = CanvasSize.Width < view.Hadjustment.PageSize ? view.Hadjustment.PageSize : CanvasSize.Width;
264 view.Vadjustment.Upper = CanvasSize.Height < view.Vadjustment.PageSize ? view.Vadjustment.PageSize : CanvasSize.Height;
265
266 RecenterView (center_x, center_y);
267
268 PintaCore.Actions.View.ResumeZoomUpdate ();
269 PintaCore.Chrome.Canvas.GdkWindow.ThawUpdates ();
270 }
271 #endregion
272 }
273}
0274
=== added file 'Pinta.Core/Classes/DocumentWorkspaceHistory.cs'
--- Pinta.Core/Classes/DocumentWorkspaceHistory.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Classes/DocumentWorkspaceHistory.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,172 @@
1//
2// DocumentWorkspace.cs
3//
4// Author:
5// Jonathan Pobst <monkey@jpobst.com>
6//
7// Copyright (c) 2010 Jonathan Pobst
8//
9// Permission is hereby granted, free of charge, to any person obtaining a copy
10// of this software and associated documentation files (the "Software"), to deal
11// in the Software without restriction, including without limitation the rights
12// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13// copies of the Software, and to permit persons to whom the Software is
14// furnished to do so, subject to the following conditions:
15//
16// The above copyright notice and this permission notice shall be included in
17// all copies or substantial portions of the Software.
18//
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25// THE SOFTWARE.
26
27using System;
28using System.Collections.Generic;
29using Gtk;
30
31namespace Pinta.Core
32{
33 public class DocumentWorkspaceHistory
34 {
35 private Document document;
36 private DocumentWorkspace workspace;
37 List<BaseHistoryItem> history = new List<BaseHistoryItem> ();
38 int historyPointer = -1;
39
40 internal DocumentWorkspaceHistory (Document document, DocumentWorkspace workspace)
41 {
42 this.document = document;
43 this.workspace = workspace;
44 ListStore = new ListStore (typeof (BaseHistoryItem));
45 }
46
47 public Gtk.ListStore ListStore { get; private set; }
48
49 public int Pointer {
50 get { return historyPointer; }
51 }
52
53 public BaseHistoryItem Current {
54 get {
55 if (historyPointer > -1 && historyPointer < history.Count)
56 return history[historyPointer];
57 else
58 return null;
59 }
60 }
61
62 public void PushNewItem (BaseHistoryItem newItem)
63 {
64
65 //Remove all old redos starting from the end of the list
66 for (int i = history.Count - 1; i >= 0; i--) {
67
68 BaseHistoryItem item = history[i];
69
70 if (item.State == HistoryItemState.Redo) {
71 history.RemoveAt(i);
72 item.Dispose();
73 //Remove from ListStore
74 ListStore.Remove (ref item.Id);
75
76 } else if (item.State == HistoryItemState.Undo) {
77 break;
78 }
79 }
80
81 //Add new undo to ListStore
82 newItem.Id = ListStore.AppendValues (newItem);
83 history.Add (newItem);
84 historyPointer = history.Count - 1;
85
86 if (newItem.CausesDirty)
87 document.IsDirty = true;
88
89 if (history.Count > 1) {
90 PintaCore.Actions.Edit.Undo.Sensitive = true;
91 CanUndo = true;
92 }
93
94 PintaCore.Actions.Edit.Redo.Sensitive = false;
95 CanRedo = false;
96 PintaCore.History.OnHistoryItemAdded (newItem);
97 }
98
99 public void Undo ()
100 {
101 // ensure that the current tool's modifications are added to the history first (e.g. editing text)
102 PintaCore.Tools.CurrentTool.DoCommit ();
103
104 if (historyPointer < 0) {
105 throw new InvalidOperationException ("Undo stack is empty");
106 } else {
107 BaseHistoryItem item = history[historyPointer];
108 item.Undo ();
109 item.State = HistoryItemState.Redo;
110 ListStore.SetValue (item.Id, 0, item);
111 history[historyPointer] = item;
112 historyPointer--;
113 }
114
115 if (historyPointer == 0) {
116 document.IsDirty = false;
117 PintaCore.Actions.Edit.Undo.Sensitive = false;
118 CanUndo = false;
119 }
120
121 PintaCore.Actions.Edit.Redo.Sensitive = true;
122 CanRedo = true;
123 PintaCore.History.OnActionUndone ();
124 }
125
126 public void Redo ()
127 {
128 if (historyPointer >= history.Count - 1)
129 throw new InvalidOperationException ("Redo stack is empty");
130
131 historyPointer++;
132 BaseHistoryItem item = history[historyPointer];
133 item.Redo ();
134 item.State = HistoryItemState.Undo;
135 ListStore.SetValue (item.Id, 0, item);
136 history[historyPointer] = item;
137
138 if (historyPointer == history.Count - 1) {
139 PintaCore.Actions.Edit.Redo.Sensitive = false;
140 CanRedo = false;
141 }
142
143 if (item.CausesDirty)
144 document.IsDirty = true;
145
146 if (history.Count > 1) {
147 PintaCore.Actions.Edit.Undo.Sensitive = true;
148 CanUndo = true;
149 }
150
151 PintaCore.History.OnActionRedone ();
152 }
153
154 public void Clear ()
155 {
156 history.ForEach (delegate(BaseHistoryItem item) { item.Dispose (); } );
157 history.Clear();
158 ListStore.Clear ();
159 historyPointer = -1;
160
161 document.IsDirty = false;
162 PintaCore.Actions.Edit.Redo.Sensitive = false;
163 PintaCore.Actions.Edit.Undo.Sensitive = false;
164
165 CanRedo = false;
166 CanUndo = false;
167 }
168
169 public bool CanRedo { get; private set; }
170 public bool CanUndo { get; private set; }
171 }
172}
0173
=== added file 'Pinta.Core/Classes/GradientRenderer.cs'
--- Pinta.Core/Classes/GradientRenderer.cs 1970-01-01 00:00:00 +0000
+++ Pinta.Core/Classes/GradientRenderer.cs 2013-01-23 15:01:21 +0000
@@ -0,0 +1,229 @@
1/////////////////////////////////////////////////////////////////////////////////
2// Paint.NET //
3// Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
4// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
5// See license-pdn.txt for full licensing and attribution details. //
6/////////////////////////////////////////////////////////////////////////////////
7
8using System;
9using System.Threading.Tasks;
10using System.Collections.Generic;
11using Cairo;
12using Rectangle = Gdk.Rectangle;
13
14namespace Pinta.Core
15{
16 public abstract class GradientRenderer
17 {
18 private BinaryPixelOp normalBlendOp;
19 private ColorBgra startColor;
20 private ColorBgra endColor;
21 private PointD startPoint;
22 private PointD endPoint;
23 private bool alphaBlending;
24 private bool alphaOnly;
25
26 private bool lerpCacheIsValid = false;
27 private byte[] lerpAlphas;
28 private ColorBgra[] lerpColors;
29
30 public ColorBgra StartColor {
31 get { return this.startColor; }
32
33 set {
34 if (this.startColor != value) {
35 this.startColor = value;
36 this.lerpCacheIsValid = false;
37 }
38 }
39 }
40
41 public ColorBgra EndColor {
42 get { return this.endColor; }
43
44 set {
45 if (this.endColor != value) {
46 this.endColor = value;
47 this.lerpCacheIsValid = false;
48 }
49 }
50 }
51
52 public PointD StartPoint {
53 get { return this.startPoint; }
54
55 set { this.startPoint = value; }
56 }
57
58 public PointD EndPoint {
59 get { return this.endPoint; }
60
61 set { this.endPoint = value; }
62 }
63
64 public bool AlphaBlending {
65 get { return this.alphaBlending; }
66
67 set { this.alphaBlending = value; }
68 }
69
70 public bool AlphaOnly {
71 get { return this.alphaOnly; }
72
73 set { this.alphaOnly = value; }
74 }
75
76 public virtual void BeforeRender ()
77 {
78 if (!this.lerpCacheIsValid) {
79 byte startAlpha;
80 byte endAlpha;
81
82 if (this.alphaOnly) {
83 ComputeAlphaOnlyValuesFromColors (this.startColor, this.endColor, out startAlpha, out endAlpha);
84 } else {
85 startAlpha = this.startColor.A;
86 endAlpha = this.endColor.A;
87 }
88
89 this.lerpAlphas = new byte[256];
90 this.lerpColors = new ColorBgra[256];
91
92 for (int i = 0; i < 256; ++i) {
93 byte a = (byte)i;
94 this.lerpColors[a] = ColorBgra.Blend (this.startColor, this.endColor, a);
95 this.lerpAlphas[a] = (byte)(startAlpha + ((endAlpha - startAlpha) * a) / 255);
96 }
97
98 this.lerpCacheIsValid = true;
99 }
100 }
101
102 public abstract byte ComputeByteLerp(int x, int y);
103
104 public virtual void AfterRender ()
105 {
106 }
107
108 private static void ComputeAlphaOnlyValuesFromColors (ColorBgra startColor, ColorBgra endColor, out byte startAlpha, out byte endAlpha)
109 {
110 startAlpha = startColor.A;
111 endAlpha = (byte)(255 - endColor.A);
112 }
113
114 unsafe public void Render (ImageSurface surface, Gdk.Rectangle[] rois)
115 {
116 byte startAlpha;
117 byte endAlpha;
118
119 if (this.alphaOnly) {
120 ComputeAlphaOnlyValuesFromColors (this.startColor, this.endColor, out startAlpha, out endAlpha);
121 } else {
122 startAlpha = this.startColor.A;
123 endAlpha = this.endColor.A;
124 }
125
126 surface.Flush ();
127
128 ColorBgra* src_data_ptr = (ColorBgra*)surface.DataPtr;
129 int src_width = surface.Width;
130
131 for (int ri = 0; ri < rois.Length; ++ri) {
132 Gdk.Rectangle rect = rois[ri];
133
134 if (this.startPoint.X == this.endPoint.X && this.startPoint.Y == this.endPoint.Y) {
135 // Start and End point are the same ... fill with solid color.
136 for (int y = rect.Top; y < rect.Bottom; ++y) {
137 ColorBgra* pixelPtr = surface.GetPointAddress(rect.Left, y);
138
139 for (int x = rect.Left; x < rect.Right; ++x) {
140 ColorBgra result;
141
142 if (this.alphaOnly && this.alphaBlending) {
143 byte resultAlpha = (byte)Utility.FastDivideShortByByte ((ushort)(pixelPtr->A * endAlpha), 255);
144 result = *pixelPtr;
145 result.A = resultAlpha;
146 } else if (this.alphaOnly && !this.alphaBlending) {
147 result = *pixelPtr;
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches