├── ScreenToGif.Cloud.YandexDisk.Tests ├── 1.txt ├── packages.config ├── Properties │ └── AssemblyInfo.cs └── YandexDiskTests.cs ├── Other ├── Translator │ ├── Logo.ico │ ├── App.config │ ├── Converters │ │ ├── NullToInvertedBool.cs │ │ └── MultiLineTitle.cs │ ├── Controls │ │ └── ExtendedTextBox.cs │ └── Themes │ │ └── Colors.xaml ├── HookTest │ ├── App.config │ ├── Properties │ │ ├── Settings.settings │ │ └── Settings.Designer.cs │ ├── App.xaml │ ├── App.xaml.cs │ ├── Util │ │ ├── CustomKeyEventArgs.cs │ │ ├── CustomKeyPressEventArgs.cs │ │ └── CustomMouseEventArgs.cs │ └── MainWindow.xaml.cs └── PositioningTest │ ├── App.config │ ├── Properties │ ├── Settings.settings │ └── Settings.Designer.cs │ ├── App.xaml │ ├── App.xaml.cs │ ├── MainWindow.xaml.cs │ └── MainWindow.xaml ├── ScreenToGif ├── Resources │ └── Logo.ico ├── Interfaces │ ├── IPersistent.cs │ ├── IPanel.cs │ ├── IFfmpegPreset.cs │ ├── IPreset.cs │ └── IExportPreset.cs ├── Util │ ├── MouseButtonType.cs │ ├── Exceptions │ │ └── GraphicsConfigurationException.cs │ ├── ScreenHelper.cs │ ├── Converters │ │ ├── EnumToBool.cs │ │ ├── KeysToString.cs │ │ ├── NullToVisibility.cs │ │ ├── InvertedEnumToBool.cs │ │ ├── IntToString.cs │ │ ├── BytesToSize.cs │ │ ├── EnumToVisibility.cs │ │ ├── InvertedEnumToVisibility.cs │ │ ├── ContentToVisibility.cs │ │ ├── PathToFilename.cs │ │ ├── InvertedBool.cs │ │ ├── KeyGestureToString.cs │ │ ├── HasEnumToVisibility.cs │ │ ├── BoolOrToInvertedVisibility.cs │ │ ├── BoolToOpacity.cs │ │ ├── MultiLineTitle.cs │ │ ├── TimeSpanToTotalMilliseconds.cs │ │ ├── BoolAndToVisibility.cs │ │ ├── BoolOrToVisibility.cs │ │ ├── CountToBool.cs │ │ ├── ScaleConverter.cs │ │ ├── DoubleToPercentage.cs │ │ ├── StringToStaticResource.cs │ │ ├── SourceToSize.cs │ │ ├── BoolOr.cs │ │ ├── BoolAnd.cs │ │ ├── BoolOrAndToVisibility.cs │ │ ├── CenterPopupConverter.cs │ │ ├── IntToDelayString.cs │ │ ├── IntToVisibility.cs │ │ ├── FormatConverter.cs │ │ ├── InvertedVisibility.cs │ │ ├── InvertedIntToVisibility.cs │ │ ├── DoubleToBool.cs │ │ ├── IntToBool.cs │ │ ├── SelectionCountToDescription.cs │ │ ├── AlphaToOpacity.cs │ │ ├── PercentageToOpacity.cs │ │ ├── InvertedBoolToVisibility.cs │ │ ├── IntToDecimal.cs │ │ ├── EnumToInt.cs │ │ ├── BoolAndOrOrToVisibility.cs │ │ ├── ColorToBrush.cs │ │ ├── StringToInt.cs │ │ ├── DoubleToInt.cs │ │ ├── DoubleTimesAHundredToInt.cs │ │ ├── CommandToKeyGesture.cs │ │ ├── RoutedCommandToInputGestureText.cs │ │ ├── TagToSelection.cs │ │ ├── StringToDoubleArray.cs │ │ ├── ShortcutKeys.cs │ │ ├── StylusTipToBool.cs │ │ ├── StageToButtonString.cs │ │ ├── UriToBitmap.cs │ │ ├── SelectionToEditingMode.cs │ │ ├── IntToRect.cs │ │ ├── DoubleToRadius.cs │ │ ├── ColorToAlpha.cs │ │ ├── StageToCanvas.cs │ │ ├── FontToSupportedGliph.cs │ │ └── SelectionToStylusShape.cs │ ├── FastRandom.cs │ ├── Secret.cs │ ├── InputHook │ │ ├── CustomKeyEventArgs.cs │ │ └── CustomKeyPressEventArgs.cs │ ├── StorageUtils.cs │ ├── Extras.cs │ ├── FunctionLoader.cs │ ├── ExtendedStack.cs │ ├── Serializer.cs │ ├── PathHelper.cs │ └── Global.cs ├── ImageUtil │ ├── Psd │ │ ├── AditionalLayers │ │ │ ├── IAditionalLayerInfo.cs │ │ │ ├── IMetadata.cs │ │ │ ├── Metadata.cs │ │ │ └── MetadataContent.cs │ │ ├── Image.cs │ │ ├── ImageResourceBlocks │ │ │ ├── IImageResource.cs │ │ │ └── ImageResources.cs │ │ ├── IPsdContent.cs │ │ ├── LayerAndMask.cs │ │ ├── ImageData.cs │ │ ├── Channel.cs │ │ └── LayerInfo.cs │ ├── Gif │ │ ├── Decoder │ │ │ ├── GifBlockKind.cs │ │ │ ├── GifTrailer.cs │ │ │ ├── GifDecoderException.cs │ │ │ ├── GifColor.cs │ │ │ ├── GifImageData.cs │ │ │ ├── GifCommentExtension.cs │ │ │ ├── GifBlock.cs │ │ │ ├── GifHeader.cs │ │ │ ├── GifExtension.cs │ │ │ └── GifFrame.cs │ │ └── Encoder │ │ │ └── Quantization │ │ │ └── MostUsedQuantizer.cs │ └── Apng │ │ └── Chunks │ │ └── IdatChunk.cs ├── Docs │ └── Documentation.md ├── Cloud │ ├── YandexDisk │ │ ├── Link.cs │ │ └── Error.cs │ ├── Gfycat │ │ ├── GfycatErrorResponse.cs │ │ ├── GfycatCreateResponse.cs │ │ ├── GfycatAuthRequest.cs │ │ └── GfycatCreateRequest.cs │ ├── Imgur │ │ ├── ImgurUploadResponse.cs │ │ └── ImgurAlbumsResponse.cs │ ├── UploadingException.cs │ ├── CloudFactory.cs │ ├── IUploader.cs │ └── OAuth2Token.cs ├── Model │ ├── Events │ │ ├── SaveEventArgs.cs │ │ └── ValidatedEventArgs.cs │ ├── UploadPresets │ │ ├── Custom │ │ │ └── CustomPreset.cs │ │ ├── Imgur │ │ │ └── ImgurAlbum.cs │ │ └── Yandex │ │ │ └── YandexPreset.cs │ ├── FosshubResponse.cs │ ├── ExportPresets │ │ ├── Video │ │ │ ├── Mkv │ │ │ │ └── MkvPreset.cs │ │ │ ├── Mov │ │ │ │ └── MovPreset.cs │ │ │ ├── Mp4 │ │ │ │ └── Mp4Preset.cs │ │ │ ├── Webm │ │ │ │ └── WebmPreset.cs │ │ │ ├── Avi │ │ │ │ └── AviPreset.cs │ │ │ └── Codecs │ │ │ │ ├── Mpeg2.cs │ │ │ │ └── Mpeg4.cs │ │ ├── AnimatedImage │ │ │ ├── Bpg │ │ │ │ └── BpgPreset.cs │ │ │ ├── Apng │ │ │ │ ├── ApngPreset.cs │ │ │ │ └── EmbeddedApngPreset.cs │ │ │ ├── Webp │ │ │ │ └── WebpPreset.cs │ │ │ ├── Gif │ │ │ │ ├── GifPreset.cs │ │ │ │ └── SystemGifPreset.cs │ │ │ └── AnimatedImagePreset.cs │ │ ├── Image │ │ │ ├── BmpPreset.cs │ │ │ ├── PngPreset.cs │ │ │ ├── JpegPreset.cs │ │ │ └── ImagePreset.cs │ │ └── Other │ │ │ ├── StgPreset.cs │ │ │ └── PsdPreset.cs │ ├── VideoSource.cs │ ├── FosshubItem.cs │ ├── MediaSource.cs │ ├── FosshubRelease.cs │ ├── ExportFrame.cs │ ├── ExportProject.cs │ └── FfmpegPreset.cs ├── UserControls │ ├── BorderPanel.xaml.cs │ ├── DelayPanel.xaml.cs │ ├── ResizePanel.xaml.cs │ ├── KeyStrokesPanel.xaml.cs │ ├── MouseClicksPanel.xaml.cs │ └── ProgressPanel.xaml.cs ├── packages.config ├── ModelEx │ ├── Sequences │ │ ├── BrushSequence.cs │ │ ├── ShapeSequence.cs │ │ ├── DrawingSequence.cs │ │ ├── SubSequences │ │ │ ├── KeyEvent.cs │ │ │ ├── Shadow.cs │ │ │ ├── Frame.cs │ │ │ └── CursorEvent.cs │ │ ├── CursorSequence.cs │ │ ├── ObfuscationSequence.cs │ │ ├── KeySequence.cs │ │ ├── ProgressSequence.cs │ │ ├── SizeableSequence.cs │ │ ├── TextSequence.cs │ │ └── RasterSequence.cs │ └── Track.cs ├── Controls │ ├── Ribbon │ │ ├── ItemSizeDefinition.cs │ │ ├── GroupSizeDefinition.cs │ │ ├── RibbonGroupPanel.cs │ │ └── RibbonTab.cs │ ├── ExtendedSlider.cs │ ├── Items │ │ ├── EncoderItem.cs │ │ ├── QuantizationMethodItem.cs │ │ └── ExportItem.cs │ ├── WebcamControl.xaml │ ├── Shapes │ │ └── Triangle.cs │ ├── BaseWindow.cs │ ├── ExtendedProgressBar.cs │ └── IntegerUpDown.cs ├── Settings │ ├── Migrations │ │ ├── Migration2_28_0To2_29_0.cs │ │ └── Migration2_29_0To2_31_0.cs │ └── Migrations.cs ├── Extensions │ ├── PropertyExtensions.cs │ ├── PresetExtensions.cs │ └── ParseExtensions.cs ├── ViewModel │ ├── FrameViewModel.cs │ └── WebcamViewModel.cs ├── Windows │ └── Other │ │ ├── TextDialog.xaml.cs │ │ ├── FeedbackPreview.xaml.cs │ │ ├── RegionSelector.xaml │ │ ├── CommandPreviewer.xaml.cs │ │ ├── RegionMagnifier.xaml.cs │ │ ├── FeedbackPreview.xaml │ │ └── GoTo.xaml.cs ├── App.config ├── Capture │ └── ICapture.cs └── Readme.md ├── ScreenToGif.Tests ├── TestData │ ├── b1.bmp │ └── b2.bmp ├── ImageMethods.cs └── ScreenToGif.Tests.csproj ├── CONTRIBUTING.md ├── .editorconfig ├── .gitignore └── .github ├── FUNDING.yml └── workflows └── discord-releases.yml /ScreenToGif.Cloud.YandexDisk.Tests/1.txt: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /Other/Translator/Logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vczh/ScreenToGif/HEAD/Other/Translator/Logo.ico -------------------------------------------------------------------------------- /ScreenToGif/Resources/Logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vczh/ScreenToGif/HEAD/ScreenToGif/Resources/Logo.ico -------------------------------------------------------------------------------- /ScreenToGif.Tests/TestData/b1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vczh/ScreenToGif/HEAD/ScreenToGif.Tests/TestData/b1.bmp -------------------------------------------------------------------------------- /ScreenToGif.Tests/TestData/b2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vczh/ScreenToGif/HEAD/ScreenToGif.Tests/TestData/b2.bmp -------------------------------------------------------------------------------- /ScreenToGif/Interfaces/IPersistent.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Interfaces 2 | { 3 | interface IPersistent 4 | { 5 | void Persist(); 6 | } 7 | } -------------------------------------------------------------------------------- /ScreenToGif/Interfaces/IPanel.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace ScreenToGif.Interfaces 4 | { 5 | public interface IPanel 6 | { 7 | Task IsValid(); 8 | } 9 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/MouseButtonType.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Util 2 | { 3 | public enum MouseButtonType 4 | { 5 | None, 6 | Left, 7 | Middle, 8 | Right 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Other/HookTest/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Other/Translator/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Other/PositioningTest/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Psd/AditionalLayers/IAditionalLayerInfo.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.ImageUtil.Psd.AditionalLayers 2 | { 3 | interface IAditionalLayerInfo : IPsdContent 4 | { 5 | string Key { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Psd/Image.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.ImageUtil.Psd 2 | { 3 | internal class Image : IPsdContent 4 | { 5 | public long Length { get; } 6 | 7 | public byte[] Content { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /Other/HookTest/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Other/PositioningTest/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ScreenToGif/Docs/Documentation.md: -------------------------------------------------------------------------------- 1 | ## ScreenToGif Developer Documentation 2 | 3 | Would you like to help build this developer documentation? 4 | 5 | ### Sections 6 | 7 | From an user perspective, the app is divided into two main parts, the recorders and the editor. -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Gif/Decoder/GifBlockKind.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.ImageUtil.Gif.Decoder 2 | { 3 | public enum GifBlockKind 4 | { 5 | Control, 6 | GraphicRendering, 7 | SpecialPurpose, 8 | Other 9 | } 10 | } -------------------------------------------------------------------------------- /ScreenToGif/Cloud/YandexDisk/Link.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace ScreenToGif.Cloud.YandexDisk 4 | { 5 | [DataContract] 6 | public class Link 7 | { 8 | [DataMember] 9 | public string href { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Psd/AditionalLayers/IMetadata.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.ImageUtil.Psd.AditionalLayers 2 | { 3 | interface IMetadata : IAditionalLayerInfo 4 | { 5 | string Signature { get; } 6 | 7 | bool CopyOnSheetDuplication { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /ScreenToGif.Cloud.YandexDisk.Tests/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ScreenToGif/Interfaces/IFfmpegPreset.cs: -------------------------------------------------------------------------------- 1 | using ScreenToGif.Util; 2 | 3 | namespace ScreenToGif.Interfaces 4 | { 5 | public interface IFfmpegPreset 6 | { 7 | VideoSettingsMode SettingsMode { get; set; } 8 | 9 | string Parameters { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/Events/SaveEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace ScreenToGif.Model.Events 4 | { 5 | public class SaveEventArgs : RoutedEventArgs 6 | { 7 | public SaveEventArgs(RoutedEvent routedEvent) : base(routedEvent) 8 | { } 9 | } 10 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/UploadPresets/Custom/CustomPreset.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Model.UploadPresets.Custom 2 | { 3 | public class CustomPreset : UploadPreset 4 | { 5 | //Custom uploader. 6 | //List of calls, with address, input and output. 7 | //Data flow. 8 | } 9 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/FosshubResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace ScreenToGif.Model 4 | { 5 | [DataContract] 6 | public class FosshubResponse 7 | { 8 | [DataMember(Name = "release")] 9 | public FosshubRelease Release { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /ScreenToGif/UserControls/BorderPanel.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ScreenToGif.UserControls 4 | { 5 | public partial class BorderPanel : UserControl 6 | { 7 | public BorderPanel() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /ScreenToGif/UserControls/DelayPanel.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ScreenToGif.UserControls 4 | { 5 | public partial class DelayPanel : UserControl 6 | { 7 | public DelayPanel() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /ScreenToGif/UserControls/ResizePanel.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ScreenToGif.UserControls 4 | { 5 | public partial class ResizePanel : UserControl 6 | { 7 | public ResizePanel() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /ScreenToGif/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Psd/ImageResourceBlocks/IImageResource.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.ImageUtil.Psd.ImageResourceBlocks 2 | { 3 | internal interface IImageResource 4 | { 5 | ushort Identifier { get; set; } 6 | 7 | string Name { get; set; } 8 | 9 | byte[] Content { get; } 10 | } 11 | } -------------------------------------------------------------------------------- /ScreenToGif/UserControls/KeyStrokesPanel.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ScreenToGif.UserControls 4 | { 5 | public partial class KeyStrokesPanel : UserControl 6 | { 7 | public KeyStrokesPanel() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /ScreenToGif/UserControls/MouseClicksPanel.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace ScreenToGif.UserControls 4 | { 5 | public partial class MouseClicksPanel : UserControl 6 | { 7 | public MouseClicksPanel() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Rules to follow for this project: 2 | 3 | * Every feature should be packed into the main executable, unless it's optional like FFmpeg, SharpDx and Gifski. 4 | * To be accepted, any big feature or change should be discussed first with the maintainer of the project. 5 | * PRs shoulkd be directed to the dev branch. 6 | -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Psd/IPsdContent.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.ImageUtil.Psd 2 | { 3 | internal interface IPsdContent 4 | { 5 | /// 6 | /// The total length of the byte array. 7 | /// 8 | long Length { get; } 9 | 10 | byte[] Content { get; } 11 | } 12 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Exceptions/GraphicsConfigurationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ScreenToGif.Util.Exceptions 4 | { 5 | public class GraphicsConfigurationException : Exception 6 | { 7 | public GraphicsConfigurationException(string message, Exception exception) : base(message, exception) 8 | { } 9 | } 10 | } -------------------------------------------------------------------------------- /Other/HookTest/App.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ScreenToGif/Interfaces/IPreset.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using ScreenToGif.Model.Events; 3 | 4 | namespace ScreenToGif.Interfaces 5 | { 6 | public interface IPreset 7 | { 8 | string Title { get; set; } 9 | 10 | string Description { get; set; } 11 | 12 | Task IsValid(); 13 | } 14 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/Video/Mkv/MkvPreset.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Model.ExportPresets.Video.Mkv 2 | { 3 | public class MkvPreset : VideoPreset 4 | { 5 | public MkvPreset() 6 | { 7 | Type = Util.Export.Mkv; 8 | DefaultExtension = ".mkv"; 9 | Extension = ".mkv"; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/Video/Mov/MovPreset.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Model.ExportPresets.Video.Mov 2 | { 3 | public class MovPreset : VideoPreset 4 | { 5 | public MovPreset() 6 | { 7 | Type = Util.Export.Mov; 8 | DefaultExtension = ".mov"; 9 | Extension = ".mov"; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/Video/Mp4/Mp4Preset.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Model.ExportPresets.Video.Mp4 2 | { 3 | public class Mp4Preset : VideoPreset 4 | { 5 | public Mp4Preset() 6 | { 7 | Type = Util.Export.Mp4; 8 | DefaultExtension = ".mp4"; 9 | Extension = ".mp4"; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/BrushSequence.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Media; 2 | 3 | namespace ScreenToGif.ModelEx.Sequences 4 | { 5 | public class BrushSequence : SizeableSequence 6 | { 7 | public Brush Brush { get; set; } 8 | 9 | 10 | public BrushSequence() 11 | { 12 | Type = Types.Brush; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/ShapeSequence.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Shapes; 2 | 3 | namespace ScreenToGif.ModelEx.Sequences 4 | { 5 | public class ShapeSequence : SizeableSequence 6 | { 7 | public Shape Shape { get; set; } 8 | 9 | 10 | public ShapeSequence() 11 | { 12 | Type = Types.Shape; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/Video/Webm/WebmPreset.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Model.ExportPresets.Video.Webm 2 | { 3 | public class WebmPreset : VideoPreset 4 | { 5 | public WebmPreset() 6 | { 7 | Type = Util.Export.Webm; 8 | DefaultExtension = ".webm"; 9 | Extension = ".webm"; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/DrawingSequence.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Ink; 2 | 3 | namespace ScreenToGif.ModelEx.Sequences 4 | { 5 | public class DrawingSequence : Sequence 6 | { 7 | public StrokeCollection Strokes { get; set; } 8 | 9 | 10 | public DrawingSequence() 11 | { 12 | Type = Types.Drawing; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/AnimatedImage/Bpg/BpgPreset.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Model.ExportPresets.AnimatedImage.Bpg 2 | { 3 | public class BpgPreset : AnimatedImagePreset 4 | { 5 | public BpgPreset() 6 | { 7 | Type = Util.Export.Bpg; 8 | DefaultExtension = ".bpg"; 9 | Extension = ".bpg"; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/SubSequences/KeyEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | 4 | namespace ScreenToGif.ModelEx.Sequences.SubSequences 5 | { 6 | public class KeyEvent 7 | { 8 | public Key Key { get; set; } 9 | 10 | public ModifierKeys Modifiers { get; set; } 11 | 12 | public TimeSpan TimeStamp { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/AnimatedImage/Apng/ApngPreset.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Model.ExportPresets.AnimatedImage.Apng 2 | { 3 | public class ApngPreset : AnimatedImagePreset 4 | { 5 | public ApngPreset() 6 | { 7 | Type = Util.Export.Apng; 8 | DefaultExtension = ".apng"; 9 | Extension = ".apng"; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/AnimatedImage/Webp/WebpPreset.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Model.ExportPresets.AnimatedImage.Webp 2 | { 3 | public class WebpPreset : AnimatedImagePreset 4 | { 5 | public WebpPreset() 6 | { 7 | Type = Util.Export.Webp; 8 | DefaultExtension = ".webp"; 9 | Extension = ".webp"; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/Video/Avi/AviPreset.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Model.ExportPresets.Video.Avi 2 | { 3 | public class AviPreset : VideoPreset 4 | { 5 | public AviPreset() 6 | { 7 | Type = Util.Export.Avi; 8 | DefaultExtension = ".avi"; 9 | Extension = ".avi"; 10 | IsAncientContainer = true; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/ScreenHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Interop; 3 | 4 | namespace ScreenToGif.Util 5 | { 6 | public class ScreenHelper 7 | { 8 | public static System.Windows.Forms.Screen GetScreen(Window window) 9 | { 10 | return System.Windows.Forms.Screen.FromHandle(new WindowInteropHelper(window).Handle); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ScreenToGif/Controls/Ribbon/ItemSizeDefinition.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Controls.Ribbon 2 | { 3 | public class ItemSizeDefinition 4 | { 5 | public enum IconSizeEnum 6 | { 7 | Large, 8 | Small 9 | } 10 | 11 | public IconSizeEnum IconSize { get; set; } = IconSizeEnum.Large; 12 | public bool IsHeaderVisible { get; set; } = true; 13 | } 14 | } -------------------------------------------------------------------------------- /Other/HookTest/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace HookTest 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Other/PositioningTest/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Other/PositioningTest/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace PositioningTest 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ScreenToGif/Controls/Ribbon/GroupSizeDefinition.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows.Markup; 3 | 4 | namespace ScreenToGif.Controls.Ribbon 5 | { 6 | [ContentProperty("SizeDefinitions")] 7 | public class GroupSizeDefinition 8 | { 9 | public List SizeDefinitions { get; set; } = new List(); 10 | 11 | public bool IsCollapsed { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /ScreenToGif/Cloud/YandexDisk/Error.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace ScreenToGif.Cloud.YandexDisk 4 | { 5 | [DataContract] 6 | public class ErrorDescriptor 7 | { 8 | [DataMember] 9 | public string message { get; set; } 10 | 11 | [DataMember] 12 | public string description { get; set; } 13 | 14 | [DataMember] 15 | public string error { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/CursorSequence.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using ScreenToGif.ModelEx.Sequences.SubSequences; 3 | 4 | namespace ScreenToGif.ModelEx.Sequences 5 | { 6 | public class CursorSequence : SizeableSequence 7 | { 8 | public List CursorEvents { get; set; } 9 | 10 | 11 | public CursorSequence() 12 | { 13 | Type = Types.Cursor; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /ScreenToGif/Cloud/Gfycat/GfycatErrorResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace ScreenToGif.Cloud.Gfycat 4 | { 5 | [DataContract] 6 | public class GfycatErrorResponse 7 | { 8 | [DataMember(Name = "code", EmitDefaultValue = false)] 9 | public string Code { get; set; } 10 | 11 | [DataMember(Name = "description", EmitDefaultValue = false)] 12 | public string Description { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Gif/Decoder/GifTrailer.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.ImageUtil.Gif.Decoder 2 | { 3 | public class GifTrailer : GifBlock 4 | { 5 | internal const int TrailerByte = 0x3B; 6 | 7 | private GifTrailer() 8 | {} 9 | 10 | public override GifBlockKind Kind => GifBlockKind.Other; 11 | 12 | internal static GifTrailer ReadTrailer() 13 | { 14 | return new GifTrailer(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/SubSequences/Shadow.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Media; 2 | 3 | namespace ScreenToGif.ModelEx.Sequences.SubSequences 4 | { 5 | public class Shadow 6 | { 7 | public Color Color { get;set; } 8 | 9 | public double Direction { get; set; } 10 | 11 | public double BlurRadius { get; set; } 12 | 13 | public double Opacity { get; set; } 14 | 15 | public double Depth { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /ScreenToGif/Cloud/Imgur/ImgurUploadResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace ScreenToGif.Cloud.Imgur 4 | { 5 | [DataContract] 6 | internal class ImgurUploadResponse 7 | { 8 | [DataMember(Name = "data")] 9 | public ImgurImageData Data { get; set; } 10 | 11 | [DataMember(Name = "success")] 12 | public bool Success { get; set; } 13 | 14 | [DataMember(Name = "status")] 15 | public int Status { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /ScreenToGif/Cloud/UploadingException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ScreenToGif.Cloud 4 | { 5 | public class UploadingException : Exception 6 | { 7 | public UploadingException() : base("Uploading failed") 8 | { 9 | 10 | } 11 | 12 | public UploadingException(string message) : base(message) 13 | { 14 | } 15 | 16 | public UploadingException(string message, Exception innerException) : base(message, innerException) 17 | { 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/ObfuscationSequence.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.ModelEx.Sequences 2 | { 3 | public class ObfuscationSequence : SizeableSequence 4 | { 5 | public enum Modes : int 6 | { 7 | Pixelate, 8 | Blur 9 | } 10 | 11 | public Modes ObfuscationMode { get; set; } 12 | 13 | //ObfuscationSize, other properties. 14 | 15 | 16 | public ObfuscationSequence() 17 | { 18 | Type = Types.Obfuscation; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/VideoSource.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | 4 | namespace ScreenToGif.Model 5 | { 6 | [DebuggerDisplay("Name = {Name}, MediaSources: {MediaSources.Count}")] 7 | public class VideoSource 8 | { 9 | public string Name { get; set; } 10 | 11 | public string SymbolicLink { get; set; } 12 | 13 | public bool IsFromHardware { get; set; } 14 | 15 | public List MediaSources { get; set; } = new List(); 16 | } 17 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/KeySequence.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using ScreenToGif.ModelEx.Sequences.SubSequences; 3 | 4 | namespace ScreenToGif.ModelEx.Sequences 5 | { 6 | /// 7 | /// KeyEvents can happen out of sync with the recording. 8 | /// 9 | public class KeySequence : SizeableSequence 10 | { 11 | public List KeyEvents { get; set; } 12 | 13 | 14 | public KeySequence() 15 | { 16 | Type = Types.Key; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /ScreenToGif/Cloud/Imgur/ImgurAlbumsResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.Serialization; 3 | 4 | namespace ScreenToGif.Cloud.Imgur 5 | { 6 | [DataContract] 7 | public class ImgurAlbumsResponse 8 | { 9 | [DataMember(Name = "data")] 10 | public List Data { get; set; } 11 | 12 | [DataMember(Name = "success")] 13 | public bool Success { get; set; } 14 | 15 | [DataMember(Name = "status")] 16 | public int Status { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /Other/HookTest/Util/CustomKeyEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Input; 7 | 8 | namespace HookTest.Util 9 | { 10 | public class CustomKeyEventArgs : EventArgs 11 | { 12 | public Keys Key { get; private set; } 13 | 14 | public bool Handled { get; private set; } 15 | 16 | public CustomKeyEventArgs(Keys key) 17 | { 18 | Key = key; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ScreenToGif/Model/FosshubItem.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace ScreenToGif.Model 4 | { 5 | [DataContract] 6 | public class FosshubItem 7 | { 8 | [DataMember(Name = "title")] 9 | public string Title { get; set; } 10 | 11 | [DataMember(Name = "link")] 12 | public string Link { get; set; } 13 | 14 | [DataMember(Name = "type")] 15 | public string Type { get; set; } 16 | 17 | [DataMember(Name = "version")] 18 | public string Version { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Track.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ScreenToGif.ModelEx 4 | { 5 | public class Track 6 | { 7 | public int Id { get; set; } 8 | 9 | public bool IsVisible { get; set; } 10 | 11 | public bool IsLocked { get; set; } 12 | 13 | public string Name { get; set; } 14 | 15 | /// 16 | /// A track can have multiple sequences of the same type. 17 | /// 18 | public List Sequences { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/MediaSource.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | 3 | namespace ScreenToGif.Model 4 | { 5 | [DebuggerDisplay("Resolution = {Width}x{Height}, Framerate: {Framerate}, Format: {Format}")] 6 | public class MediaSourceType 7 | { 8 | public int StreamIndex { get; set; } 9 | 10 | public int MediaIndex { get; set; } 11 | 12 | public int Width { get; set; } 13 | 14 | public int Height { get; set; } 15 | 16 | public double Framerate { get; set; } 17 | 18 | public string Format { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /ScreenToGif/Controls/Ribbon/RibbonGroupPanel.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | 4 | namespace ScreenToGif.Controls.Ribbon 5 | { 6 | public class RibbonGroupPanel : Panel 7 | { 8 | protected override Size ArrangeOverride(Size finalSize) 9 | { 10 | //? 11 | 12 | return base.ArrangeOverride(finalSize); 13 | } 14 | 15 | protected override Size MeasureOverride(Size availableSize) 16 | { 17 | 18 | return base.MeasureOverride(availableSize); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/ProgressSequence.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.ModelEx.Sequences 2 | { 3 | public class ProgressSequence : SizeableSequence 4 | { 5 | public enum Modes : int 6 | { 7 | Test, 8 | Bar 9 | } 10 | 11 | public Modes ProgressMode { get; set; } 12 | 13 | //Color. 14 | //Bar percentage. 15 | //How to calculate the correct text to be shown? 16 | 17 | 18 | public ProgressSequence() 19 | { 20 | Type = Types.Progress; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /ScreenToGif/Settings/Migrations/Migration2_28_0To2_29_0.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ScreenToGif.Settings.Migrations 4 | { 5 | internal class Migration2_28_0To2_29_0 6 | { 7 | internal static bool Up(List properties) 8 | { 9 | //Remove deprecated properties. 10 | var removeKeys = new List 11 | { 12 | "AsyncRecording" 13 | }; 14 | properties.RemoveAll(r => removeKeys.Contains(r.Key)); 15 | 16 | return true; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/SubSequences/Frame.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.ModelEx.Sequences.SubSequences 2 | { 3 | public class Frame 4 | { 5 | /// 6 | /// The time, in miliseconds that the frame should be visible. 7 | /// 8 | public uint Delay { get; set; } 9 | 10 | public double Left { get; set; } 11 | 12 | public double Top { get; set; } 13 | 14 | public double Width { get; set; } 15 | 16 | public double Height { get; set; } 17 | 18 | internal byte[] Pixels { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /ScreenToGif/Controls/ExtendedSlider.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | 4 | namespace ScreenToGif.Controls 5 | { 6 | internal class ExtendedSlider : Slider 7 | { 8 | public static readonly DependencyProperty ShowNumbersProperty = DependencyProperty.Register(nameof(ShowNumbers), typeof(bool), typeof(ExtendedSlider), new PropertyMetadata(default(bool))); 9 | 10 | public bool ShowNumbers 11 | { 12 | get => (bool) GetValue(ShowNumbersProperty); 13 | set => SetValue(ShowNumbersProperty, value); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /ScreenToGif/Controls/Items/EncoderItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | 4 | namespace ScreenToGif.Controls.Items 5 | { 6 | public class EncoderItem : GenericItem 7 | { 8 | public static readonly DependencyProperty EncoderTypeProperty = DependencyProperty.Register(nameof(EncoderType), typeof(Enum), typeof(EncoderItem), 9 | new PropertyMetadata(default(Enum))); 10 | 11 | public Enum EncoderType 12 | { 13 | get => (Enum) GetValue(EncoderTypeProperty); 14 | set => SetValue(EncoderTypeProperty, value); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Other/Translator/Converters/NullToInvertedBool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace Translator.Converters 6 | { 7 | public class NullToInvertedBool : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | return value == null; 12 | } 13 | 14 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 15 | { 16 | return Binding.DoNothing; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ScreenToGif/Controls/WebcamControl.xaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/AnimatedImage/Gif/GifPreset.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Model.ExportPresets.AnimatedImage.Gif 2 | { 3 | public class GifPreset : AnimatedImagePreset 4 | { 5 | private bool _useGlobalColorTable; 6 | 7 | 8 | public bool UseGlobalColorTable 9 | { 10 | get => _useGlobalColorTable; 11 | set => SetProperty(ref _useGlobalColorTable, value); 12 | } 13 | 14 | 15 | public GifPreset() 16 | { 17 | Type = Util.Export.Gif; 18 | DefaultExtension = ".gif"; 19 | Extension = ".gif"; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | end_of_line = crlf 9 | insert_final_newline = false 10 | indent_style = space 11 | indent_size = 4 12 | trim_trailing_whitespace = true 13 | 14 | # Markdown files 15 | [*.{md}] 16 | indent_size = 2 17 | 18 | # Visual Studio Solution Files 19 | [*.sln] 20 | indent_style = tab 21 | 22 | # Visual Studio XML Project Files 23 | [*.{csproj,vbproj,vcxproj.filters,proj,projitems,shproj}] 24 | indent_size = 2 25 | 26 | # XML Configuration Files 27 | [*.{xml,config,props,targets,nuspec,resx,ruleset,vsixmanifest,vsct}] 28 | indent_size = 2 -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Gif/Decoder/GifDecoderException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ScreenToGif.ImageUtil.Gif.Decoder 4 | { 5 | [Serializable] 6 | public class GifDecoderException : Exception 7 | { 8 | public GifDecoderException() { } 9 | 10 | public GifDecoderException(string message) : base(message) { } 11 | 12 | public GifDecoderException(string message, Exception inner) : base(message, inner) { } 13 | 14 | public GifDecoderException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) 15 | : base(info, context) { } 16 | } 17 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Gif/Decoder/GifColor.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.ImageUtil.Gif.Decoder 2 | { 3 | public struct GifColor 4 | { 5 | private readonly byte _r; 6 | private readonly byte _g; 7 | private readonly byte _b; 8 | 9 | public GifColor(byte r, byte g, byte b) 10 | { 11 | _r = r; 12 | _g = g; 13 | _b = b; 14 | } 15 | 16 | public byte R => _r; 17 | public byte G => _g; 18 | public byte B => _b; 19 | 20 | public override string ToString() 21 | { 22 | return $"#{_r:x2}{_g:x2}{_b:x2}"; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/SizeableSequence.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.ModelEx.Sequences 2 | { 3 | /// 4 | /// Primitive sequence object which has a defined sizing information. 5 | /// 6 | public class SizeableSequence : Sequence 7 | { 8 | public double Left { get; set; } 9 | 10 | public double Top { get; set; } 11 | 12 | public double Width { get; set; } 13 | 14 | public double Height { get; set; } 15 | 16 | public double Angle { get; set; } 17 | 18 | public double HorizontalDpi { get; set; } 19 | 20 | public double VerticalDpi { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/EnumToBool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Data; 3 | 4 | namespace ScreenToGif.Util.Converters 5 | { 6 | public class EnumToBool: IValueConverter 7 | { 8 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 9 | { 10 | return value?.Equals(parameter) == true; 11 | } 12 | 13 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 14 | { 15 | return value?.Equals(true) == true ? parameter : Binding.DoNothing; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/KeysToString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | using System.Windows.Input; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | class KeysToString : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | var keys = value as Key?; 13 | 14 | return keys?.ToString(); 15 | } 16 | 17 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 18 | { 19 | return value; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /GifRecorder.v12.suo 6 | /.vs 7 | /GifRecorder 8 | /ScreenToGif/ScreenToGif.csproj.user 9 | /GifRecorder.v12-Notebook-Nicke.suo 10 | /GifRecorder.suo 11 | /GifRecorder.sln.DotSettings.user 12 | /GifRecorder.sdf 13 | /GifRecorder.sln.DotSettings 14 | ScreenToGif/Util/Secret.cs 15 | /ScreenToGif/Util/Secret.cs 16 | 17 | /Other/Translator/Translator.csproj.user 18 | /ScreenToGif.UWP 19 | /packages 20 | obj 21 | bin 22 | -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/NullToVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class NullToVisibility : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | return value == null ? Visibility.Visible : Visibility.Collapsed; 13 | } 14 | 15 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 16 | { 17 | return Binding.DoNothing; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/InvertedEnumToBool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Data; 3 | 4 | namespace ScreenToGif.Util.Converters 5 | { 6 | public class InvertedEnumToBool : IValueConverter 7 | { 8 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 9 | { 10 | return value?.Equals(parameter) == false; 11 | } 12 | 13 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 14 | { 15 | return value?.Equals(true) == false ? parameter : Binding.DoNothing; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/FastRandom.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Util 2 | { 3 | public class FastRandom 4 | { 5 | private const double RealUnitInt = 1.0/(int.MaxValue + 1.0); 6 | 7 | private uint x, y, z, w; 8 | 9 | public FastRandom(uint seed) 10 | { 11 | x = seed; 12 | y = 842502087; 13 | z = 3579807591; 14 | w = 273326509; 15 | } 16 | 17 | public int Next(int upperBound) 18 | { 19 | var t = (x ^ (x << 11)); x = y; y = z; z = w; 20 | return (int) ((RealUnitInt*(int) (0x7FFFFFFF & (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)))))*upperBound); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/IntToString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace ScreenToGif.Util.Converters 6 | { 7 | public class IntToString : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | if (!(value is int number)|| number == 0) 12 | return ""; 13 | 14 | return number.ToString(); 15 | } 16 | 17 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 18 | { 19 | return value; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /ScreenToGif/Cloud/CloudFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ScreenToGif.Util; 3 | 4 | namespace ScreenToGif.Cloud 5 | { 6 | public class CloudFactory 7 | { 8 | public static IUploader CreateCloud(UploadType service) 9 | { 10 | switch (service) 11 | { 12 | case UploadType.Imgur: 13 | return new Imgur.Imgur(); 14 | case UploadType.Gfycat: 15 | return new Gfycat.Gfycat(); 16 | case UploadType.Yandex: 17 | return new YandexDisk.YandexDisk(); 18 | } 19 | 20 | throw new NotImplementedException(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /ScreenToGif/Extensions/PropertyExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ScreenToGif.Settings; 3 | 4 | namespace ScreenToGif.Extensions 5 | { 6 | internal static class PropertyExtensions 7 | { 8 | internal static bool AsBoolean(this Property prop) 9 | { 10 | return prop == null || prop.Value.TryParseBoolean(); 11 | } 12 | 13 | internal static DateTime? AsNullableDateTime(this Property prop) 14 | { 15 | return prop?.Value.TryParseDateTimeNullable(); 16 | } 17 | 18 | internal static int AsInteger(this Property prop) 19 | { 20 | return prop?.Value.TryParseInteger() ?? 0; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /ScreenToGif/ViewModel/FrameViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.ViewModel 2 | { 3 | public class FrameViewModel : BaseViewModel 4 | { 5 | private string _image; 6 | private int _number; 7 | private int _delay; 8 | 9 | 10 | public string Image 11 | { 12 | get => _image; 13 | set => SetProperty(ref _image, value); 14 | } 15 | 16 | public int Number 17 | { 18 | get => _number; 19 | set => SetProperty(ref _number, value); 20 | } 21 | 22 | public int Delay 23 | { 24 | get => _delay; 25 | set => SetProperty(ref _delay, value); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /ScreenToGif/Controls/Shapes/Triangle.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | using System.Windows.Media; 3 | using System.Windows.Shapes; 4 | 5 | namespace ScreenToGif.Controls.Shapes 6 | { 7 | internal class Triangle : Shape 8 | { 9 | protected override Geometry DefiningGeometry => Geometry.Parse($"M {(Width/2d).ToString(CultureInfo.InvariantCulture)},{(StrokeThickness / 2d).ToString(CultureInfo.InvariantCulture)} L{(Width - (StrokeThickness / 2d)).ToString(CultureInfo.InvariantCulture)},{(Height - (StrokeThickness / 2d)).ToString(CultureInfo.InvariantCulture)} L {(StrokeThickness / 2d).ToString(CultureInfo.InvariantCulture)},{(Height - (StrokeThickness / 2d)).ToString(CultureInfo.InvariantCulture)} z"); 10 | } 11 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Secret.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Util 2 | { 3 | public static class Secret 4 | { 5 | public static string ServerAddress { get; set; } 6 | 7 | public static string Email { get; set; } 8 | 9 | public static string Password { get; set; } 10 | 11 | public static int Port { get; set; } 12 | 13 | public static string Host { get; set; } 14 | 15 | 16 | public static string ImgurId { get; set; } 17 | 18 | public static string ImgurSecret { get; set; } 19 | 20 | public static string GfycatId { get; set; } 21 | 22 | public static string GfycatSecret { get; set; } 23 | 24 | public static string YandexId { get; set; } 25 | } 26 | } -------------------------------------------------------------------------------- /ScreenToGif/Extensions/PresetExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using ScreenToGif.Model.UploadPresets; 3 | using ScreenToGif.Settings; 4 | 5 | namespace ScreenToGif.Extensions 6 | { 7 | internal static class PresetExtensions 8 | { 9 | internal static void Persist(this UploadPreset preset, string previousTitle = null) 10 | { 11 | var current = UserSettings.All.UploadPresets.OfType().FirstOrDefault(f => f.Title == (previousTitle ?? preset.Title)); 12 | 13 | if (current != null) 14 | UserSettings.All.UploadPresets.Remove(current); 15 | 16 | UserSettings.All.UploadPresets.Add(preset); 17 | UserSettings.Save(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/InputHook/CustomKeyEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | 4 | namespace ScreenToGif.Util.InputHook 5 | { 6 | /// 7 | /// Custom Key Event Args. 8 | /// 9 | public class CustomKeyEventArgs : EventArgs 10 | { 11 | public Key Key { get; } 12 | 13 | public bool IsUppercase { get; } 14 | 15 | public bool IsInjected { get; } 16 | 17 | public bool Handled { get; private set; } 18 | 19 | public CustomKeyEventArgs(Key key, bool isUppercase = false, bool isInjected = false) 20 | { 21 | Key = key; 22 | IsUppercase = isUppercase; 23 | IsInjected = isInjected; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: nicke 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: nickemanarin 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: NickeManarin 11 | otechie: # Replace with a single Otechie username 12 | custom: ["https://www.screentogif.com/donate", "https://flattr.com/@NickeManarin/domain/screentogif.com", "https://www.buymeacoffee.com/NickeManarin"] 13 | -------------------------------------------------------------------------------- /ScreenToGif/Controls/Items/QuantizationMethodItem.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using ScreenToGif.Util; 3 | 4 | namespace ScreenToGif.Controls.Items 5 | { 6 | public class QuantizationMethodItem : GenericItem 7 | { 8 | public static readonly DependencyProperty QuantizationTypeProperty = DependencyProperty.Register(nameof(QuantizationType), typeof(ColorQuantizationType), typeof(QuantizationMethodItem), 9 | new PropertyMetadata(default(ColorQuantizationType))); 10 | 11 | public ColorQuantizationType QuantizationType 12 | { 13 | get => (ColorQuantizationType) GetValue(QuantizationTypeProperty); 14 | set => SetValue(QuantizationTypeProperty, value); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Other/Translator/Converters/MultiLineTitle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace Translator.Converters 6 | { 7 | class MultiLineTitle : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | var text = value as string; 12 | 13 | if (String.IsNullOrEmpty(text)) 14 | return value; 15 | 16 | return text.Replace(@"\n", Environment.NewLine); 17 | } 18 | 19 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 20 | { 21 | return value; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/BytesToSize.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | class BytesToSize : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | if (!(value is long length)) 13 | return DependencyProperty.UnsetValue; 14 | 15 | return Humanizer.BytesToString(length); 16 | } 17 | 18 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 19 | { 20 | throw new NotImplementedException(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Other/HookTest/Util/CustomKeyPressEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HookTest.Util 4 | { 5 | public class CustomKeyPressEventArgs : EventArgs 6 | { 7 | /// 8 | /// Gets or sets the character corresponding to the key pressed. 9 | /// 10 | /// 11 | /// The ASCII character that is composed. For example, if the user presses SHIFT + K, 12 | /// this property returns an uppercase K. 13 | /// 14 | public char KeyChar { get; private set; } 15 | 16 | public bool Handled { get; private set; } 17 | 18 | public CustomKeyPressEventArgs(char keyChar) 19 | { 20 | KeyChar = keyChar; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/EnumToVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using System.Windows.Data; 4 | 5 | namespace ScreenToGif.Util.Converters 6 | { 7 | public class InvertedEnumToVisibility: IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 10 | { 11 | return value?.Equals(parameter) == true ? Visibility.Collapsed : Visibility.Visible; 12 | } 13 | 14 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 15 | { 16 | return value?.Equals(Visibility.Visible) == true ? Binding.DoNothing : parameter; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/InvertedEnumToVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using System.Windows.Data; 4 | 5 | namespace ScreenToGif.Util.Converters 6 | { 7 | public class EnumToVisibility: IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 10 | { 11 | return value?.Equals(parameter) == true ? Visibility.Visible : Visibility.Collapsed; 12 | } 13 | 14 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 15 | { 16 | return value?.Equals(Visibility.Visible) == true ? parameter : Binding.DoNothing; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /ScreenToGif/Windows/Other/TextDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace ScreenToGif.Windows.Other 4 | { 5 | public partial class TextDialog : Window 6 | { 7 | public string Command { get; set; } 8 | public string Output { get; set; } 9 | 10 | public TextDialog() 11 | { 12 | InitializeComponent(); 13 | } 14 | 15 | private void Window_Loaded(object sender, RoutedEventArgs e) 16 | { 17 | CommandTextBox.Text = Command; 18 | OutputTextBox.Text = Output; 19 | 20 | CommandTextBox.Focus(); 21 | } 22 | 23 | private void OkButton_Click(object sender, RoutedEventArgs e) 24 | { 25 | Close(); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Other/HookTest/Util/CustomMouseEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | 4 | namespace HookTest.Util 5 | { 6 | public class CustomMouseEventArgs : EventArgs 7 | { 8 | public MouseButton Button { get; private set; } 9 | 10 | public int Clicks { get; private set; } 11 | 12 | public int PosX { get; private set; } 13 | 14 | public int PosY { get; private set; } 15 | 16 | public int Delta { get; private set; } 17 | 18 | public CustomMouseEventArgs(MouseButton button, int clicks, int x, int y, int delta) 19 | { 20 | Button = button; 21 | Clicks = clicks; 22 | PosX = x; 23 | PosY = y; 24 | Delta = delta; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/ContentToVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Returns Visible when source is not null. 10 | /// 11 | public class ContentToVisibility : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | return value != null ? Visibility.Visible : Visibility.Collapsed; 16 | } 17 | 18 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 19 | { 20 | return Binding.DoNothing; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/StorageUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using ScreenToGif.Settings; 4 | using ScreenToGif.Windows.Other; 5 | 6 | namespace ScreenToGif.Util 7 | { 8 | internal static class StorageUtils 9 | { 10 | internal static void PurgeCache() 11 | { 12 | if (UserSettings.All.AskDeleteCacheWhenClosing && !CacheDialog.Ask(false, out _)) 13 | return; 14 | 15 | try 16 | { 17 | var cache = Other.AdjustPath(UserSettings.All.TemporaryFolderResolved); 18 | 19 | Directory.Delete(cache, true); 20 | } 21 | catch (Exception e) 22 | { 23 | LogWriter.Log(e, "Purging cache"); 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /ScreenToGif/Extensions/ParseExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ScreenToGif.Extensions 4 | { 5 | internal static class ParseExtensions 6 | { 7 | internal static bool TryParseBoolean(this string source) 8 | { 9 | bool.TryParse(source, out var result); 10 | 11 | return result; 12 | } 13 | 14 | internal static DateTime? TryParseDateTimeNullable(this string source) 15 | { 16 | if (!DateTime.TryParse(source, out var result)) 17 | return null; 18 | 19 | return result; 20 | } 21 | 22 | internal static int TryParseInteger(this string source) 23 | { 24 | return !int.TryParse(source, out var result) ? 0 : result; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /ScreenToGif/Controls/BaseWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | 4 | namespace ScreenToGif.Controls 5 | { 6 | public class BaseWindow : Window 7 | { 8 | public DateTime CreationIn { get; set; } 9 | public DateTime NonMinimizedIn { get; set; } 10 | public DateTime MinimizedIn { get; set; } 11 | 12 | public BaseWindow() 13 | { 14 | NonMinimizedIn = CreationIn = DateTime.Now; 15 | } 16 | 17 | protected override void OnStateChanged(EventArgs e) 18 | { 19 | if (WindowState != WindowState.Minimized) 20 | NonMinimizedIn = DateTime.Now; 21 | else 22 | MinimizedIn = DateTime.Now; 23 | 24 | base.OnStateChanged(e); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /ScreenToGif.Cloud.YandexDisk.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("ScreenToGif.Cloud.YandexDisk.Tests")] 6 | [assembly: AssemblyDescription("")] 7 | [assembly: AssemblyConfiguration("")] 8 | [assembly: AssemblyCompany("")] 9 | [assembly: AssemblyProduct("ScreenToGif.Cloud.YandexDisk.Tests")] 10 | [assembly: AssemblyCopyright("Copyright © 2018")] 11 | [assembly: AssemblyTrademark("")] 12 | [assembly: AssemblyCulture("")] 13 | 14 | [assembly: ComVisible(false)] 15 | 16 | [assembly: Guid("2e037df4-b0ad-43ed-9b99-4623ddf86f5d")] 17 | 18 | // [assembly: AssemblyVersion("1.0.*")] 19 | [assembly: AssemblyVersion("1.0.0.0")] 20 | [assembly: AssemblyFileVersion("1.0.0.0")] 21 | -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/PathToFilename.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.IO; 4 | using System.Windows; 5 | using System.Windows.Data; 6 | 7 | namespace ScreenToGif.Util.Converters 8 | { 9 | public class PathToFilename : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | var path = value as string; 14 | 15 | return string.IsNullOrEmpty(path) ? LocalizationHelper.Get("S.Watermark.File.Nothing") : Path.GetFileName(path); 16 | } 17 | 18 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 19 | { 20 | return DependencyProperty.UnsetValue; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /ScreenToGif/Cloud/Gfycat/GfycatCreateResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace ScreenToGif.Cloud.Gfycat 4 | { 5 | [DataContract] 6 | public class GfycatCreateResponse 7 | { 8 | [DataMember(Name = "isOk")] 9 | public string IsOk { get; set; } 10 | 11 | [DataMember(Name = "gfyname")] 12 | public string Name { get; set; } 13 | 14 | [DataMember(Name = "secret")] 15 | public string Secret { get; set; } 16 | 17 | [DataMember(Name = "uploadType")] 18 | public string UploadType { get; set; } 19 | 20 | [DataMember(Name = "errorType")] 21 | public string ErrorType { get; set; } 22 | 23 | [DataMember(Name = "errorMessage")] 24 | public GfycatErrorResponse Error { get; set; } 25 | } 26 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/InvertedBool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class InvertedBool: IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | if (!(value is bool vis)) 13 | return DependencyProperty.UnsetValue; 14 | 15 | return !vis; 16 | } 17 | 18 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 19 | { 20 | if (!(value is bool vis)) 21 | return DependencyProperty.UnsetValue; 22 | 23 | return !vis; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/KeyGestureToString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | using System.Windows.Input; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class KeyGestureToString : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | if (!(value is KeyGesture gesture) || gesture.Key == Key.None) 13 | return Binding.DoNothing; 14 | 15 | return $"{Native.GetSelectKeyText(gesture.Key, gesture.Modifiers)}"; 16 | } 17 | 18 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 19 | { 20 | return Binding.DoNothing; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /ScreenToGif.Tests/ImageMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | 5 | using ScreenToGif.Model; 6 | 7 | using Xunit; 8 | 9 | namespace ScreenToGif.Tests 10 | { 11 | public class ImageMethods 12 | { 13 | [Fact] 14 | public void CanCalculateDifference() 15 | { 16 | var f1 = new FrameInfo() 17 | { 18 | Path = "./TestData/b1.bmp", 19 | Index = 0 20 | }; 21 | 22 | var f2 = new FrameInfo() 23 | { 24 | Path = "./TestData/b2.bmp", 25 | Index = 1 26 | }; 27 | 28 | var diff = ImageUtil.ImageMethods.CalculateDifference(f1, f2); 29 | 30 | Assert.Equal(25, diff); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/AnimatedImage/Gif/SystemGifPreset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ScreenToGif.Util; 3 | 4 | namespace ScreenToGif.Model.ExportPresets.AnimatedImage.Gif 5 | { 6 | public class SystemGifPreset : GifPreset 7 | { 8 | public SystemGifPreset() 9 | { 10 | Encoder = EncoderType.System; 11 | ImageId = "Vector.Net"; 12 | } 13 | 14 | 15 | public static SystemGifPreset Default => new SystemGifPreset 16 | { 17 | TitleKey = "S.Preset.Gif.System.Low.Title", 18 | DescriptionKey = "S.Preset.Gif.System.Low.Description", 19 | HasAutoSave = true, 20 | IsDefault = true, 21 | IsSelectedForEncoder = true, 22 | CreationDate = new DateTime(2021, 02, 20) 23 | }; 24 | } 25 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/HasEnumToVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using System.Windows.Data; 4 | 5 | namespace ScreenToGif.Util.Converters 6 | { 7 | public class HasEnumToVisibility: IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 10 | { 11 | var enumValue = value as Enum; 12 | 13 | 14 | return value?.Equals(parameter) == true ? Visibility.Visible : Visibility.Collapsed; 15 | } 16 | 17 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 18 | { 19 | return value?.Equals(Visibility.Visible) == true ? parameter : Binding.DoNothing; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Extras.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace ScreenToGif.Util 4 | { 5 | /// 6 | /// Extra methods for dealing with Files, Folders and Directories. 7 | /// 8 | public static class Extras 9 | { 10 | /// 11 | /// Creates the temp folder that holds all frames. 12 | /// 13 | public static void CreateTemp(string tempFolder) 14 | { 15 | #region Temp Folder 16 | 17 | if (!Directory.Exists(tempFolder)) 18 | { 19 | Directory.CreateDirectory(tempFolder); 20 | //Directory.CreateDirectory(tempFolder + "Undo"); 21 | //Directory.CreateDirectory(tempFolder + "Edit"); 22 | } 23 | 24 | #endregion 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/BoolOrToInvertedVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Linq; 4 | using System.Windows; 5 | using System.Windows.Data; 6 | 7 | namespace ScreenToGif.Util.Converters 8 | { 9 | public class BoolOrToInvertedVisibility : IMultiValueConverter 10 | { 11 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | if (values.Length < 1) 14 | return Visibility.Collapsed; 15 | 16 | return values.Cast().Any(x => x) ? Visibility.Collapsed : Visibility.Visible; 17 | } 18 | 19 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 20 | { 21 | return null; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/TextSequence.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Media; 3 | 4 | namespace ScreenToGif.ModelEx.Sequences 5 | { 6 | public class TextSequence : SizeableSequence 7 | { 8 | public string Text { get; set; } 9 | 10 | public FontFamily FontFamily { get; set; } 11 | 12 | public double FontSize { get; set; } 13 | 14 | public FontWeight FontWeight { get; set; } 15 | 16 | public FontStyle FontStyle { get; set; } 17 | 18 | public Brush Foreground { get; set; } 19 | 20 | public double OutlineThickness { get; set; } 21 | 22 | public Brush OutlineColor { get; set; } 23 | 24 | 25 | public TextSequence() 26 | { 27 | Type = Types.Text; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /ScreenToGif/UserControls/ProgressPanel.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Windows.Controls; 4 | using ScreenToGif.Util; 5 | 6 | namespace ScreenToGif.UserControls 7 | { 8 | public partial class ProgressPanel : UserControl 9 | { 10 | public ProgressPanel() 11 | { 12 | InitializeComponent(); 13 | } 14 | 15 | private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) 16 | { 17 | try 18 | { 19 | Process.Start(e.Uri.AbsoluteUri); 20 | } 21 | catch (Exception ex) 22 | { 23 | LogWriter.Log(ex, $"Error while trying to navigate to a given URI: '{e?.Uri?.AbsoluteUri}'."); 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Gif/Decoder/GifImageData.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace ScreenToGif.ImageUtil.Gif.Decoder 4 | { 5 | public class GifImageData 6 | { 7 | public byte LzwMinimumCodeSize { get; set; } 8 | public byte[] CompressedData { get; set; } 9 | 10 | private GifImageData() 11 | {} 12 | 13 | internal static GifImageData ReadImageData(Stream stream, bool metadataOnly) 14 | { 15 | var imgData = new GifImageData(); 16 | imgData.Read(stream, metadataOnly); 17 | return imgData; 18 | } 19 | 20 | private void Read(Stream stream, bool metadataOnly) 21 | { 22 | LzwMinimumCodeSize = (byte)stream.ReadByte(); 23 | CompressedData = GifHelpers.ReadDataBlocks(stream, metadataOnly); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/BoolToOpacity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Bool to Opacity property converter. Returns 0 if true. 10 | /// 11 | public class BoolToOpacity : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | if (!(value is bool boolean)) 16 | return DependencyProperty.UnsetValue; 17 | 18 | return boolean ? 0 : 1; 19 | } 20 | 21 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 22 | { 23 | return Binding.DoNothing; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/InputHook/CustomKeyPressEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ScreenToGif.Util.InputHook 4 | { 5 | /// 6 | /// Custom KeyPress Event Args 7 | /// 8 | public class CustomKeyPressEventArgs : EventArgs 9 | { 10 | /// 11 | /// Gets or sets the character corresponding to the key pressed. 12 | /// 13 | /// 14 | /// The ASCII character that is composed. For example, if the user presses SHIFT + K, 15 | /// this property returns an uppercase K. 16 | /// 17 | public char KeyChar { get; private set; } 18 | 19 | public bool Handled { get; private set; } 20 | 21 | public CustomKeyPressEventArgs(char keyChar) 22 | { 23 | KeyChar = keyChar; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/MultiLineTitle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Data; 8 | 9 | namespace ScreenToGif.Util.Converters 10 | { 11 | class MultiLineTitle : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | var text = value as string; 16 | 17 | if (String.IsNullOrEmpty(text)) 18 | return value; 19 | 20 | return text.Replace(@"\n", Environment.NewLine); 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | return value; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/TimeSpanToTotalMilliseconds.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace ScreenToGif.Util.Converters 6 | { 7 | public class TimeSpanToTotalMilliseconds : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | if (!(value is TimeSpan timeSpan)) 12 | return Binding.DoNothing; 13 | 14 | return timeSpan.TotalMilliseconds; 15 | } 16 | 17 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 18 | { 19 | if (!(value is double milliseconds)) 20 | return Binding.DoNothing; 21 | 22 | return TimeSpan.FromMilliseconds(milliseconds); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/BoolAndToVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Linq; 4 | using System.Windows; 5 | using System.Windows.Data; 6 | 7 | namespace ScreenToGif.Util.Converters 8 | { 9 | public class BoolAndToVisibility : IMultiValueConverter 10 | { 11 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | if (values == null || values.Length == 0 || values.Any(a => a.GetType() != typeof(bool))) 14 | return Visibility.Collapsed; 15 | 16 | return values.Cast().All(x => x) ? Visibility.Visible : Visibility.Collapsed; 17 | } 18 | 19 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 20 | { 21 | return null; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/BoolOrToVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Linq; 4 | using System.Windows; 5 | using System.Windows.Data; 6 | 7 | namespace ScreenToGif.Util.Converters 8 | { 9 | public class BoolOrToVisibility : IMultiValueConverter 10 | { 11 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | if (values == null || values.Length == 0 || values.Any(a => a.GetType() != typeof(bool))) 14 | return Visibility.Collapsed; 15 | 16 | return values.Cast().Any(x => x) ? Visibility.Visible : Visibility.Collapsed; 17 | } 18 | 19 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 20 | { 21 | return null; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/CountToBool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Windows.Data; 5 | using ScreenToGif.Model; 6 | 7 | namespace ScreenToGif.Util.Converters 8 | { 9 | /// 10 | /// True only if Count > 0. 11 | /// 12 | public class CountToBool : IValueConverter 13 | { 14 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 15 | { 16 | var list = value as List; 17 | 18 | //return DependencyProperty.UnsetValue; 19 | 20 | return list?.Count > 0; 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | throw new NotImplementedException(); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/ScaleConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class ScaleConverter : IMultiValueConverter 9 | { 10 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | var value = System.Convert.ToDouble(values[0]); 13 | var maximum = System.Convert.ToDouble(values[1]); 14 | 15 | if (maximum < 1) 16 | return 0d; 17 | 18 | return value / maximum; 19 | } 20 | 21 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 22 | { 23 | return new[] { DependencyProperty.UnsetValue }; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Other/Translator/Controls/ExtendedTextBox.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | using System.Windows.Input; 4 | 5 | namespace Translator.Controls 6 | { 7 | public class ExtendedTextBox : TextBox 8 | { 9 | static ExtendedTextBox() 10 | { 11 | DefaultStyleKeyProperty.OverrideMetadata(typeof(ExtendedTextBox), new FrameworkPropertyMetadata(typeof(ExtendedTextBox))); 12 | } 13 | 14 | protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) 15 | { 16 | if (!IsKeyboardFocusWithin) 17 | { 18 | e.Handled = true; 19 | Focus(); 20 | } 21 | } 22 | 23 | protected override void OnGotFocus(RoutedEventArgs e) 24 | { 25 | base.OnGotFocus(e); 26 | 27 | SelectAll(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ScreenToGif/Cloud/IUploader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | using ScreenToGif.Model.UploadPresets; 5 | using ScreenToGif.Model.UploadPresets.History; 6 | 7 | namespace ScreenToGif.Cloud 8 | { 9 | public interface IUploader 10 | { 11 | /// 12 | /// Upload the file to the cloud service. 13 | /// 14 | /// The upload preset with the configurations necessary for the upload. 15 | /// Path of file. 16 | /// 17 | /// 18 | /// The upload details. 19 | Task UploadFileAsync(UploadPreset preset, string path, CancellationToken cancellationToken, IProgress progressCallback = null); 20 | } 21 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/DoubleToPercentage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Converts a Double value to a String representation of a percentage. 100 % 10 | /// 11 | public class DoubleToPercentage : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | if (!(value is double doubleValue)) 16 | return DependencyProperty.UnsetValue; 17 | 18 | return doubleValue + " %"; 19 | } 20 | 21 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 22 | { 23 | throw new NotImplementedException(); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/StringToStaticResource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class StringToStaticResource : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | var str = value as string; 13 | 14 | if (string.IsNullOrWhiteSpace(str) || Application.Current == null || !Application.Current.Resources.Contains(str)) 15 | return DependencyProperty.UnsetValue; 16 | 17 | return Application.Current.Resources[str]; 18 | } 19 | 20 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 21 | { 22 | return Binding.DoNothing; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/FunctionLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace ScreenToGif.Util 5 | { 6 | /// 7 | /// Loads externals functions/methods based on a dynamic DLL path. 8 | /// 9 | internal static class FunctionLoader 10 | { 11 | [DllImport("Kernel32.dll")] 12 | private static extern IntPtr LoadLibrary(string path); 13 | 14 | [DllImport("Kernel32.dll")] 15 | private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); 16 | 17 | internal static Delegate LoadFunction(string dllPath, string functionName) 18 | { 19 | var hModule = LoadLibrary(dllPath); 20 | var functionAddress = GetProcAddress(hModule, functionName); 21 | 22 | return Marshal.GetDelegateForFunctionPointer(functionAddress, typeof(T)); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /ScreenToGif/Interfaces/IExportPreset.cs: -------------------------------------------------------------------------------- 1 | using ScreenToGif.Util; 2 | 3 | namespace ScreenToGif.Interfaces 4 | { 5 | public interface IExportPreset : IPreset 6 | { 7 | string TitleKey { get; set; } 8 | string DescriptionKey { get; set; } 9 | Export Type { get; set; } 10 | bool PickLocation { get; set; } 11 | bool OverwriteOnSave { get; set; } 12 | bool ExportAsProjectToo { get; set; } 13 | bool UploadFile { get; set; } 14 | string UploadService { get; set; } 15 | 16 | bool ExportPartially { get; set; } 17 | PartialExportType PartialExport { get; set; } 18 | string PartialExportFrameExpression { get; set; } 19 | 20 | string OutputFolder { get; set; } 21 | string OutputFilename { get; set; } 22 | 23 | bool RequiresFfmpeg { get; set; } 24 | bool RequiresGifski { get; set; } 25 | } 26 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/RasterSequence.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using ScreenToGif.ModelEx.Sequences.SubSequences; 3 | 4 | namespace ScreenToGif.ModelEx.Sequences 5 | { 6 | public class RasterSequence : SizeableSequence 7 | { 8 | /// 9 | /// Origin of the raster frames. 10 | /// It could be from capture (screen or webcam), media import (gif, apng, image or video) or rasterization of other sequences. 11 | /// 12 | public string Origin { get; set; } 13 | 14 | /// 15 | /// The bit depth of the raster images. 16 | /// Usually 24 or 32 bits. 17 | /// 18 | public int BitDepth { get; set; } 19 | 20 | public List Frames { get; set; } 21 | 22 | 23 | public RasterSequence() 24 | { 25 | Type = Types.Raster; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/SourceToSize.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Windows.Data; 5 | using System.Windows.Media.Imaging; 6 | 7 | namespace ScreenToGif.Util.Converters 8 | { 9 | public class SourceToSize : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | var image = value as BitmapImage; 14 | var param = parameter as string; 15 | 16 | if (image == null || String.IsNullOrEmpty(param)) 17 | return value; 18 | 19 | return param.Equals("width") ? image.Width : image.Height; 20 | } 21 | 22 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 23 | { 24 | return value; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ScreenToGif/Cloud/OAuth2Token.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace ScreenToGif.Cloud 4 | { 5 | [DataContract] 6 | public class OAuth2Token 7 | { 8 | [DataMember(Name = "access_token")] 9 | public string AccessToken { get; set; } 10 | 11 | [DataMember(Name = "refresh_token")] 12 | public string RefreshToken { get; set; } 13 | 14 | [DataMember(Name = "expires_in")] 15 | public int ExpiresIn { get; set; } 16 | 17 | [DataMember(Name = "refresh_token_expires_in")] 18 | public int RefreshTokenExpiresIn { get; set; } 19 | 20 | [DataMember(Name = "token_type")] 21 | public string TokenType { get; set; } 22 | 23 | [DataMember(Name = "scope")] 24 | public string Scope { get; set; } 25 | 26 | [DataMember(Name = "resource_owner")] 27 | public string ResourceOwner { get; set; } 28 | } 29 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/BoolOr.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Linq; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Multi-value converter. 10 | /// Check if any bools are true. 11 | /// Pass any parameter to invert the logic. 12 | /// 13 | public class BoolOr : IMultiValueConverter 14 | { 15 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 16 | { 17 | var res = values.Cast().Any(x => x); 18 | 19 | //If there's any parameter, invert the logic. 20 | return parameter != null ? !res : res; 21 | } 22 | 23 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 24 | { 25 | return null; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/BoolAnd.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Linq; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Multi-value converter. 10 | /// Check if all bools are true. 11 | /// Pass any parameter to invert the logic. 12 | /// 13 | public class BoolAnd : IMultiValueConverter 14 | { 15 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 16 | { 17 | var res = values.Cast().All(x => x); 18 | 19 | //If there's any parameter, invert the logic. 20 | return parameter != null ? !res : res; 21 | } 22 | 23 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 24 | { 25 | return null; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/Image/BmpPreset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ScreenToGif.Util; 3 | 4 | namespace ScreenToGif.Model.ExportPresets.Image 5 | { 6 | public class BmpPreset : ImagePreset 7 | { 8 | public BmpPreset() 9 | { 10 | Type = Export.Bmp; 11 | ImageId = "Vector.Logo"; 12 | DefaultExtension = ".bmp"; 13 | Extension = ".bmp"; 14 | } 15 | 16 | 17 | public static BmpPreset Default => new BmpPreset 18 | { 19 | TitleKey = "S.Preset.Default.Title", 20 | DescriptionKey = "S.Preset.Default.Description", 21 | HasAutoSave = true, 22 | IsSelectedForEncoder = true, 23 | IsDefault = true, 24 | CreationDate = new DateTime(2021, 02, 20), 25 | 26 | ExportPartially = true, 27 | PartialExport = PartialExportType.Selection 28 | }; 29 | } 30 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/Image/PngPreset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ScreenToGif.Util; 3 | 4 | namespace ScreenToGif.Model.ExportPresets.Image 5 | { 6 | public class PngPreset : ImagePreset 7 | { 8 | public PngPreset() 9 | { 10 | Type = Export.Png; 11 | ImageId = "Vector.Logo"; 12 | DefaultExtension = ".png"; 13 | Extension = ".png"; 14 | } 15 | 16 | 17 | public static PngPreset Default => new PngPreset 18 | { 19 | TitleKey = "S.Preset.Default.Title", 20 | DescriptionKey = "S.Preset.Default.Description", 21 | HasAutoSave = true, 22 | IsSelectedForEncoder = true, 23 | IsDefault = true, 24 | CreationDate = new DateTime(2021, 02, 20), 25 | 26 | ExportPartially = true, 27 | PartialExport = PartialExportType.Selection 28 | }; 29 | } 30 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/BoolOrAndToVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Linq; 4 | using System.Windows; 5 | using System.Windows.Data; 6 | 7 | namespace ScreenToGif.Util.Converters 8 | { 9 | public class BoolOrAndToVisibility : IMultiValueConverter 10 | { 11 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | var list = values.Cast().ToList(); 14 | 15 | for (var i = 0; i < list.Count; i += 2) 16 | { 17 | if (list[i] && list[i + 1]) 18 | return Visibility.Visible; 19 | } 20 | 21 | return Visibility.Collapsed; 22 | } 23 | 24 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 25 | { 26 | return null; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/Image/JpegPreset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ScreenToGif.Util; 3 | 4 | namespace ScreenToGif.Model.ExportPresets.Image 5 | { 6 | public class JpegPreset : ImagePreset 7 | { 8 | public JpegPreset() 9 | { 10 | Type = Export.Jpeg; 11 | ImageId = "Vector.Logo"; 12 | DefaultExtension = ".jpeg"; 13 | Extension = ".jpeg"; 14 | } 15 | 16 | 17 | public static JpegPreset Default => new JpegPreset 18 | { 19 | TitleKey = "S.Preset.Default.Title", 20 | DescriptionKey = "S.Preset.Default.Description", 21 | HasAutoSave = true, 22 | IsSelectedForEncoder = true, 23 | IsDefault = true, 24 | CreationDate = new DateTime(2021, 02, 20), 25 | 26 | ExportPartially = true, 27 | PartialExport = PartialExportType.Selection 28 | }; 29 | } 30 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/CenterPopupConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class CenterPopupConverter : IMultiValueConverter 9 | { 10 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | if (values.Length < 2) 13 | return DependencyProperty.UnsetValue; 14 | 15 | if (!(values[0] is double targetWidth) || !(values[1] is double popupWidth)) 16 | return DependencyProperty.UnsetValue; 17 | 18 | return targetWidth / 2.0 - popupWidth / 2.0; 19 | } 20 | 21 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 22 | { 23 | throw new NotSupportedException(); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/IntToDelayString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Converts a Integer to a String formated as Delay (Example: 1 ms) 10 | /// 11 | public class IntToDelayString : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | var intValue = value as int?; 16 | 17 | if (!intValue.HasValue) 18 | return DependencyProperty.UnsetValue; 19 | 20 | return String.Format("{0} ms", intValue); 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | throw new NotImplementedException(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/IntToVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class IntToVisibility : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | var number = value as int?; 13 | var param = parameter as string; 14 | 15 | if (!number.HasValue || string.IsNullOrWhiteSpace(param) || !int.TryParse(param, out var number2)) 16 | return Visibility.Collapsed; 17 | 18 | return Equals(number, number2) ? Visibility.Visible : Visibility.Collapsed; 19 | } 20 | 21 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 22 | { 23 | return Binding.DoNothing; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/FormatConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Linq; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class FormatConverter : IMultiValueConverter 9 | { 10 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | if (values.Length < 2) 13 | return Binding.DoNothing; 14 | 15 | if (!(values[0] is string format)) 16 | return Binding.DoNothing; 17 | 18 | var list = values.ToList(); 19 | list.RemoveAt(0); 20 | 21 | return string.Format(format, list.ToArray()); 22 | } 23 | 24 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/InvertedVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | class InvertedVisibility : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | var visibility = value as Visibility?; 13 | var param = parameter as string; 14 | 15 | if (!visibility.HasValue) 16 | return DependencyProperty.UnsetValue; 17 | 18 | return visibility.Value != Visibility.Visible ? Visibility.Visible : param != null ? Visibility.Hidden : Visibility.Collapsed; 19 | } 20 | 21 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 22 | { 23 | return Binding.DoNothing; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/InvertedIntToVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class InvertedIntToVisibility : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | var number = value as int?; 13 | var param = parameter as string; 14 | 15 | if (!number.HasValue || string.IsNullOrWhiteSpace(param) || !int.TryParse(param, out var number2)) 16 | return Visibility.Visible; 17 | 18 | return Equals(number, number2) ? Visibility.Collapsed : Visibility.Visible; 19 | } 20 | 21 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 22 | { 23 | return Binding.DoNothing; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/ExtendedStack.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ScreenToGif.Util 4 | { 5 | public class ExtendedStack : LinkedList 6 | { 7 | public T Pop() 8 | { 9 | var first = First.Value; 10 | 11 | RemoveFirst(); 12 | 13 | return first; 14 | } 15 | 16 | public T Peek() 17 | { 18 | return First.Value; 19 | } 20 | 21 | public void Push(T obj) 22 | { 23 | AddFirst(obj); 24 | } 25 | 26 | 27 | public T PopBottom() 28 | { 29 | var last = Last.Value; 30 | 31 | RemoveLast(); 32 | 33 | return last; 34 | } 35 | 36 | public T PeekBottom() 37 | { 38 | return Last.Value; 39 | } 40 | 41 | public void PushBottom(T obj) 42 | { 43 | AddLast(obj); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /ScreenToGif/Cloud/Gfycat/GfycatAuthRequest.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace ScreenToGif.Cloud.Gfycat 4 | { 5 | [DataContract] 6 | public class GfycatAuthRequest 7 | { 8 | [DataMember(Name = "grant_type", EmitDefaultValue = false)] 9 | public string GrantType { get; set; } 10 | 11 | [DataMember(Name = "client_id", EmitDefaultValue = false)] 12 | public string ClientId { get; set; } 13 | 14 | [DataMember(Name = "client_secret", EmitDefaultValue = false)] 15 | public string ClientSecret { get; set; } 16 | 17 | [DataMember(Name = "username", EmitDefaultValue = false)] 18 | public string Username { get; set; } 19 | 20 | [DataMember(Name = "password", EmitDefaultValue = false)] 21 | public string Password { get; set; } 22 | 23 | [DataMember(Name = "refresh_token", EmitDefaultValue = false)] 24 | public string RefreshToken { get; set; } 25 | } 26 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/AnimatedImage/AnimatedImagePreset.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenToGif.Model.ExportPresets.AnimatedImage 2 | { 3 | public class AnimatedImagePreset : ExportPreset 4 | { 5 | private bool _looped = true; 6 | private bool _repeatForever = true; 7 | private int _repeatCount = 2; 8 | 9 | 10 | public bool Looped 11 | { 12 | get => _looped; 13 | set => SetProperty(ref _looped, value); 14 | } 15 | 16 | public bool RepeatForever 17 | { 18 | get => _repeatForever; 19 | set => SetProperty(ref _repeatForever, value); 20 | } 21 | 22 | public int RepeatCount 23 | { 24 | get => _repeatCount; 25 | set => SetProperty(ref _repeatCount, value); 26 | } 27 | 28 | 29 | public AnimatedImagePreset() 30 | { 31 | OutputFilenameKey = "S.Preset.Filename.Animation"; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/DoubleToBool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Double to Boolean property converter. It compares the the parameter with the provided value. 10 | /// 11 | public class DoubleToBool : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | var param = parameter as string; 16 | 17 | if (!(value is double @double) || param == null) 18 | return DependencyProperty.UnsetValue; 19 | 20 | return @double == double.Parse(param); 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | return DependencyProperty.UnsetValue; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Serializer.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Runtime.Serialization.Json; 3 | using System.Text; 4 | 5 | namespace ScreenToGif.Util 6 | { 7 | public static class Serializer 8 | { 9 | internal static string Serialize(T data) 10 | { 11 | using (var ms = new MemoryStream()) 12 | { 13 | var ser = new DataContractJsonSerializer(typeof(T)); 14 | ser.WriteObject(ms, data); 15 | ms.Position = 0; 16 | 17 | using (var reader = new StreamReader(ms, Encoding.UTF8)) 18 | return reader.ReadToEnd(); 19 | } 20 | } 21 | 22 | internal static T Deserialize(string json) 23 | { 24 | var ser = new DataContractJsonSerializer(typeof(T)); 25 | 26 | using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) 27 | return (T) ser.ReadObject(stream); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/IntToBool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Integer to Boolean property converter. It compares the the parameter with the provided value. 10 | /// 11 | public class IntToBool : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | var param = parameter as string; 16 | 17 | if (!(value is int integer) || param == null) 18 | return DependencyProperty.UnsetValue; 19 | 20 | return integer == int.Parse(param); 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | return DependencyProperty.UnsetValue; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/SelectionCountToDescription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace ScreenToGif.Util.Converters 6 | { 7 | public class SelectionCountToDescription : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | if (!(value is int count)) 12 | return Binding.DoNothing; 13 | 14 | return count > 1 ? LocalizationHelper.GetWithFormat("S.SaveAs.Partial.Mode.Selection.Plural", "{0} frames selected.", count) : 15 | count == 1 ? LocalizationHelper.Get("S.SaveAs.Partial.Mode.Selection.Singular") : LocalizationHelper.Get("S.SaveAs.Partial.Mode.Selection.None"); 16 | } 17 | 18 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 19 | { 20 | return Binding.DoNothing; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/AlphaToOpacity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Converts the Alpha value to a Opacity Double and vice-versa. 10 | /// 11 | public class AlphaToOpacity : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | if (!(value is long cent)) 16 | return DependencyProperty.UnsetValue; 17 | 18 | return cent / 255F; 19 | } 20 | 21 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 22 | { 23 | if (!(parameter is double parameterString) || value?.Equals(false) == true) 24 | return DependencyProperty.UnsetValue; 25 | 26 | return parameter; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/PercentageToOpacity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Converts a value in the order of 100s value to a Opacity double (0 to 1) and vice-versa. 10 | /// 11 | public class PercentageToOpacity : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | if (!(value is double cent)) 16 | return DependencyProperty.UnsetValue; 17 | 18 | return cent * 100D; 19 | } 20 | 21 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 22 | { 23 | if (!(value is double opacity)) 24 | return DependencyProperty.UnsetValue; 25 | 26 | return opacity / 100D; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/InvertedBoolToVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// The inverted BoolToVisibility converter. 10 | /// 11 | public class InvertedBoolToVisibility : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | if (!(value is bool vis)) 16 | return DependencyProperty.UnsetValue; 17 | 18 | return vis ? Visibility.Collapsed: Visibility.Visible; 19 | } 20 | 21 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 22 | { 23 | if (!(value is Visibility vis)) 24 | return DependencyProperty.UnsetValue; 25 | 26 | return !vis.Equals(Visibility.Visible); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/FosshubRelease.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Runtime.Serialization; 5 | 6 | namespace ScreenToGif.Model 7 | { 8 | [DataContract] 9 | public class FosshubRelease 10 | { 11 | [DataMember(Name = "title")] 12 | public string Title { get; set; } 13 | 14 | [DataMember(Name = "date")] 15 | public string DateString { get; set; } 16 | 17 | public DateTime? CreatedAt 18 | { 19 | get 20 | { 21 | if (DateTime.TryParse(DateString, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out var date)) 22 | return date; 23 | 24 | return null; 25 | } 26 | } 27 | 28 | [DataMember(Name = "link")] 29 | public string Link { get; set; } 30 | 31 | [DataMember(Name = "items")] 32 | public List Items { get; set; } 33 | } 34 | } -------------------------------------------------------------------------------- /ScreenToGif/Windows/Other/FeedbackPreview.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using ScreenToGif.Util; 4 | 5 | namespace ScreenToGif.Windows.Other 6 | { 7 | public partial class FeedbackPreview : Window 8 | { 9 | public string Html { get; set; } 10 | 11 | public FeedbackPreview() 12 | { 13 | InitializeComponent(); 14 | } 15 | 16 | private void FeedbackPreview_Loaded(object sender, RoutedEventArgs e) 17 | { 18 | try 19 | { 20 | MainBrowser.NavigateToString(Html); 21 | } 22 | catch (Exception ex) 23 | { 24 | LogWriter.Log(ex, "Displaying the preview"); 25 | 26 | Dialog.Ok("Feedback Preview", "It was not possible to display the content", ex.Message); 27 | } 28 | } 29 | 30 | private void OkButton_Click(object sender, RoutedEventArgs e) 31 | { 32 | Close(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /ScreenToGif/Controls/Items/ExportItem.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using ScreenToGif.Util; 3 | 4 | namespace ScreenToGif.Controls.Items 5 | { 6 | public class ExportItem : GenericItem 7 | { 8 | public static readonly DependencyProperty ExportTypeProperty = DependencyProperty.Register(nameof(ExportType), typeof(string), typeof(ExportItem), 9 | new PropertyMetadata(default(string))); 10 | 11 | public static readonly DependencyProperty FileTypeProperty = DependencyProperty.Register(nameof(FileType), typeof(Export), typeof(ExportItem), 12 | new PropertyMetadata(default(Export))); 13 | 14 | 15 | public string ExportType 16 | { 17 | get => (string) GetValue(ExportTypeProperty); 18 | set => SetValue(ExportTypeProperty, value); 19 | } 20 | 21 | public Export FileType 22 | { 23 | get => (Export) GetValue(FileTypeProperty); 24 | set => SetValue(FileTypeProperty, value); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /ScreenToGif.Tests/ScreenToGif.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net48 5 | 6 | 7 | 8 | 9 | 10 | 11 | all 12 | runtime; build; native; contentfiles; analyzers; buildtransitive 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Always 23 | 24 | 25 | Always 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/IntToDecimal.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Converts 100 to 1,0. 10 | /// 11 | public class IntToDecimal : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | var doubleValue = value as double?; 16 | 17 | if (!doubleValue.HasValue) 18 | return DependencyProperty.UnsetValue; 19 | 20 | return doubleValue * 100; 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | var intValue = value as int?; 26 | 27 | if (!intValue.HasValue) 28 | return DependencyProperty.UnsetValue; 29 | 30 | return intValue / 100D; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ScreenToGif/ViewModel/WebcamViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using ScreenToGif.Model; 3 | 4 | namespace ScreenToGif.ViewModel 5 | { 6 | public class WebcamViewModel : RecorderViewModel 7 | { 8 | private List _videoSources = new List(); 9 | private VideoSource _selectedVideoSource = null; 10 | private MediaSourceType _selectedMediaSource = null; 11 | 12 | public List VideoSources 13 | { 14 | get => _videoSources; 15 | set => SetProperty(ref _videoSources, value); 16 | } 17 | 18 | public VideoSource SelectedVideoSource 19 | { 20 | get => _selectedVideoSource; 21 | set => SetProperty(ref _selectedVideoSource, value); 22 | } 23 | 24 | public MediaSourceType SelectedMediaSource 25 | { 26 | get => _selectedMediaSource; 27 | set => SetProperty(ref _selectedMediaSource, value); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Psd/AditionalLayers/Metadata.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Text; 4 | using ScreenToGif.Util; 5 | 6 | namespace ScreenToGif.ImageUtil.Psd.AditionalLayers 7 | { 8 | internal class Metadata : IAditionalLayerInfo 9 | { 10 | public string Key { get; } = "shmd"; 11 | 12 | public List MetadataContentList = new List(); 13 | 14 | public long Length => Content?.Length ?? 0; 15 | 16 | public byte[] Content 17 | { 18 | get 19 | { 20 | using (var stream = new MemoryStream()) 21 | { 22 | stream.WriteBytes(Encoding.ASCII.GetBytes(Key)); //Aditional layer info key, 4 bytes. 23 | 24 | foreach (var metadata in MetadataContentList) 25 | stream.WriteBytes(metadata.Content); 26 | 27 | return stream.ToArray(); 28 | } 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/Events/ValidatedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using ScreenToGif.Util; 4 | 5 | namespace ScreenToGif.Model.Events 6 | { 7 | public delegate void ValidatedEventHandler(object sender, ValidatedEventArgs e); 8 | 9 | public class ValidatedEventArgs : RoutedEventArgs 10 | { 11 | public string MessageKey { get; set; } 12 | 13 | public StatusReasons Reason { get; set; } 14 | 15 | public Action Action { get; set; } 16 | 17 | 18 | public ValidatedEventArgs(string messageKey, StatusReasons reason, Action action = null) 19 | { 20 | MessageKey = messageKey; 21 | Reason = reason; 22 | Action = action; 23 | } 24 | 25 | public ValidatedEventArgs(RoutedEvent routedEvent, string messageKey, StatusReasons reason, Action action = null) : base(routedEvent) 26 | { 27 | MessageKey = messageKey; 28 | Reason = reason; 29 | Action = action; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/EnumToInt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Data; 3 | 4 | namespace ScreenToGif.Util.Converters 5 | { 6 | public class EnumToInt: IValueConverter 7 | { 8 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 9 | { 10 | if (value == null) 11 | return null; 12 | 13 | //Converts int to enum. 14 | if (targetType.IsEnum) 15 | return Enum.ToObject(targetType, value); 16 | 17 | //Converts enum to int. 18 | return value.GetType().IsEnum ? System.Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType())) : null; 19 | } 20 | 21 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 22 | { 23 | //Performs the same conversion in both directions. 24 | return Convert(value, targetType, parameter, culture); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Gif/Decoder/GifCommentExtension.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text; 3 | 4 | namespace ScreenToGif.ImageUtil.Gif.Decoder 5 | { 6 | public class GifCommentExtension : GifExtension 7 | { 8 | public const int ExtensionLabel = 0xFE; 9 | 10 | public string Text { get; private set; } 11 | 12 | private GifCommentExtension() 13 | {} 14 | 15 | public override GifBlockKind Kind => GifBlockKind.SpecialPurpose; 16 | 17 | public static GifCommentExtension ReadComment(Stream stream) 18 | { 19 | var comment = new GifCommentExtension(); 20 | comment.Read(stream); 21 | return comment; 22 | } 23 | 24 | private void Read(Stream stream) 25 | { 26 | // Note: at this point, the label (0xFE) has already been read 27 | var bytes = GifHelpers.ReadDataBlocks(stream, false); 28 | 29 | if (bytes != null) 30 | Text = Encoding.ASCII.GetString(bytes); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/BoolAndOrOrToVisibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Linq; 4 | using System.Windows; 5 | using System.Windows.Data; 6 | 7 | namespace ScreenToGif.Util.Converters 8 | { 9 | public class BoolAndOrOrToVisibility : IMultiValueConverter 10 | { 11 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | //List of params: 14 | //[0]: Always true. 15 | //[1-2]: At least one true. 16 | 17 | var list = values.Cast().ToList(); 18 | 19 | if (list.Count != 3) 20 | return Visibility.Collapsed; 21 | 22 | if (!list[0] || !(list[1] || list[2])) 23 | return Visibility.Collapsed; 24 | 25 | return Visibility.Visible; 26 | } 27 | 28 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 29 | { 30 | return null; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/ColorToBrush.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | using System.Windows.Media; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Converts the System.Drawing.Color to a WPF Brush. 10 | /// 11 | public class ColorToBrush : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | var color = value as Color?; 16 | 17 | if (!color.HasValue) 18 | return new SolidColorBrush(Colors.Transparent); 19 | 20 | return new SolidColorBrush(color.Value); 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | var brush = value as SolidColorBrush; 26 | 27 | if (brush == null) 28 | return Binding.DoNothing; 29 | 30 | return brush.Color; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/Video/Codecs/Mpeg2.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using ScreenToGif.Util; 3 | 4 | namespace ScreenToGif.Model.ExportPresets.Video.Codecs 5 | { 6 | public class Mpeg2 : VideoCodec 7 | { 8 | public Mpeg2() 9 | { 10 | Type = VideoCodecs.Mpeg2; 11 | Name = "MPEG-2"; 12 | Command = "mpeg2video"; 13 | 14 | CodecPresets = new List> 15 | { 16 | new EnumItem(VideoCodecPresets.None, "S.SaveAs.VideoOptions.CodecPreset.None", "") 17 | }; 18 | PixelFormats = new List> 19 | { 20 | new EnumItem(VideoPixelFormats.Auto, "S.SaveAs.VideoOptions.PixelFormat.Auto", ""), 21 | new EnumItem(VideoPixelFormats.Yuv420p, "", "Yuv420p", "yuv420p"), 22 | new EnumItem(VideoPixelFormats.Yuv422p, "", "Yuv422p", "yuv422p") 23 | }; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/StringToInt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Converts a String to Int32 and vice-versa. 10 | /// 11 | public class StringToInt : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | var stringValue = value as string; 16 | 17 | if (String.IsNullOrEmpty(stringValue)) 18 | return DependencyProperty.UnsetValue; 19 | 20 | return int.Parse(stringValue); 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | var parameterString = parameter as int?; 26 | 27 | if (!parameterString.HasValue) 28 | return DependencyProperty.UnsetValue; 29 | 30 | return parameter.ToString(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/DoubleToInt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Simple Double-Int32 converter. 10 | /// 11 | public class DoubleToInt : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | var number = value as double?; 16 | 17 | if (!number.HasValue || Double.IsNaN(number.Value)) 18 | return DependencyProperty.UnsetValue; 19 | 20 | return System.Convert.ToInt32(number.Value); 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | var number = value as int?; 26 | 27 | if (!number.HasValue) 28 | return DependencyProperty.UnsetValue; 29 | 30 | return System.Convert.ToDouble(number.Value); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/DoubleTimesAHundredToInt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Windows.Data; 9 | 10 | namespace ScreenToGif.Util.Converters 11 | { 12 | public class DoubleTimesAHundredToInt : IValueConverter 13 | { 14 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 15 | { 16 | var doubleValue = value as double?; 17 | 18 | if (!doubleValue.HasValue) 19 | return DependencyProperty.UnsetValue; 20 | 21 | return doubleValue.Value * 100; 22 | } 23 | 24 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 25 | { 26 | var intValue = value as int?; 27 | 28 | if (!intValue.HasValue) 29 | return DependencyProperty.UnsetValue; 30 | 31 | return intValue.Value / 100D; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ScreenToGif/Model/UploadPresets/Imgur/ImgurAlbum.cs: -------------------------------------------------------------------------------- 1 | using ScreenToGif.Cloud.Imgur; 2 | 3 | namespace ScreenToGif.Model.UploadPresets.Imgur 4 | { 5 | public class ImgurAlbum 6 | { 7 | public string Id { get; set; } 8 | 9 | public string Title { get; set; } 10 | 11 | public string Description { get; set; } 12 | 13 | public string Link { get; set; } 14 | 15 | public string Privacy { get; set; } 16 | 17 | public bool Favorite { get; set; } 18 | 19 | public bool? Nsfw { get; set; } 20 | 21 | public int ImagesCount { get; set; } 22 | 23 | public ImgurAlbum() 24 | { } 25 | 26 | public ImgurAlbum(ImgurAlbumData data) 27 | { 28 | Id = data.Id; 29 | Title = data.Title; 30 | Description = data.Description; 31 | Link = data.Link; 32 | Privacy = data.Privacy; 33 | Favorite = data.Favorite; 34 | Nsfw = data.Nsfw; 35 | ImagesCount = data.ImagesCount; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/Video/Codecs/Mpeg4.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using ScreenToGif.Util; 3 | 4 | namespace ScreenToGif.Model.ExportPresets.Video.Codecs 5 | { 6 | /// 7 | /// https://trac.ffmpeg.org/wiki/Encode/MPEG-4 8 | /// 9 | public class Mpeg4 : VideoCodec 10 | { 11 | public Mpeg4() 12 | { 13 | Type = VideoCodecs.Mpeg4; 14 | Name = "MPEG-4"; 15 | Command = "mpeg4"; 16 | Parameters = "-vtag xvid"; 17 | 18 | CodecPresets = new List> 19 | { 20 | new EnumItem(VideoCodecPresets.None, "S.SaveAs.VideoOptions.CodecPreset.None", "") 21 | }; 22 | PixelFormats = new List> 23 | { 24 | new EnumItem(VideoPixelFormats.Auto, "S.SaveAs.VideoOptions.PixelFormat.Auto", ""), 25 | new EnumItem(VideoPixelFormats.Yuv420p, "", "Yuv420p", "yuv420p") 26 | }; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/CommandToKeyGesture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | using System.Windows.Input; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class CommandToKeyGesture : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | var command = value as RoutedUICommand; 13 | 14 | if (command?.InputGestures == null) 15 | return Binding.DoNothing; 16 | 17 | //var keys = Native.GetSelectKeyText(gesture.Key, gesture.Modifiers); 18 | 19 | foreach (KeyGesture gesture in command.InputGestures) 20 | if (gesture.Key != Key.None) 21 | return $"{Native.GetSelectKeyText(gesture.Key, gesture.Modifiers)}"; 22 | 23 | return Binding.DoNothing; 24 | } 25 | 26 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 27 | { 28 | return Binding.DoNothing; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /ScreenToGif/ModelEx/Sequences/SubSequences/CursorEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ScreenToGif.ModelEx.Sequences.SubSequences 4 | { 5 | public class CursorEvent 6 | { 7 | public byte[] Pixels { get; set; } 8 | 9 | public double Left { get; set; } 10 | 11 | public double Top { get; set; } 12 | 13 | public double Width { get; set; } 14 | 15 | public double Height { get; set; } 16 | 17 | //DPI, Depth? 18 | 19 | public bool IsLeftButtonDown { get; set; } 20 | 21 | public bool IsRightButtonDown { get; set; } 22 | 23 | public bool IsMiddleButtonDown { get; set; } 24 | 25 | public bool IsFourthButtonDown { get; set; } 26 | 27 | public bool IsFifthButtonDown { get; set; } 28 | 29 | public int MouseWheelDelta { get; set; } 30 | 31 | public bool IsMiddleScrollUp => MouseWheelDelta > 0; 32 | 33 | public bool IsMiddleScrollDown => MouseWheelDelta < 0; 34 | 35 | public bool IsMiddleScroll => IsMiddleScrollUp || IsMiddleScrollDown; 36 | 37 | public TimeSpan TimeStamp { get; set; } 38 | } 39 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/RoutedCommandToInputGestureText.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | using System.Windows.Input; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class CommandToInputGestureText : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | var command = value as RoutedUICommand; 13 | 14 | if (command?.InputGestures == null) 15 | return Binding.DoNothing; 16 | 17 | //var keys = Native.GetSelectKeyText(gesture.Key, gesture.Modifiers); 18 | foreach (KeyGesture gesture in command.InputGestures) 19 | return $"{LocalizationHelper.Get(command.Text) ?? command.Text}\n({Native.GetSelectKeyText(gesture.Key, gesture.Modifiers)})"; 20 | 21 | return Binding.DoNothing; 22 | } 23 | 24 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 25 | { 26 | return Binding.DoNothing; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/TagToSelection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// Tag to Selection property converter. It compares the the parameter with the provided value. 10 | /// 11 | public class TagToSelection : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | var param = value as string; 16 | 17 | if (param == null) 18 | return DependencyProperty.UnsetValue; 19 | 20 | return Equals(param, parameter.ToString()); 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | var parameterString = parameter as string; 26 | 27 | if (parameterString == null || value.Equals(false)) 28 | return DependencyProperty.UnsetValue; 29 | 30 | return parameter; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ScreenToGif/Windows/Other/RegionSelector.xaml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 14 | -------------------------------------------------------------------------------- /Other/PositioningTest/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | 4 | namespace PositioningTest 5 | { 6 | public partial class MainWindow : Window 7 | { 8 | public MainWindow() 9 | { 10 | InitializeComponent(); 11 | } 12 | 13 | private void MainWindow_LocationChanged(object sender, EventArgs e) 14 | { 15 | UpdateText(); 16 | } 17 | 18 | private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e) 19 | { 20 | UpdateText(); 21 | } 22 | 23 | private void MainWindow_DpiChanged(object sender, DpiChangedEventArgs e) 24 | { 25 | UpdateText(); 26 | } 27 | 28 | private void UpdateText() 29 | { 30 | TopLeftTextBlock.Text = $"{Top} • {Left}"; 31 | TopRightTextBlock.Text = $"{Top} • {Left + Width}"; 32 | 33 | SizeTextBlock.Text = $"{Width} x {Height}"; 34 | 35 | BottomLeftTextBlock.Text = $"{Top + Height} • {Left}"; 36 | BottomRightTextBlock.Text = $"{Top + Height} • {Left + Width}"; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Psd/LayerAndMask.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using ScreenToGif.Util; 3 | 4 | namespace ScreenToGif.ImageUtil.Psd 5 | { 6 | internal class LayerAndMask : IPsdContent 7 | { 8 | internal LayerInfo LayerInfo = new LayerInfo(); 9 | 10 | public long Length => Content?.Length ?? 0; 11 | 12 | public byte[] Content 13 | { 14 | get 15 | { 16 | using (var stream = new MemoryStream()) 17 | { 18 | var layerInfo = LayerInfo.Content; 19 | stream.WriteUInt32(BitHelper.ConvertEndian((uint)layerInfo.Length)); //Length of the LayerInfo block, 4 bytes. 20 | stream.WriteBytes(layerInfo); //Layer info block, XX bytes. 21 | 22 | stream.WriteUInt32(BitHelper.ConvertEndian((uint)0)); //Length of the Mask block, 4 bytes. 23 | 24 | //Aditional LayerInfo goes here. TODO 25 | 26 | stream.WritePadding(2); //Pad to multiple of 2 bytes. 27 | 28 | return stream.ToArray(); 29 | } 30 | } 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Gif/Decoder/GifBlock.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace ScreenToGif.ImageUtil.Gif.Decoder 5 | { 6 | public abstract class GifBlock 7 | { 8 | public static GifBlock ReadBlock(Stream stream, IEnumerable controlExtensions, bool metadataOnly) 9 | { 10 | var blockId = stream.ReadByte(); 11 | 12 | if (blockId < 0) 13 | throw GifHelpers.UnexpectedEndOfStreamException(); 14 | 15 | switch (blockId) 16 | { 17 | case GifExtension.ExtensionIntroducer: 18 | return GifExtension.ReadExtension(stream, controlExtensions, metadataOnly); 19 | case GifFrame.ImageSeparator: 20 | return GifFrame.ReadFrame(stream, controlExtensions, metadataOnly); 21 | case GifTrailer.TrailerByte: 22 | return GifTrailer.ReadTrailer(); 23 | default: 24 | throw GifHelpers.UnknownBlockTypeException(blockId); 25 | } 26 | } 27 | 28 | public abstract GifBlockKind Kind { get; } 29 | } 30 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/StringToDoubleArray.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Text.RegularExpressions; 4 | using System.Windows.Data; 5 | using System.Windows.Media; 6 | 7 | namespace ScreenToGif.Util.Converters 8 | { 9 | public class StringToDoubleArray : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | try 14 | { 15 | var text = value as string; 16 | 17 | if (string.IsNullOrWhiteSpace(text)) 18 | return new DoubleCollection { 1, 0 }; 19 | 20 | return DoubleCollection.Parse(Regex.Replace(text, " {2,}", " ")); 21 | } 22 | catch (Exception) 23 | { 24 | return new DoubleCollection { 1, 0 }; 25 | } 26 | } 27 | 28 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 29 | { 30 | var col = value as DoubleCollection; 31 | 32 | return col?.ToString().Replace(',', ' '); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /ScreenToGif/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /.github/workflows/discord-releases.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | name: Discord • Releases 3 | 4 | # Controls when the action will run. 5 | on: 6 | # Triggers the workflow on new release. 7 | release: 8 | types: [published] 9 | 10 | # Allows you to run this workflow manually from the Actions tab 11 | workflow_dispatch: 12 | 13 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 14 | jobs: 15 | # This workflow contains a single job called "released" 16 | released: 17 | # The type of runner that the job will run on 18 | runs-on: ubuntu-latest 19 | name: Sends release details to Discord/News channel 20 | 21 | # Steps represent a sequence of tasks that will be executed as part of the job 22 | steps: 23 | - name: Sending release notes 24 | 25 | # Checks-out a repository, to send the release notes 26 | uses: nhevia/discord-styled-releases@main 27 | 28 | # Gets the ID and Token from the project secrets 29 | with: 30 | webhook_id: ${{ secrets.DISCORD_WEBHOOK_ID }} 31 | webhook_token: ${{ secrets.DISCORD_WEBHOOK_TOKEN }} 32 | -------------------------------------------------------------------------------- /Other/HookTest/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34014 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace HookTest.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Other/PositioningTest/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace PositioningTest.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ScreenToGif/Capture/ICapture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using ScreenToGif.Model; 4 | 5 | namespace ScreenToGif.Capture 6 | { 7 | internal interface ICapture 8 | { 9 | bool WasStarted { get; set; } 10 | int FrameCount { get; set; } 11 | int MinimumDelay { get; set; } 12 | int Left { get; set; } 13 | int Top { get; set; } 14 | int Width { get; set; } 15 | int Height { get; set; } 16 | string DeviceName { get; set; } 17 | ProjectInfo Project { get; set; } 18 | 19 | Action OnError {get;set;} 20 | 21 | void Start(int delay, int left, int top, int width, int height, double dpi, ProjectInfo project); 22 | void ResetConfiguration(); 23 | int Capture(FrameInfo frame); 24 | Task CaptureAsync(FrameInfo frame); 25 | int CaptureWithCursor(FrameInfo frame); 26 | Task CaptureWithCursorAsync(FrameInfo frame); 27 | int ManualCapture(FrameInfo frame, bool showCursor = false); 28 | Task ManualCaptureAsync(FrameInfo frame, bool showCursor = false); 29 | void Save(FrameInfo info); 30 | Task Stop(); 31 | Task Dispose(); 32 | } 33 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/Other/StgPreset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO.Compression; 3 | 4 | namespace ScreenToGif.Model.ExportPresets.Other 5 | { 6 | public class StgPreset : ExportPreset 7 | { 8 | private CompressionLevel _compressionLevel = CompressionLevel.Optimal; 9 | 10 | 11 | public CompressionLevel CompressionLevel 12 | { 13 | get => _compressionLevel; 14 | set => SetProperty(ref _compressionLevel, value); 15 | } 16 | 17 | 18 | public StgPreset() 19 | { 20 | Type = Util.Export.Stg; 21 | ImageId = "Vector.Logo"; 22 | OutputFilenameKey = "S.Preset.Filename.Project"; 23 | DefaultExtension = ".stg"; 24 | Extension = ".stg"; 25 | IsEncoderExpanded = false; 26 | } 27 | 28 | 29 | public static StgPreset Default => new StgPreset 30 | { 31 | TitleKey = "S.Preset.Default.Title", 32 | DescriptionKey = "S.Preset.Default.Description", 33 | HasAutoSave = true, 34 | IsSelectedForEncoder = true, 35 | IsDefault = true, 36 | CreationDate = new DateTime(2021, 02, 20), 37 | }; 38 | } 39 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Psd/ImageData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using ScreenToGif.Util; 4 | 5 | namespace ScreenToGif.ImageUtil.Psd 6 | { 7 | internal class ImageData : IPsdContent 8 | { 9 | /// 10 | /// 0 = Raw Data 11 | /// 1 = RLE compressed 12 | /// 2 = ZIP without prediction 13 | /// 3 = ZIP with prediction. 14 | /// 15 | internal ushort Encoding { get; set; } = 1; 16 | 17 | internal List ImageList { get; set; } = new List(); 18 | 19 | public long Length => Content?.Length ?? 0; 20 | 21 | public byte[] Content 22 | { 23 | get 24 | { 25 | using (var stream = new MemoryStream()) 26 | { 27 | foreach (var image in ImageList) 28 | { 29 | stream.WriteUInt16(BitHelper.ConvertEndian(Encoding)); //Encoding type, 2 bytes. 30 | stream.WriteBytes(image.Content); //Image data, XX bytes. 31 | } 32 | 33 | return stream.ToArray(); 34 | } 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportFrame.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace ScreenToGif.Model 4 | { 5 | internal class ExportFrame 6 | { 7 | /// 8 | /// The position of the frame within the list. 9 | /// 10 | public int Index { get; set; } 11 | 12 | /// 13 | /// The position of the frame on the pixel array. 14 | /// 15 | public long DataPosition { get; set; } 16 | 17 | /// 18 | /// The pixel array data length of the frame. 19 | /// 20 | public long DataLength { get; set; } 21 | 22 | /// 23 | /// The delay of the frame. 24 | /// 25 | public int Delay { get; set; } 26 | 27 | /// 28 | /// The Rectangle of the frame. 29 | /// 30 | public Int32Rect Rect { get; set; } 31 | 32 | /// 33 | /// The depth in bits of the frame. 34 | /// 35 | public int ImageDepth { get; set; } 36 | 37 | /// 38 | /// True if the frame has area, width and height > 0. 39 | /// 40 | public bool HasArea => Rect.HasArea; 41 | } 42 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/ShortcutKeys.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | using ScreenToGif.Settings; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class ShortcutKeys : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | var param = parameter as string; 13 | 14 | switch (param) 15 | { 16 | case "1": //Start/Pause 17 | return Native.GetSelectKeyText(UserSettings.All.StartPauseShortcut, UserSettings.All.StartPauseModifiers, true, true); 18 | case "2": //Stop 19 | return Native.GetSelectKeyText(UserSettings.All.StopShortcut, UserSettings.All.StopModifiers, true, true); 20 | case "3": //Discard 21 | return Native.GetSelectKeyText(UserSettings.All.DiscardShortcut, UserSettings.All.DiscardModifiers, true, true); 22 | } 23 | 24 | return ""; 25 | } 26 | 27 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 28 | { 29 | return Binding.DoNothing; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/StylusTipToBool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | using System.Windows.Ink; 6 | 7 | namespace ScreenToGif.Util.Converters 8 | { 9 | public class StylusTipToBool : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | var tip = value as StylusTip?; 14 | var param = parameter as string; 15 | 16 | if (!tip.HasValue || param == null) 17 | return DependencyProperty.UnsetValue; 18 | 19 | return tip.Value.ToString().Contains(param); 20 | } 21 | 22 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 23 | { 24 | var selection = value as bool?; 25 | var param = parameter as string; 26 | 27 | if (!selection.HasValue || !selection.Value) 28 | return DependencyProperty.UnsetValue; 29 | 30 | if (string.IsNullOrEmpty(param)) 31 | return StylusTip.Rectangle; 32 | 33 | return param.Equals("Ellipse") ? StylusTip.Ellipse : StylusTip.Rectangle; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/StageToButtonString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace ScreenToGif.Util.Converters 6 | { 7 | public class StageToButtonString : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | if (!(value is Stage stage)) 12 | return LocalizationHelper.Get("S.Recorder.Record"); 13 | 14 | switch (stage) 15 | { 16 | case Stage.Stopped: 17 | return LocalizationHelper.Get("S.Recorder.Record"); 18 | case Stage.Recording: 19 | return LocalizationHelper.Get("S.Recorder.Pause"); 20 | case Stage.Paused: 21 | return LocalizationHelper.Get("S.Recorder.Continue"); 22 | case Stage.Snapping: 23 | return LocalizationHelper.Get("S.Recorder.Snap"); 24 | } 25 | 26 | return LocalizationHelper.Get("S.Recorder.Record"); 27 | } 28 | 29 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 30 | { 31 | return value; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/UploadPresets/Yandex/YandexPreset.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.Serialization; 3 | using System.Threading.Tasks; 4 | using ScreenToGif.Model.Events; 5 | using ScreenToGif.Util; 6 | using ScreenToGif.Windows; 7 | 8 | namespace ScreenToGif.Model.UploadPresets.Yandex 9 | { 10 | public class YandexPreset : UploadPreset 11 | { 12 | private string _oAuthToken = ""; 13 | 14 | [DataMember(EmitDefaultValue = false)] 15 | public string OAuthToken 16 | { 17 | get => _oAuthToken; 18 | set => SetProperty(ref _oAuthToken, value); 19 | } 20 | 21 | public YandexPreset() 22 | { 23 | Type = UploadType.Yandex; 24 | ImageId = "Vector.YandexDisk"; 25 | AllowedTypes = new List(); 26 | } 27 | 28 | public override async Task IsValid() 29 | { 30 | if (!IsAnonymous && !Cloud.YandexDisk.YandexDisk.IsAuthorized(this)) 31 | return new ValidatedEventArgs("S.SaveAs.Warning.Upload.NotAuthorized", StatusReasons.UploadServiceUnauthorized, () => App.MainViewModel.OpenOptions.Execute(Options.UploadIndex)); 32 | 33 | return await base.IsValid(); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Gif/Decoder/GifHeader.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace ScreenToGif.ImageUtil.Gif.Decoder 4 | { 5 | public class GifHeader : GifBlock 6 | { 7 | public string Signature { get; private set; } 8 | public string Version { get; private set; } 9 | public GifLogicalScreenDescriptor LogicalScreenDescriptor { get; private set; } 10 | 11 | private GifHeader() 12 | {} 13 | 14 | public override GifBlockKind Kind => GifBlockKind.Other; 15 | 16 | public static GifHeader ReadHeader(Stream stream) 17 | { 18 | var header = new GifHeader(); 19 | header.Read(stream); 20 | return header; 21 | } 22 | 23 | private void Read(Stream stream) 24 | { 25 | Signature = GifHelpers.ReadString(stream, 3); 26 | 27 | if (Signature != "GIF") 28 | throw GifHelpers.InvalidSignatureException(Signature); 29 | 30 | Version = GifHelpers.ReadString(stream, 3); 31 | 32 | if (Version != "87a" && Version != "89a") 33 | throw GifHelpers.UnsupportedVersionException(Version); 34 | 35 | LogicalScreenDescriptor = GifLogicalScreenDescriptor.ReadLogicalScreenDescriptor(stream); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/AnimatedImage/Apng/EmbeddedApngPreset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ScreenToGif.Util; 3 | 4 | namespace ScreenToGif.Model.ExportPresets.AnimatedImage.Apng 5 | { 6 | public class EmbeddedApngPreset : ApngPreset 7 | { 8 | private bool _detectUnchanged = true; 9 | private bool _paintTransparent = true; 10 | 11 | 12 | public bool DetectUnchanged 13 | { 14 | get => _detectUnchanged; 15 | set => SetProperty(ref _detectUnchanged, value); 16 | } 17 | 18 | public bool PaintTransparent 19 | { 20 | get => _paintTransparent; 21 | set => SetProperty(ref _paintTransparent, value); 22 | } 23 | 24 | 25 | public EmbeddedApngPreset() 26 | { 27 | Encoder = EncoderType.ScreenToGif; 28 | ImageId = "Vector.Logo"; 29 | } 30 | 31 | public static EmbeddedApngPreset Default = new EmbeddedApngPreset 32 | { 33 | TitleKey = "S.Preset.Default.Title", 34 | DescriptionKey = "S.Preset.Default.Description", 35 | HasAutoSave = true, 36 | IsSelectedForEncoder = true, 37 | IsDefault = true, 38 | CreationDate = new DateTime(2021, 02, 20) 39 | }; 40 | } 41 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Psd/ImageResourceBlocks/ImageResources.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Linq; 4 | using ScreenToGif.Util; 5 | 6 | namespace ScreenToGif.ImageUtil.Psd.ImageResourceBlocks 7 | { 8 | internal class ImageResources : IPsdContent 9 | { 10 | internal List ImageResourceList = new List(); 11 | 12 | public long Length => Content?.Length ?? 0; 13 | 14 | public byte[] Content 15 | { 16 | get 17 | { 18 | using (var stream = new MemoryStream()) 19 | { 20 | //If there's no ImageResource block, return a size of 0 bytes. 21 | if (ImageResourceList.Count == 0) 22 | { 23 | stream.WriteUInt32(BitHelper.ConvertEndian((uint)0)); 24 | return stream.ToArray(); 25 | } 26 | 27 | var bytes = ImageResourceList.SelectMany(s => s.Content).ToArray(); 28 | 29 | stream.WriteUInt32(BitHelper.ConvertEndian((uint)bytes.Length)); 30 | stream.WriteBytes(bytes); 31 | 32 | return stream.ToArray(); 33 | } 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/UriToBitmap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Windows.Data; 4 | using ScreenToGif.ImageUtil; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | /// 9 | /// URI to BitmapImage converter. 10 | /// 11 | public class UriToBitmap : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 14 | { 15 | var stringValue = value as string; 16 | var size = parameter as string; 17 | 18 | if (string.IsNullOrEmpty(stringValue)) 19 | return null; 20 | 21 | if (!File.Exists(stringValue)) 22 | return null; 23 | 24 | if (!string.IsNullOrEmpty(size)) 25 | return stringValue.SourceFrom(System.Convert.ToInt32(size)); 26 | 27 | var image = stringValue.SourceFrom(); 28 | 29 | if (image.PixelWidth < 3) 30 | image = stringValue.SourceFrom(); 31 | 32 | return image; 33 | } 34 | 35 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 36 | { 37 | return Binding.DoNothing; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/SelectionToEditingMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Controls; 5 | using System.Windows.Data; 6 | 7 | namespace ScreenToGif.Util.Converters 8 | { 9 | public class SelectionToEditingMode : IMultiValueConverter 10 | { 11 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | if (values.Length != 3) return DependencyProperty.UnsetValue; 14 | 15 | var penBool = values[0] as bool?; 16 | var eraserBool = values[1] as bool?; 17 | var selectorBool = values[2] as bool?; 18 | 19 | if (!penBool.HasValue || !eraserBool.HasValue || !selectorBool.HasValue) 20 | return DependencyProperty.UnsetValue; 21 | 22 | return penBool.Value ? InkCanvasEditingMode.Ink : 23 | selectorBool.Value ? InkCanvasEditingMode.Select : 24 | eraserBool.Value ? InkCanvasEditingMode.EraseByPoint : 25 | InkCanvasEditingMode.EraseByStroke; 26 | } 27 | 28 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 29 | { 30 | throw new NotImplementedException(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /ScreenToGif/Cloud/Gfycat/GfycatCreateRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Runtime.Serialization; 4 | using ScreenToGif.Model.UploadPresets.Gfycat; 5 | 6 | namespace ScreenToGif.Cloud.Gfycat 7 | { 8 | [DataContract] 9 | public class GfycatCreateRequest 10 | { 11 | public GfycatCreateRequest() 12 | { } 13 | 14 | public GfycatCreateRequest(GfycatPreset preset) 15 | { 16 | var tags = preset.DefaultTags?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) ?? new string[]{}; 17 | tags = tags.Length > 0 ? tags.Select(s => s.Trim()).ToArray() : null; 18 | 19 | Tile = preset.DefaultTitle; 20 | Description = preset.DefaultDescription; 21 | Tags = tags; 22 | IsPrivate = preset.DefaultIsPrivate; 23 | } 24 | 25 | [DataMember(Name = "title", EmitDefaultValue = false)] 26 | public string Tile { get; set; } 27 | 28 | [DataMember(Name = "description", EmitDefaultValue = false)] 29 | public string Description { get; set; } 30 | 31 | [DataMember(Name = "tags", EmitDefaultValue = false)] 32 | public string[] Tags { get; set; } 33 | 34 | [DataMember(Name = "private", EmitDefaultValue = false)] 35 | public bool IsPrivate { get; set; } 36 | } 37 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/IntToRect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class IntToRect : IMultiValueConverter 9 | { 10 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | if (values.Length < 2) 13 | return DependencyProperty.UnsetValue; 14 | 15 | var width = values[0] as double? ?? values[0] as int? ?? 0; 16 | var height = values[1] as double? ?? values[1] as int? ?? 0; 17 | 18 | if (values.Length < 4) 19 | return new Rect(new Point(0, 0), new Size(width, height)); 20 | 21 | var xAxis = values[2] as double? ?? values[2] as int? ?? 0; 22 | var yAxis = values[3] as double? ?? values[3] as int? ?? 0; 23 | 24 | if (double.IsNegativeInfinity(width) || double.IsNegativeInfinity(height)) 25 | return Rect.Empty; 26 | 27 | return new Rect(new Point(xAxis, yAxis), new Size(width, height)); 28 | } 29 | 30 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 31 | { 32 | throw new NotImplementedException(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/PathHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace ScreenToGif.Util 5 | { 6 | internal static class PathHelper 7 | { 8 | /// 9 | /// Puts the current date/time into filename, replacing the format typed in between two questions marks. 10 | /// Such as 'Animation ?dd-MM-yy?' -> 'Animation 21-04-21' 11 | /// Only some of the formats are available, since there's a file name limitation from Windows. 12 | /// https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings 13 | /// 14 | /// The name of the file, with the date/time format. 15 | /// The name with the date and time. 16 | internal static string ReplaceRegexInName(string name) 17 | { 18 | const string dateTimeFileNameRegEx = @"[?]([ymdhsfzgkt]+[-_ ]*)+[?]"; 19 | 20 | if (!Regex.IsMatch(name, dateTimeFileNameRegEx, RegexOptions.IgnoreCase)) 21 | return name; 22 | 23 | var match = Regex.Match(name, dateTimeFileNameRegEx, RegexOptions.IgnoreCase); 24 | var date = DateTime.Now.ToString(Regex.Replace(match.Value, "[?]", "")); 25 | 26 | return name.Replace(match.ToString(), date); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /ScreenToGif/Settings/Migrations.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using ScreenToGif.Settings.Migrations; 3 | 4 | namespace ScreenToGif.Settings 5 | { 6 | internal static class Migration 7 | { 8 | internal static bool Migrate(List properties, string version) 9 | { 10 | switch (version) 11 | { 12 | case "0.0": //2.27.3 or older to 2.28. 13 | Migration0To2_28_0.Up(properties); 14 | goto case "2.28"; 15 | 16 | case "2.28": //To 2.29 17 | case "2.28.1": 18 | case "2.28.2": 19 | Migration2_28_0To2_29_0.Up(properties); 20 | goto case "2.29"; 21 | 22 | case "2.29": //To 2.31 23 | case "2.29.1": 24 | case "2.30": 25 | case "2.30.1": 26 | Migration2_29_0To2_31_0.Up(properties); 27 | goto case "2.31"; 28 | 29 | case "2.31": 30 | Migration2_31_0To2_32_0.Up(properties); 31 | goto default; 32 | 33 | default: 34 | { 35 | properties.RemoveAll(p => p.Key == "Version"); 36 | return true; 37 | } 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/DoubleToRadius.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class DoubleToRadius : IMultiValueConverter 9 | { 10 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | if (values.Length < 2) 13 | return new CornerRadius(0); 14 | 15 | var left = values[0] as double? ?? values[0] as int? ?? 0; 16 | var top = values[1] as double? ?? values[1] as int? ?? 0; 17 | 18 | if (values.Length < 4) 19 | return new CornerRadius(Math.Abs(Math.Max(0, left)), Math.Abs(Math.Max(0, top)), Math.Abs(Math.Max(0, left)), Math.Abs(Math.Max(0, top))); 20 | 21 | var right = values[2] as double? ?? values[2] as int? ?? 0; 22 | var bottom = values[3] as double? ?? values[3] as int? ?? 0; 23 | 24 | return new CornerRadius(Math.Abs(Math.Max(0, left)), Math.Abs(Math.Max(0, top)), Math.Abs(Math.Max(0, right)), Math.Abs(Math.Max(0, bottom))); 25 | } 26 | 27 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 28 | { 29 | throw new NotImplementedException(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/ColorToAlpha.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Data; 8 | using System.Windows.Media; 9 | 10 | namespace ScreenToGif.Util.Converters 11 | { 12 | /// 13 | /// Gets the Color given by the binding engine and sets the given alpha value (as hexadecimal). 14 | /// 15 | public class ColorToAlpha : IValueConverter 16 | { 17 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 18 | { 19 | var color = value as Color?; 20 | var alphaAux = parameter as string; 21 | 22 | if (!color.HasValue) 23 | return value; 24 | 25 | if (String.IsNullOrEmpty(alphaAux)) 26 | return value; 27 | 28 | int alpha = 0; 29 | if (!int.TryParse(alphaAux, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out alpha)) 30 | return value; 31 | 32 | return Color.FromArgb((byte)alpha, color.Value.R, color.Value.G, color.Value.B); 33 | } 34 | 35 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 36 | { 37 | return value; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportProject.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ScreenToGif.Model 4 | { 5 | internal class ExportProject 6 | { 7 | /// 8 | /// True if the project will be passed as files instead of byte array. 9 | /// 10 | public bool UsesFiles { get; set; } 11 | 12 | /// 13 | /// The path of frame chunk. 14 | /// 15 | public string ChunkPath { get; set; } 16 | 17 | /// 18 | /// The path of frame chunk that is used to hold the new frame data when cutting the images. 19 | /// 20 | public string NewChunkPath { get; set; } 21 | 22 | /// 23 | /// Path of the folder where the files are located. 24 | /// 25 | public string Path { get; set; } 26 | 27 | /// 28 | /// List of frames. 29 | /// 30 | public List Frames { get; set; } = new List(); 31 | 32 | /// 33 | /// List of frames. 34 | /// 35 | public List FramesFiles { get; set; } = new List(); 36 | 37 | /// 38 | /// Frame count. 39 | /// 40 | public int FrameCount => UsesFiles ? FramesFiles.Count : Frames.Count; 41 | } 42 | } -------------------------------------------------------------------------------- /ScreenToGif/Settings/Migrations/Migration2_29_0To2_31_0.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace ScreenToGif.Settings.Migrations 5 | { 6 | internal class Migration2_29_0To2_31_0 7 | { 8 | internal static bool Up(List properties) 9 | { 10 | //Rename properties. 11 | var mouseClickColor = properties.FirstOrDefault(f => f.Key == "MouseClicksColor"); 12 | 13 | if (mouseClickColor != null) 14 | mouseClickColor.Key = "LeftMouseButtonClicksColor"; 15 | 16 | var tasks = properties.FirstOrDefault(f => f.Key == "AutomatedTasksList"); 17 | 18 | if (tasks != null) 19 | { 20 | foreach (var child in tasks.Children) 21 | { 22 | if (child.Type == "MouseClicksModel") 23 | { 24 | foreach (var attribute in child.Attributes) 25 | { 26 | if (attribute.Key == "ForegroundColor") 27 | { 28 | attribute.Key = "LeftButtonForegroundColor"; 29 | break; 30 | } 31 | } 32 | } 33 | } 34 | } 35 | 36 | return true; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /ScreenToGif.Cloud.YandexDisk.Tests/YandexDiskTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Net; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | 8 | namespace ScreenToGif.Cloud.YandexDisk.Tests 9 | { 10 | [TestClass] 11 | public class YandexDiskTests 12 | { 13 | [TestMethod] 14 | public async Task CanUploadFile() 15 | { 16 | var cloud = new YandexDisk("2344534523e45LW2jwerdp-efUwe4rmg"); //Paste your OAuth token 17 | 18 | // upload 19 | var result = await cloud.UploadFileAsync("1.txt", CancellationToken.None); 20 | 21 | Assert.IsNotNull(result); 22 | Assert.AreEqual(false, string.IsNullOrEmpty(result.Link)); 23 | 24 | Trace.WriteLine("link: " + result.Link); 25 | 26 | // download 27 | var data = new WebClient().DownloadData(result.Link); 28 | Assert.IsNotNull(data); 29 | } 30 | 31 | [TestMethod] 32 | [ExpectedException(typeof(UploadingException))] 33 | public async Task ThrowExceptionWhenUploadFileWithInvalidToken() 34 | { 35 | var cloud = new YandexDisk("invalid token"); 36 | 37 | // upload 38 | var result = await cloud.UploadFileAsync("1.txt", CancellationToken.None); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/StageToCanvas.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | using System.Windows.Media; 6 | 7 | namespace ScreenToGif.Util.Converters 8 | { 9 | public class StageToCanvas : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | if (!(value is Stage stage)) 14 | return (Brush)Application.Current.FindResource("Vector.Record"); 15 | 16 | switch (stage) 17 | { 18 | case Stage.Stopped: 19 | return (Brush)Application.Current.FindResource("Vector.Record"); 20 | case Stage.Recording: 21 | return (Brush)Application.Current.FindResource("Vector.Pause"); 22 | case Stage.Paused: 23 | return (Brush)Application.Current.FindResource("Vector.Record"); 24 | case Stage.Snapping: 25 | return (Brush)Application.Current.FindResource("Vector.Camera.Add"); 26 | } 27 | 28 | return (Brush)Application.Current.FindResource("Vector.Record"); 29 | } 30 | 31 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 32 | { 33 | return value; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /ScreenToGif/Controls/ExtendedProgressBar.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | 4 | namespace ScreenToGif.Controls 5 | { 6 | public class ExtendedProgressBar : ProgressBar 7 | { 8 | public enum ProgressState 9 | { 10 | Primary, 11 | Info, 12 | Warning, 13 | Danger 14 | } 15 | 16 | public static readonly DependencyProperty StateProperty = DependencyProperty.Register(nameof(State), typeof(ProgressState), typeof(ExtendedProgressBar), new PropertyMetadata(ProgressState.Primary)); 17 | public static readonly DependencyProperty ShowPercentageProperty = DependencyProperty.Register(nameof(ShowPercentage), typeof(bool), typeof(ExtendedProgressBar), new PropertyMetadata(default(bool))); 18 | 19 | public ProgressState State 20 | { 21 | get => (ProgressState)GetValue(StateProperty); 22 | set => SetValue(StateProperty, value); 23 | } 24 | 25 | public bool ShowPercentage 26 | { 27 | get => (bool) GetValue(ShowPercentageProperty); 28 | set => SetValue(ShowPercentageProperty, value); 29 | } 30 | 31 | static ExtendedProgressBar() 32 | { 33 | DefaultStyleKeyProperty.OverrideMetadata(typeof(ExtendedProgressBar), new FrameworkPropertyMetadata(typeof(ExtendedProgressBar))); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /ScreenToGif/Controls/Ribbon/RibbonTab.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Windows; 3 | using System.Windows.Controls; 4 | using System.Windows.Media; 5 | 6 | namespace ScreenToGif.Controls.Ribbon 7 | { 8 | public class RibbonTab : TabItem 9 | { 10 | #region Properties 11 | 12 | public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Image), typeof(Brush), typeof(RibbonTab)); 13 | 14 | public static readonly DependencyProperty DisplayAccentProperty = DependencyProperty.Register(nameof(DisplayAccent), typeof(bool), typeof(RibbonTab), new PropertyMetadata(true)); 15 | 16 | /// 17 | /// The icon of the tab. 18 | /// 19 | [Description("The icon of the tab.")] 20 | public Brush Icon 21 | { 22 | get => (Brush)GetValue(IconProperty); 23 | set => SetCurrentValue(IconProperty, value); 24 | } 25 | 26 | public bool DisplayAccent 27 | { 28 | get => (bool)GetValue(DisplayAccentProperty); 29 | set => SetCurrentValue(DisplayAccentProperty, value); 30 | } 31 | 32 | #endregion 33 | 34 | static RibbonTab() 35 | { 36 | DefaultStyleKeyProperty.OverrideMetadata(typeof(RibbonTab), new FrameworkPropertyMetadata(typeof(RibbonTab))); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Psd/AditionalLayers/MetadataContent.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text; 3 | using ScreenToGif.Util; 4 | 5 | namespace ScreenToGif.ImageUtil.Psd.AditionalLayers 6 | { 7 | internal class MetadataContent : IAditionalLayerInfo 8 | { 9 | internal string Signature { get; } 10 | 11 | public string Key { get; } 12 | 13 | internal bool CopyOnSheetDuplication { get; } = true; 14 | 15 | internal string Data { get; } 16 | 17 | public long Length => Content?.Length ?? 0; 18 | 19 | public byte[] Content 20 | { 21 | get 22 | { 23 | using (var stream = new MemoryStream()) 24 | { 25 | stream.WriteBytes(Encoding.ASCII.GetBytes(Signature)); //Signature, 4 bytes. 26 | stream.WriteBytes(Encoding.ASCII.GetBytes(Key)); //Key, 4 bytes. 27 | stream.WriteByte((byte)(CopyOnSheetDuplication ? 1: 0)); //Copy on sheet duplication, 1 byte. 28 | stream.Position += 3; //Padding 3 bytes. 29 | 30 | var bytes = Encoding.UTF8.GetBytes(Data); 31 | 32 | stream.WriteUInt32((uint)BitHelper.ConvertEndian(bytes.Length)); //Data length, 4 bytes. 33 | stream.WriteBytes(bytes); 34 | 35 | return stream.ToArray(); 36 | } 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Psd/Channel.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using ScreenToGif.Util; 3 | 4 | namespace ScreenToGif.ImageUtil.Psd 5 | { 6 | internal class Channel : IPsdContent 7 | { 8 | public byte[] RawContent { get; } 9 | 10 | public byte[][] RleCompressedContent { get; } 11 | 12 | public long Length => Content?.Length ?? 0; 13 | 14 | public byte[] Content 15 | { 16 | get 17 | { 18 | if (RleCompressedContent == null) 19 | return RawContent; 20 | 21 | using (var stream = new MemoryStream()) 22 | { 23 | //Writes all byte counts for all the scan lines (rows * channels), with each count stored as a two-byte value. 24 | foreach (var b in RleCompressedContent) 25 | stream.WriteUInt16(BitHelper.ConvertEndian((ushort)b.Length)); 26 | 27 | //Writes down each layer, in planar order: AAA RRR GGG BBB. 28 | foreach (var b in RleCompressedContent) 29 | stream.WriteBytes(b); 30 | 31 | return stream.ToArray(); 32 | } 33 | } 34 | } 35 | 36 | public Channel(byte[] raw) 37 | { 38 | RawContent = raw; 39 | } 40 | 41 | public Channel(byte[][] content) 42 | { 43 | RleCompressedContent = content; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Gif/Decoder/GifExtension.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace ScreenToGif.ImageUtil.Gif.Decoder 5 | { 6 | public abstract class GifExtension : GifBlock 7 | { 8 | public const int ExtensionIntroducer = 0x21; 9 | 10 | public static GifExtension ReadExtension(Stream stream, IEnumerable controlExtensions, bool metadataOnly) 11 | { 12 | //Note: at this point, the Extension Introducer (0x21) has already been read 13 | var label = stream.ReadByte(); 14 | 15 | if (label < 0) 16 | throw GifHelpers.UnexpectedEndOfStreamException(); 17 | 18 | switch (label) 19 | { 20 | case GifGraphicControlExtension.ExtensionLabel: 21 | return GifGraphicControlExtension.ReadGraphicsControl(stream); 22 | case GifCommentExtension.ExtensionLabel: 23 | return GifCommentExtension.ReadComment(stream); 24 | case GifPlainTextExtension.ExtensionLabel: 25 | return GifPlainTextExtension.ReadPlainText(stream, controlExtensions, metadataOnly); 26 | case GifApplicationExtension.ExtensionLabel: 27 | return GifApplicationExtension.ReadApplication(stream); 28 | default: 29 | throw GifHelpers.UnknownExtensionTypeException(label); 30 | } 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Other/PositioningTest/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ScreenToGif/Model/FfmpegPreset.cs: -------------------------------------------------------------------------------- 1 | using ScreenToGif.Util; 2 | 3 | namespace ScreenToGif.Model 4 | { 5 | public class FfmpegPreset : BindableBase 6 | { 7 | private string _extension; 8 | private string _name; 9 | private string _parameters; 10 | private bool _isDefault; 11 | private bool _lastSelected; 12 | 13 | public string Extension 14 | { 15 | get => _extension; 16 | set => SetProperty(ref _extension, value); 17 | } 18 | 19 | public string Name 20 | { 21 | get => _name; 22 | private set => SetProperty(ref _name, value); 23 | } 24 | 25 | public string ActualName 26 | { 27 | get => IsDefault ? LocalizationHelper.Get("S.SaveAs.Presets.Default") + $" ({Extension})" : Name; 28 | set 29 | { 30 | if (!IsDefault) 31 | Name = value; 32 | } 33 | } 34 | 35 | public string Parameters 36 | { 37 | get => _parameters; 38 | set => SetProperty(ref _parameters, value); 39 | } 40 | 41 | public bool IsDefault 42 | { 43 | get => _isDefault; 44 | set => SetProperty(ref _isDefault, value); 45 | } 46 | 47 | public bool LastSelected 48 | { 49 | get => _lastSelected; 50 | set => SetProperty(ref _lastSelected, value); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Global.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ScreenToGif.Model; 3 | 4 | namespace ScreenToGif.Util 5 | { 6 | internal static class Global 7 | { 8 | internal static DateTime StartupDateTime { get; set; } 9 | 10 | /// 11 | /// When it's true, the global shortcuts won't work. 12 | /// 13 | internal static bool IgnoreHotKeys { get; set; } 14 | 15 | /// 16 | /// When it's true, the hotfix with the bug is installed. 17 | /// https://github.com/dotnet/announcements/issues/53 18 | /// 19 | internal static bool IsHotFix4055002Installed { get; set; } 20 | 21 | /// 22 | /// When it's true, the app is currently deleting old projects. 23 | /// 24 | internal static bool IsCurrentlyDeletingFiles { get; set; } 25 | 26 | /// 27 | /// The available space on the disk that currently holds the data, as percentage. 28 | /// 29 | internal static double AvailableDiskSpacePercentage { get; set; } 30 | 31 | /// 32 | /// The available space on the disk that currently holds the data. 33 | /// 34 | internal static double AvailableDiskSpace { get; set; } 35 | 36 | /// 37 | /// Holds the details of the latest update available. 38 | /// 39 | internal static UpdateAvailable UpdateAvailable { get; set; } 40 | } 41 | } -------------------------------------------------------------------------------- /Other/HookTest/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using HookTest.Util; 4 | 5 | namespace HookTest 6 | { 7 | /// 8 | /// Interaction logic for MainWindow.xaml 9 | /// 10 | public partial class MainWindow : Window 11 | { 12 | private UserActivityHook _hook; 13 | 14 | public MainWindow() 15 | { 16 | InitializeComponent(); 17 | 18 | _hook = new UserActivityHook(true, true); 19 | _hook.OnMouseActivity += _hook_OnMouseActivity; 20 | _hook.KeyDown += _hook_KeyDown; 21 | } 22 | 23 | void _hook_KeyDown(object sender, CustomKeyEventArgs e) 24 | { 25 | KeyboardTextBox.Text += String.Format(">> {0} - {1}{2}", e.Key, DateTime.Now.ToString("HH:mm:ss"), Environment.NewLine); 26 | MouseTextBox.ScrollToLine(MouseTextBox.LineCount - 1); 27 | } 28 | 29 | void _hook_OnMouseActivity(object sender, CustomMouseEventArgs e) 30 | { 31 | MouseTextBox.Text += String.Format(">> {0} - {1}{2}", e.Button, DateTime.Now.ToString("HH:mm:ss"), Environment.NewLine); 32 | MouseTextBox.ScrollToLine(MouseTextBox.LineCount - 1); 33 | } 34 | 35 | private void StartButton_Click(object sender, RoutedEventArgs e) 36 | { 37 | _hook.Start(); 38 | } 39 | 40 | private void StopButton_Click(object sender, RoutedEventArgs e) 41 | { 42 | _hook.Stop(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/FontToSupportedGliph.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Windows; 5 | using System.Windows.Data; 6 | using System.Windows.Media; 7 | 8 | namespace ScreenToGif.Util.Converters 9 | { 10 | public class FontToSupportedGliph : IValueConverter 11 | { 12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 13 | { 14 | if (!(value is IReadOnlyCollection list)) 15 | return DependencyProperty.UnsetValue; 16 | 17 | var returnList = new List(); 18 | 19 | foreach (var font in list) 20 | { 21 | try 22 | { 23 | //Instantiate a TypeFace object with the font settings you want to use. 24 | var ltypFace = new Typeface(font, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal); 25 | 26 | //Try to create a GlyphTypeface object from the TypeFace object. 27 | if (ltypFace.TryGetGlyphTypeface(out var lglyphTypeFace)) 28 | returnList.Add(font); 29 | } 30 | catch (Exception) {} 31 | } 32 | 33 | return returnList; 34 | } 35 | 36 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 37 | { 38 | return value; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Other/Translator/Themes/Colors.xaml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ScreenToGif/Windows/Other/CommandPreviewer.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using ScreenToGif.Util; 4 | 5 | namespace ScreenToGif.Windows.Other 6 | { 7 | public partial class CommandPreviewer : Window 8 | { 9 | public string Parameters { get; set; } 10 | 11 | public string Extension { get; set; } 12 | 13 | 14 | public CommandPreviewer() 15 | { 16 | InitializeComponent(); 17 | } 18 | 19 | 20 | private void Window_Loaded(object sender, RoutedEventArgs e) 21 | { 22 | ExtensionTextBlock.Text = Extension; 23 | ParametersTextBox.Text = "ffmpeg\n" + (Parameters ?? "").Replace("{I}", $"-safe 0 -f concat -i \"[{LocalizationHelper.Get("S.CommandPreviewer.Input")}]\"") 24 | .Replace("{O}", $"-y \"[{LocalizationHelper.Get("S.CommandPreviewer.Output")}]\""); 25 | 26 | if (ParametersTextBox.Text.Contains("-pass 2")) 27 | { 28 | ParametersTextBox.Text = ParametersTextBox.Text.Replace("-pass 2 ", $"-pass 1 -passlogfile -y \"[{LocalizationHelper.Get("S.CommandPreviewer.Output")}]\" ") + 29 | Environment.NewLine + Environment.NewLine + 30 | ParametersTextBox.Text.Replace("-pass 2", $"-pass 2 -passlogfile -y \"[{LocalizationHelper.Get("S.CommandPreviewer.Output")}]\" "); 31 | } 32 | } 33 | 34 | private void OkButton_Click(object sender, RoutedEventArgs e) 35 | { 36 | Close(); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /ScreenToGif/Util/Converters/SelectionToStylusShape.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | using System.Windows.Ink; 5 | 6 | namespace ScreenToGif.Util.Converters 7 | { 8 | public class SelectionToStylusShape : IMultiValueConverter 9 | { 10 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | if (values.Length < 2) 13 | return new RectangleStylusShape(10, 10, 0); 14 | 15 | var width = values[0] as int? ?? values[0] as double?; 16 | var height = values[1] as int? ?? values[1] as double?; 17 | var isRectangle = values[2] as bool?; 18 | 19 | if (!width.HasValue) 20 | return new RectangleStylusShape(10, 10, 0); 21 | 22 | if (!height.HasValue || !isRectangle.HasValue) 23 | return new RectangleStylusShape(width.Value, 10, 0); 24 | 25 | if (isRectangle.Value) 26 | return new RectangleStylusShape(width.Value, height.Value, 0); 27 | 28 | return new EllipseStylusShape(width.Value, height.Value, 0); 29 | } 30 | 31 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 32 | { 33 | if (!(value is StylusShape shape)) 34 | return new object[] { 10d, 10d, true }; 35 | 36 | return new object[] {shape.Width, shape.Height, shape is RectangleStylusShape}; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /ScreenToGif/Windows/Other/RegionMagnifier.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Media; 3 | 4 | namespace ScreenToGif.Windows.Other 5 | { 6 | public partial class RegionMagnifier : Window 7 | { 8 | #region Properties 9 | 10 | public static readonly DependencyProperty LeftPositionProperty = DependencyProperty.Register(nameof(LeftPosition), typeof(double), typeof(RegionMagnifier), new PropertyMetadata(double.NaN)); 11 | public static readonly DependencyProperty TopPositionProperty = DependencyProperty.Register(nameof(TopPosition), typeof(double), typeof(RegionMagnifier), new PropertyMetadata(double.NaN)); 12 | public static readonly DependencyProperty ImageProperty = DependencyProperty.Register(nameof(Image), typeof(ImageSource), typeof(RegionMagnifier), new PropertyMetadata(null)); 13 | 14 | public double LeftPosition 15 | { 16 | get => (double)GetValue(LeftPositionProperty); 17 | set => SetValue(LeftPositionProperty, value); 18 | } 19 | 20 | public double TopPosition 21 | { 22 | get => (double)GetValue(TopPositionProperty); 23 | set => SetValue(TopPositionProperty, value); 24 | } 25 | 26 | public ImageSource Image 27 | { 28 | get => (ImageSource)GetValue(ImageProperty); 29 | set => SetValue(ImageProperty, value); 30 | } 31 | 32 | #endregion 33 | 34 | public RegionMagnifier() 35 | { 36 | InitializeComponent(); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Apng/Chunks/IdatChunk.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text; 3 | using ScreenToGif.Util; 4 | 5 | namespace ScreenToGif.ImageUtil.Apng.Chunks 6 | { 7 | /// 8 | /// The image data chunk. 9 | /// 10 | internal class IdatChunk : Chunk 11 | { 12 | /// 13 | /// The image data. 14 | /// 15 | internal byte[] FrameData { get; private set; } 16 | 17 | /// 18 | /// Attempts to read XX bytes of the stream. 19 | /// 20 | internal static IdatChunk Read(uint length, byte[] array) 21 | { 22 | var chunk = new IdatChunk 23 | { 24 | Length = length, //Chunk length, 4 bytes. 25 | ChunkType = "IDAT" //Chunk type, 4 bytes. 26 | }; 27 | 28 | using (var stream = new MemoryStream(array)) 29 | { 30 | //Chunk details, XX bytes. 31 | chunk.FrameData = stream.ReadBytes(length); // - 4 32 | } 33 | 34 | return chunk; 35 | } 36 | 37 | internal new void Write(Stream stream) 38 | { 39 | stream.WriteUInt32(BitHelper.ConvertEndian(Length)); //4 bytes. 40 | stream.WriteBytes(Encoding.ASCII.GetBytes(ChunkType)); //4 bytes. 41 | stream.WriteBytes(FrameData); //XX bytes. 42 | stream.WriteUInt32(BitHelper.ConvertEndian(CrcHelper.Calculate(stream.PeekBytes(stream.Position - (Length + 4), (int)Length + 4)))); //CRC, 4 bytes. 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /ScreenToGif/Windows/Other/FeedbackPreview.xaml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/Image/ImagePreset.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Management.Instrumentation; 3 | using ScreenToGif.Util; 4 | 5 | namespace ScreenToGif.Model.ExportPresets.Image 6 | { 7 | public class ImagePreset : ExportPreset 8 | { 9 | private bool _zipFiles; 10 | 11 | 12 | public bool ZipFiles 13 | { 14 | get => _zipFiles; 15 | set 16 | { 17 | SetProperty(ref _zipFiles, value); 18 | 19 | CanExportMultipleFiles = !value; 20 | Extension = value ? ".zip" : DefaultExtension; 21 | } 22 | } 23 | 24 | /// 25 | /// Internal accessor for controlling the switch of the ZipFiles property without altering the extension. 26 | /// 27 | [IgnoreMember] 28 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 29 | internal bool ZipFilesInternal 30 | { 31 | get => _zipFiles; 32 | set 33 | { 34 | SetProperty(ref _zipFiles, value); 35 | OnPropertyChanged(nameof(ZipFiles)); 36 | 37 | CanExportMultipleFiles = !value; 38 | } 39 | } 40 | 41 | 42 | public ImagePreset() 43 | { 44 | OutputFilenameKey = "S.Preset.Filename.Image"; 45 | IsEncoderExpanded = false; 46 | ExportPartially = true; 47 | PartialExport = PartialExportType.Selection; 48 | CanExportMultipleFiles = true; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /ScreenToGif/Model/ExportPresets/Other/PsdPreset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ScreenToGif.Model.ExportPresets.Other 4 | { 5 | public class PsdPreset : ExportPreset 6 | { 7 | private bool _compressImage = true; 8 | private bool _saveTimeline = true; 9 | private bool _maximizeCompatibility = true; 10 | 11 | 12 | public bool CompressImage 13 | { 14 | get => _compressImage; 15 | set => SetProperty(ref _compressImage, value); 16 | } 17 | 18 | public bool SaveTimeline 19 | { 20 | get => _saveTimeline; 21 | set => SetProperty(ref _saveTimeline, value); 22 | } 23 | 24 | public bool MaximizeCompatibility 25 | { 26 | get => _maximizeCompatibility; 27 | set => SetProperty(ref _maximizeCompatibility, value); 28 | } 29 | 30 | 31 | public PsdPreset() 32 | { 33 | Type = Util.Export.Psd; 34 | ImageId = "Vector.Logo"; 35 | OutputFilenameKey = "S.Preset.Filename.Image"; 36 | DefaultExtension = ".psd"; 37 | Extension = ".psd"; 38 | IsEncoderExpanded = false; 39 | } 40 | 41 | 42 | public static PsdPreset Default => new PsdPreset 43 | { 44 | TitleKey = "S.Preset.Default.Title", 45 | DescriptionKey = "S.Preset.Default.Description", 46 | HasAutoSave = true, 47 | IsSelectedForEncoder = true, 48 | IsDefault = true, 49 | CreationDate = new DateTime(2021, 02, 20), 50 | }; 51 | } 52 | } -------------------------------------------------------------------------------- /ScreenToGif/Readme.md: -------------------------------------------------------------------------------- 1 | # ScreenToGif 2 | 3 | This is the current project of ScreenToGif. 4 | 5 | _VS 2019 and .Net 4.8 or newer required._ 6 | 7 | ## What's new? (Version 2.33.1) 8 | 9 | • Nothing yet. 10 | 11 | ### Fixed: 12 | 13 | ♦ The option to change the editor's background based on the system's theme was not working properly (it was behaving as if it was always on). 14 | ♦ When stopping a recording by using a keyboars shortcut, the confirmation dialog to delete the previous project was not getting focus (thanks to @pawlos). 15 | ♦ When minimizing the new recorder UI by left-clicking once the system's tray icon, the region selection was not minimizing along. 16 | ♦ The editor window was not appearing on the correct screen after closing and opening again (when maximized). 17 | 18 | ### Known Bugs: 19 | 20 | ♠ When exporting with FFmpeg, the last frame may be out of sync with the timmings of the project. 21 | ♠ Cancelling a encoding of FFmpeg will result in a crash (file in use). 22 | ♠ Keystrokes has a 1 pixel transparent border at the bottom-right sides when using a high DPI screen. 23 | ♠ The newer recorder doesn't let you move the selected region to other windows. 24 | ♠ When using the capture option "Capture a frame only when something changes on screen" and moving the recording window, the recording will glitch. 25 | ♠ The Previous/Next repeat buttons are only triggering the events once (because of the command). 26 | ♠ Holding the side arrows to seek the frames for a long period makes the scrubing act jump frames. 27 | ♠ Capturing with DirectX using a screen not in landscaped mode results in a rotated frame. -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Gif/Decoder/GifFrame.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Linq; 4 | 5 | namespace ScreenToGif.ImageUtil.Gif.Decoder 6 | { 7 | public class GifFrame : GifBlock 8 | { 9 | public const int ImageSeparator = 0x2C; 10 | 11 | public GifImageDescriptor Descriptor { get; private set; } 12 | public GifColor[] LocalColorTable { get; private set; } 13 | public IList Extensions { get; private set; } 14 | public GifImageData ImageData { get; private set; } 15 | 16 | private GifFrame() 17 | {} 18 | 19 | public override GifBlockKind Kind => GifBlockKind.GraphicRendering; 20 | 21 | public static GifFrame ReadFrame(Stream stream, IEnumerable controlExtensions, bool metadataOnly) 22 | { 23 | var frame = new GifFrame(); 24 | 25 | frame.Read(stream, controlExtensions, metadataOnly); 26 | 27 | return frame; 28 | } 29 | 30 | private void Read(Stream stream, IEnumerable controlExtensions, bool metadataOnly) 31 | { 32 | //Note: at this point, the Image Separator (0x2C) has already been read 33 | Descriptor = GifImageDescriptor.ReadImageDescriptor(stream); 34 | 35 | if (Descriptor.HasLocalColorTable) 36 | LocalColorTable = GifHelpers.ReadColorTable(stream, Descriptor.LocalColorTableSize); 37 | 38 | ImageData = GifImageData.ReadImageData(stream, metadataOnly); 39 | Extensions = controlExtensions.ToList().AsReadOnly(); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Psd/LayerInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Linq; 4 | using ScreenToGif.Util; 5 | 6 | namespace ScreenToGif.ImageUtil.Psd 7 | { 8 | internal class LayerInfo : IPsdContent 9 | { 10 | internal List LayerList = new List(); 11 | internal List ImageChannelDataList = new List(); 12 | 13 | public long Length => Content?.Length ?? 0; 14 | 15 | public byte[] Content 16 | { 17 | get 18 | { 19 | using (var stream = new MemoryStream()) 20 | { 21 | var layers = LayerList.SelectMany(s => s.Content).ToArray(); 22 | //var channels = ImageChannelDataList.SelectMany(s => s.Content).ToArray(); 23 | 24 | stream.WriteInt16(BitHelper.ConvertEndian((short)(LayerList.Count))); //Number of channels of this layer, 2 bytes. Negative if absolute alpha. 25 | 26 | stream.WriteBytes(layers); //Layer records, XX bytes. 27 | //stream.WriteBytes(channels); //List of channel data, XX bytes. 28 | 29 | //List of channel data, XX bytes. Use this to avoid airthmetic overflows. 30 | foreach (var channel in ImageChannelDataList) 31 | stream.WriteBytes(channel.Content); 32 | 33 | stream.WritePadding(4); //Pad to multiple of 4 bytes. 34 | 35 | return stream.ToArray(); 36 | } 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /ScreenToGif/Controls/IntegerUpDown.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls.Primitives; 3 | 4 | namespace ScreenToGif.Controls 5 | { 6 | /// 7 | /// Integer only control with up and down buttons to change the value. 8 | /// 9 | public class IntegerUpDown : IntegerBox 10 | { 11 | #region Variables 12 | 13 | private RepeatButton _upButton; 14 | private RepeatButton _downButton; 15 | 16 | #endregion 17 | 18 | static IntegerUpDown() 19 | { 20 | DefaultStyleKeyProperty.OverrideMetadata(typeof(IntegerUpDown), new FrameworkPropertyMetadata(typeof(IntegerUpDown))); 21 | } 22 | 23 | public override void OnApplyTemplate() 24 | { 25 | base.OnApplyTemplate(); 26 | 27 | _upButton = Template.FindName("UpButton", this) as RepeatButton; 28 | _downButton = Template.FindName("DownButton", this) as RepeatButton; 29 | 30 | if (_upButton != null) 31 | _upButton.Click += UpButton_Click; 32 | 33 | if (_downButton != null) 34 | _downButton.Click += DownButton_Click; 35 | } 36 | 37 | #region Event Handlers 38 | 39 | private void DownButton_Click(object sender, RoutedEventArgs e) 40 | { 41 | if (Value > Minimum) 42 | Value -= StepValue; 43 | } 44 | 45 | private void UpButton_Click(object sender, RoutedEventArgs e) 46 | { 47 | if (Value < Maximum) 48 | Value += StepValue; 49 | } 50 | 51 | #endregion 52 | } 53 | } -------------------------------------------------------------------------------- /ScreenToGif/ImageUtil/Gif/Encoder/Quantization/MostUsedQuantizer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Windows.Media; 4 | 5 | namespace ScreenToGif.ImageUtil.Gif.Encoder.Quantization 6 | { 7 | public class MostUsedQuantizer : PaletteQuantizer 8 | { 9 | internal override void FirstPass(byte[] pixels) 10 | { 11 | //Pixels are in BGRA. 12 | Colors = new List(); 13 | 14 | for (var index = 0; index < pixels.Length; index += 4) 15 | { 16 | //Transparent colors are ignored. 17 | if (pixels[index + 3] == 0) 18 | continue; 19 | 20 | Colors.Add(new Color 21 | { 22 | B = pixels[index], 23 | G = pixels[index + 1], 24 | R = pixels[index + 2] 25 | }); 26 | } 27 | } 28 | 29 | internal override List BuildPalette() 30 | { 31 | MaxColorsWithTransparency = TransparentColor.HasValue ? MaxColors - 1 : MaxColors; 32 | 33 | var colorTable = Colors.AsParallel().GroupBy(x => x) //Grouping based on its value. 34 | .OrderByDescending(g => g.Count()) //Order by most frequent values. 35 | .Select(g => g.FirstOrDefault()) //Take the first among the group. 36 | .Take(MaxColorsWithTransparency).ToList(); //Take all the colors neeeded. 37 | 38 | if (TransparentColor.HasValue) 39 | colorTable.Add(TransparentColor.Value); 40 | 41 | return colorTable; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /ScreenToGif/Windows/Other/GoTo.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Input; 3 | 4 | namespace ScreenToGif.Windows.Other 5 | { 6 | public partial class GoTo 7 | { 8 | #region Properties 9 | 10 | public int Maximum { get; set; } 11 | 12 | public int Selected { get; set; } 13 | 14 | #endregion 15 | 16 | public GoTo(int maximum) 17 | { 18 | InitializeComponent(); 19 | 20 | Maximum = maximum; 21 | } 22 | 23 | #region Events 24 | 25 | private void Window_Loaded(object sender, RoutedEventArgs e) 26 | { 27 | GoToLabel.Content = string.Format(GoToLabel.Content.ToString(), Maximum); 28 | NumberIntegerUpDown.Maximum = Maximum; 29 | 30 | NumberIntegerUpDown.Focus(); 31 | NumberIntegerUpDown.SelectAll(); 32 | } 33 | 34 | private void Cancel_CanExecute(object sender, CanExecuteRoutedEventArgs e) 35 | { 36 | e.CanExecute = true; 37 | } 38 | 39 | private void Cancel_Executed(object sender, ExecutedRoutedEventArgs e) 40 | { 41 | DialogResult = false; 42 | } 43 | 44 | private void OkButton_Click(object sender, RoutedEventArgs e) 45 | { 46 | Selected = NumberIntegerUpDown.Value; 47 | DialogResult = true; 48 | } 49 | 50 | private void IntegerUpDown_OnKeyDown(object sender, KeyEventArgs e) 51 | { 52 | if (e.Key == Key.Enter || e.Key == Key.Return) 53 | OkButton_Click(null, null); 54 | } 55 | 56 | #endregion 57 | } 58 | } --------------------------------------------------------------------------------