├── .gitattributes ├── .gitignore ├── README.md └── Src ├── ScreenGun.Recorder.Capturers.GDIPlus ├── CursorHelper.cs ├── GDIPlusFrameCaptureBackend.cs ├── GDIStuff.cs ├── Properties │ └── AssemblyInfo.cs ├── ScreenGun.Recorder.Capturers.GDIPlus.csproj └── Win32Stuff.cs ├── ScreenGun.Recorder ├── FFMPEGScreenRecorder.cs ├── FFMPEGScreenRecorderOptions.cs ├── IFrameCaptureBackend.cs ├── IScreenRecorder.cs ├── MicrophoneRecorder.cs ├── Properties │ └── AssemblyInfo.cs ├── RecorderReporter.cs ├── RecordingStage.cs ├── ScreenGun.Recorder.csproj ├── ScreenRecorderException.cs ├── ScreenRecorderOptions.cs └── packages.config ├── ScreenGun.sln ├── ScreenGun.sln.DotSettings ├── ScreenGun ├── App.config ├── App.xaml ├── App.xaml.cs ├── AppBootstrapper.cs ├── Base │ └── ViewModel.cs ├── Converters │ ├── BetterBooleanToVisibilityConverter.cs │ └── BooleanToColorConverter.cs ├── Events │ ├── RecordingCreated.cs │ └── RecordingViewClosed.cs ├── FodyWeavers.xml ├── Icons │ ├── IconClose.xaml │ ├── IconClose.xaml.cs │ ├── IconCogwheel.xaml │ ├── IconCogwheel.xaml.cs │ ├── IconDelete.xaml │ ├── IconDelete.xaml.cs │ ├── IconFullscreen.xaml │ ├── IconFullscreen.xaml.cs │ ├── IconFullscreenExit.xaml │ ├── IconFullscreenExit.xaml.cs │ ├── IconMic.xaml │ ├── IconMic.xaml.cs │ ├── IconMicOff.xaml │ ├── IconMicOff.xaml.cs │ ├── IconRecord.xaml │ ├── IconRecord.xaml.cs │ ├── IconSave.xaml │ └── IconSave.xaml.cs ├── Misc │ ├── Command.cs │ └── NativeWindowHelper.cs ├── Modules │ ├── About │ │ ├── AboutView.xaml │ │ ├── AboutView.xaml.cs │ │ └── AboutViewModel.cs │ ├── Main │ │ ├── ScreenGunFile │ │ │ ├── RecordingDeletedHandler.cs │ │ │ ├── ScreenGunFileView.xaml │ │ │ ├── ScreenGunFileView.xaml.cs │ │ │ └── ScreenGunFileViewModel.cs │ │ ├── ShellView.xaml │ │ ├── ShellView.xaml.cs │ │ └── ShellViewModel.cs │ ├── NotifyIcon │ │ └── NotifyIconViewModel.cs │ ├── Recorder │ │ ├── RecorderView.cs │ │ └── RecorderViewModel.cs │ ├── RegionSelector │ │ ├── FullScreenChanged.cs │ │ ├── FullScreenChangedArgs.cs │ │ ├── RegionChange.cs │ │ ├── RegionChangeArgs.cs │ │ ├── RegionSelectorWindow.xaml │ │ └── RegionSelectorWindow.xaml.cs │ └── Settings │ │ ├── IScreenGunSettings.cs │ │ ├── RecordingDevice.cs │ │ ├── SettingsFile.cs │ │ ├── SettingsView.xaml │ │ ├── SettingsView.xaml.cs │ │ └── SettingsViewModel.cs ├── Properties │ ├── Annotations.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Resources │ ├── VisibilityConverters.xaml │ ├── record_icon.ico │ └── record_icon.png ├── ScreenGun.csproj ├── ffmpeg.exe ├── packages.config └── record_icon.ico ├── Settings.StyleCop └── build └── ScreenGun ├── ScreenGun.exe └── ffmpeg.exe /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #ignore thumbnails created by windows 2 | Thumbs.db 3 | #Ignore files build by Visual Studio 4 | *.user 5 | *.aps 6 | *.pch 7 | *.vspscc 8 | *_i.c 9 | *_p.c 10 | *.ncb 11 | *.suo 12 | *.bak 13 | *.cache 14 | *.ilk 15 | *.log 16 | *.log.* 17 | [Bb]in 18 | [Dd]ebug*/ 19 | *.sbr 20 | obj/ 21 | [Rr]elease*/ 22 | _ReSharper*/ 23 | packages/ 24 | .nuget 25 | packages 26 | obj 27 | bin -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | # ScreenGun 6 | 7 | The free screen recorder for Windows, based on FFMPEG. 8 | 9 | ![Recorder View](http://i.imgur.com/re5glAH.jpg) 10 | 11 | # Quickstart 12 | 13 | 14 | * [Download it](https://github.com/jeffijoe/screengun/releases/download/0.1.2/ScreenGun.zip) 15 | * Extract somewhere and run `ScreenGun.exe` 16 | * Press "New Recording" 17 | * Select the area you wish to record, amd press the **Record**: 18 | 19 | ![Record button](http://i.imgur.com/OY0iT1e.png) 20 | 21 | * To stop recording, click on the ScreenGun icon in the system tray: 22 | 23 | ![Icon](http://i.imgur.com/UGRARNG.png) 24 | 25 | # What is it? 26 | 27 | ScreenGun is a very simple tool to make quick screen recordings in excellent quality at the expense of framerate. 28 | 29 | **ScreenGun is suitable for** 30 | 31 | * Quick demos 32 | * Showing your parents how to send an email 33 | * Small tutorials 34 | 35 | **ScreenGun is NOT suitable for** 36 | 37 | * Game recordings 38 | * .. other things requiring a high framerate 39 | 40 | # The techy stuff 41 | 42 | ScreenGun uses Window's GDI+ to take screenshots as fast as it can (basically the same as `PrtScr`). It timestamps these frames internally and generates a textfile to be fed to the `ffmpeg` concat demuxer. For audio, ScreenGun uses NAudio to record the selected microphone. It also records the cursor. 43 | 44 | # Author 45 | 46 | Jeff Hansen - [@Jeffijoe](https://twitter.com/Jeffijoe) -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder.Capturers.GDIPlus/CursorHelper.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - CursorHelper.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System; 10 | using System.Diagnostics; 11 | using System.Diagnostics.CodeAnalysis; 12 | using System.Drawing; 13 | using System.Runtime.InteropServices; 14 | 15 | namespace ScreenGun.Recorder.Capturers.GDIPlus 16 | { 17 | /// 18 | /// The rt global cursor. 19 | /// 20 | public class CursorHelper 21 | { 22 | #region Constants 23 | 24 | /// 25 | /// The curso r_ showing. 26 | /// 27 | private const int CURSOR_SHOWING = 1; 28 | 29 | #endregion 30 | 31 | #region Public Methods and Operators 32 | 33 | /// 34 | /// The capture cursor. 35 | /// 36 | /// 37 | /// The x. 38 | /// 39 | /// 40 | /// The y. 41 | /// 42 | /// 43 | /// The . 44 | /// 45 | public static Bitmap CaptureCursor(ref int x, ref int y) 46 | { 47 | Win32Stuff.CURSORINFO cursorInfo = new Win32Stuff.CURSORINFO(); 48 | cursorInfo.cbSize = Marshal.SizeOf(cursorInfo); 49 | if (!Win32Stuff.GetCursorInfo(out cursorInfo)) 50 | { 51 | return null; 52 | } 53 | 54 | if (cursorInfo.flags != Win32Stuff.CURSOR_SHOWING) 55 | { 56 | return null; 57 | } 58 | 59 | IntPtr hicon = Win32Stuff.CopyIcon(cursorInfo.hCursor); 60 | if (hicon == IntPtr.Zero) 61 | { 62 | return null; 63 | } 64 | 65 | Win32Stuff.ICONINFO iconInfo; 66 | if (!Win32Stuff.GetIconInfo(hicon, out iconInfo)) 67 | { 68 | return null; 69 | } 70 | 71 | x = cursorInfo.ptScreenPos.x - ((int)iconInfo.xHotspot); 72 | y = cursorInfo.ptScreenPos.y - ((int)iconInfo.yHotspot); 73 | 74 | using (Bitmap maskBitmap = Bitmap.FromHbitmap(iconInfo.hbmMask)) 75 | { 76 | // Is this a monochrome cursor? 77 | if (maskBitmap.Height == maskBitmap.Width * 2) 78 | { 79 | Bitmap resultBitmap = new Bitmap(maskBitmap.Width, maskBitmap.Width); 80 | 81 | using (Graphics desktopGraphics = Graphics.FromHwnd(Win32Stuff.GetDesktopWindow())) 82 | { 83 | IntPtr desktopHdc = desktopGraphics.GetHdc(); 84 | 85 | IntPtr maskHdc = GDIStuff.CreateCompatibleDC(desktopHdc); 86 | IntPtr oldPtr = GDIStuff.SelectObject(maskHdc, maskBitmap.GetHbitmap()); 87 | 88 | using (Graphics resultGraphics = Graphics.FromImage(resultBitmap)) 89 | { 90 | IntPtr resultHdc = resultGraphics.GetHdc(); 91 | 92 | // These two operation will result in a black cursor over a white background. 93 | // Later in the code, a call to MakeTransparent() will get rid of the white background. 94 | GDIStuff.BitBlt( 95 | resultHdc, 96 | 0, 97 | 0, 98 | 32, 99 | 32, 100 | maskHdc, 101 | 0, 102 | 32, 103 | (int)GDIStuff.TernaryRasterOperations.SRCCOPY); 104 | GDIStuff.BitBlt( 105 | resultHdc, 106 | 0, 107 | 0, 108 | 32, 109 | 32, 110 | maskHdc, 111 | 0, 112 | 0, 113 | (int)GDIStuff.TernaryRasterOperations.SRCINVERT); 114 | 115 | resultGraphics.ReleaseHdc(resultHdc); 116 | GDIStuff.DeleteDC(resultHdc); 117 | GDIStuff.DeleteObject(resultHdc); 118 | } 119 | 120 | IntPtr newPtr = GDIStuff.SelectObject(maskHdc, oldPtr); 121 | GDIStuff.DeleteObject(oldPtr); 122 | GDIStuff.DeleteObject(newPtr); 123 | GDIStuff.DeleteDC(maskHdc); 124 | desktopGraphics.ReleaseHdc(desktopHdc); 125 | GDIStuff.DeleteDC(desktopHdc); 126 | } 127 | 128 | // Remove the white background from the BitBlt calls, 129 | // resulting in a black cursor over a transparent background. 130 | resultBitmap.MakeTransparent(Color.White); 131 | return resultBitmap; 132 | } 133 | } 134 | 135 | //// Delete the mask, if present. 136 | // if (iconInfo.hbmMask != IntPtr.Zero) 137 | // { 138 | // DeleteObject(iconInfo.hbmMask); 139 | // } 140 | 141 | //// Delete the color bitmap, if present. 142 | // if (iconInfo.hbmColor != IntPtr.Zero) 143 | // { 144 | // DeleteObject(iconInfo.hbmColor); 145 | // } 146 | using (Icon icon = Icon.FromHandle(hicon)) 147 | { 148 | return icon.ToBitmap(); 149 | } 150 | } 151 | 152 | #endregion 153 | 154 | #region Methods 155 | 156 | /// 157 | /// The copy icon. 158 | /// 159 | /// 160 | /// The h icon. 161 | /// 162 | /// 163 | /// The . 164 | /// 165 | [DllImport("user32.dll")] 166 | private static extern IntPtr CopyIcon(IntPtr hIcon); 167 | 168 | /// 169 | /// The delete object. 170 | /// 171 | /// 172 | /// The h dc. 173 | /// 174 | /// 175 | /// The . 176 | /// 177 | [DllImport("gdi32.dll")] 178 | private static extern IntPtr DeleteObject(IntPtr hDc); 179 | 180 | /// 181 | /// The destroy icon. 182 | /// 183 | /// 184 | /// The h icon. 185 | /// 186 | /// 187 | /// The . 188 | /// 189 | [DllImport("user32.dll")] 190 | private static extern bool DestroyIcon(IntPtr hIcon); 191 | 192 | /// 193 | /// The get cursor info. 194 | /// 195 | /// 196 | /// The pci. 197 | /// 198 | /// 199 | /// The . 200 | /// 201 | [DllImport("user32.dll")] 202 | private static extern bool GetCursorInfo(out CURSORINFO pci); 203 | 204 | /// 205 | /// The get gdi handle count. 206 | /// 207 | /// 208 | /// The . 209 | /// 210 | private static int GetGDIHandleCount() 211 | { 212 | return GetGuiResources(Process.GetCurrentProcess().Handle, 0); 213 | } 214 | 215 | /// 216 | /// The get gui resources. 217 | /// 218 | /// 219 | /// The h process. 220 | /// 221 | /// 222 | /// The ui flags. 223 | /// 224 | /// 225 | /// The . 226 | /// 227 | [DllImport("user32.dll")] 228 | private static extern int GetGuiResources(IntPtr hProcess, int uiFlags); 229 | 230 | /// 231 | /// The get icon info. 232 | /// 233 | /// 234 | /// The h icon. 235 | /// 236 | /// 237 | /// The piconinfo. 238 | /// 239 | /// 240 | /// The . 241 | /// 242 | [DllImport("user32.dll")] 243 | private static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo); 244 | 245 | /// 246 | /// The get user handle count. 247 | /// 248 | /// 249 | /// The . 250 | /// 251 | private static int GetUserHandleCount() 252 | { 253 | return GetGuiResources(Process.GetCurrentProcess().Handle, 1); 254 | } 255 | 256 | /// 257 | /// The handle message. 258 | /// 259 | /// 260 | /// The message. 261 | /// 262 | private static void HandleMessage(string message) 263 | { 264 | Debug.WriteLine("HC: " + message + ": GDI: " + GetGDIHandleCount() + ": User: " + GetUserHandleCount()); 265 | } 266 | 267 | #endregion 268 | 269 | /// 270 | /// The cursorinfo. 271 | /// 272 | [StructLayout(LayoutKind.Sequential)] 273 | private struct CURSORINFO 274 | { 275 | // Fields 276 | /// 277 | /// The cb size. 278 | /// 279 | [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here."), 280 | SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")] 281 | public int cbSize; 282 | 283 | /// 284 | /// The flags. 285 | /// 286 | [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here."), 287 | SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")] 288 | public int flags; 289 | 290 | /// 291 | /// The h cursor. 292 | /// 293 | [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here."), 294 | SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")] 295 | public IntPtr hCursor; 296 | 297 | /// 298 | /// The pt screen pos. 299 | /// 300 | [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here."), 301 | SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Reviewed. Suppression is OK here.")] 302 | public POINT ptScreenPos; 303 | } 304 | 305 | /// 306 | /// The iconinfo. 307 | /// 308 | [StructLayout(LayoutKind.Sequential)] 309 | private struct ICONINFO 310 | { 311 | // Fields 312 | /// 313 | /// The f icon. 314 | /// 315 | public bool fIcon; 316 | 317 | /// 318 | /// The x hotspot. 319 | /// 320 | public int xHotspot; 321 | 322 | /// 323 | /// The y hotspot. 324 | /// 325 | public int yHotspot; 326 | 327 | // Handle of the icon’s bitmask bitmap. 328 | /// 329 | /// The hbm mask. 330 | /// 331 | public IntPtr hbmMask; 332 | 333 | // Handle of the icon’s color bitmap. Optional for monochrome icons. 334 | /// 335 | /// The hbm color. 336 | /// 337 | public IntPtr hbmColor; 338 | } 339 | 340 | /// 341 | /// The point. 342 | /// 343 | [StructLayout(LayoutKind.Sequential)] 344 | private struct POINT 345 | { 346 | // Fields 347 | /// 348 | /// The x. 349 | /// 350 | public int x; 351 | 352 | /// 353 | /// The y. 354 | /// 355 | public int y; 356 | } 357 | 358 | ///// 359 | ///// The capture cursor. 360 | ///// 361 | ///// 362 | ///// The x. 363 | ///// 364 | ///// 365 | ///// The y. 366 | ///// 367 | ///// 368 | ///// The . 369 | ///// 370 | // public static Bitmap CaptureCursor(ref int x, ref int y) 371 | // { 372 | // try 373 | // { 374 | // // Return value initially nothing 375 | // Bitmap bmp = null; 376 | 377 | // CURSORINFO curInfo = new CURSORINFO(); 378 | // curInfo.cbSize = Marshal.SizeOf(curInfo); 379 | 380 | // // HandleMessage("Start") 381 | // if (GetCursorInfo(ref curInfo)) 382 | // { 383 | // if (curInfo.flags == CURSOR_SHOWING) 384 | // { 385 | // IntPtr hicon = CopyIcon(curInfo.hCursor); 386 | 387 | // if (hicon != IntPtr.Zero) 388 | // { 389 | // ICONINFO icoInfo = default(ICONINFO); 390 | // if (GetIconInfo(hicon, ref icoInfo)) 391 | // { 392 | // // Delete the mask, if present. 393 | // if (icoInfo.hbmMask != IntPtr.Zero) 394 | // { 395 | // DeleteObject(icoInfo.hbmMask); 396 | // } 397 | 398 | // // Delete the color bitmap, if present. 399 | // if (icoInfo.hbmColor != IntPtr.Zero) 400 | // { 401 | // DeleteObject(icoInfo.hbmColor); 402 | // } 403 | 404 | // x = curInfo.ptScreenPos.x - icoInfo.xHotspot; 405 | // y = curInfo.ptScreenPos.y - icoInfo.yHotspot; 406 | // } 407 | 408 | // Icon ic = Icon.FromHandle(hicon); 409 | // bmp = ic.ToBitmap(); 410 | 411 | // // Must destroy the icon object we got from CopyIcon 412 | // DestroyIcon(hicon); 413 | // } 414 | // } 415 | // } 416 | 417 | // // HandleMessage("End") 418 | // return bmp; 419 | // } 420 | // catch 421 | // { 422 | // return null; 423 | // } 424 | // } 425 | } 426 | } -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder.Capturers.GDIPlus/GDIPlusFrameCaptureBackend.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - GDIPlusFrameCaptureBackend.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Drawing; 10 | using System.Drawing.Imaging; 11 | using System.Windows.Forms; 12 | 13 | namespace ScreenGun.Recorder.Capturers.GDIPlus 14 | { 15 | /// 16 | /// GDI+ Back-end. 17 | /// 18 | public class GDIPlusFrameCaptureBackend : IFrameCaptureBackend 19 | { 20 | #region Public Methods and Operators 21 | 22 | /// 23 | /// Captures a frame. 24 | /// 25 | /// 26 | /// The region. 27 | /// 28 | /// 29 | /// A bitmap containing the captured frame. 30 | /// 31 | public Bitmap CaptureFrame(Rectangle region) 32 | { 33 | // Create a new bitmap. 34 | var frameBitmap = new Bitmap( 35 | region.Width, 36 | region.Height, 37 | PixelFormat.Format32bppArgb); 38 | 39 | // Create a graphics object from the bitmap. 40 | using (var gfxScreenshot = Graphics.FromImage(frameBitmap)) 41 | { 42 | // Take the screenshot from the upper left corner to the right bottom corner. 43 | gfxScreenshot.CopyFromScreen( 44 | region.X, 45 | region.Y, 46 | 0, 47 | 0, 48 | region.Size, 49 | CopyPixelOperation.SourceCopy); 50 | 51 | Point position = Cursor.Position; 52 | var x = position.X; 53 | var y = position.Y; 54 | var cursorBmp = CursorHelper.CaptureCursor(ref x, ref y); 55 | 56 | // We need to offset the cursor position by the region, to position it correctly 57 | // in the image. 58 | position = new Point( 59 | x - region.X, 60 | y - region.Y); 61 | if (cursorBmp != null) 62 | { 63 | gfxScreenshot.DrawImage(cursorBmp, position); 64 | } 65 | 66 | cursorBmp.Dispose(); 67 | } 68 | 69 | return frameBitmap; 70 | } 71 | 72 | #endregion 73 | } 74 | } -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder.Capturers.GDIPlus/GDIStuff.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffijoe/screengun/7bb60297f7c6c6ef3f7eab43377f4c14e9d9232f/Src/ScreenGun.Recorder.Capturers.GDIPlus/GDIStuff.cs -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder.Capturers.GDIPlus/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - AssemblyInfo.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Reflection; 10 | using System.Runtime.InteropServices; 11 | 12 | // General Information about an assembly is controlled through the following 13 | // set of attributes. Change these attribute values to modify the information 14 | // associated with an assembly. 15 | [assembly: AssemblyTitle("ScreenGun.Recorder.Capturers.GDIPlus")] 16 | [assembly: AssemblyDescription("")] 17 | [assembly: AssemblyConfiguration("")] 18 | [assembly: AssemblyCompany("")] 19 | [assembly: AssemblyProduct("ScreenGun.Recorder.Capturers.GDIPlus")] 20 | [assembly: AssemblyCopyright("Copyright © 2015")] 21 | [assembly: AssemblyTrademark("")] 22 | [assembly: AssemblyCulture("")] 23 | 24 | // Setting ComVisible to false makes the types in this assembly not visible 25 | // to COM components. If you need to access a type in this assembly from 26 | // COM, set the ComVisible attribute to true on that type. 27 | [assembly: ComVisible(false)] 28 | 29 | // The following GUID is for the ID of the typelib if this project is exposed to COM 30 | [assembly: Guid("86006ccd-a61f-46f9-8d0b-dfc1a3d2180a")] 31 | 32 | // Version information for an assembly consists of the following four values: 33 | // Major Version 34 | // Minor Version 35 | // Build Number 36 | // Revision 37 | // You can specify all the values or you can default the Build and Revision Numbers 38 | // by using the '*' as shown below: 39 | // [assembly: AssemblyVersion("1.0.*")] 40 | [assembly: AssemblyVersion("1.0.0.0")] 41 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder.Capturers.GDIPlus/ScreenGun.Recorder.Capturers.GDIPlus.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {2823434A-15E1-4E83-8A76-E351E39A6CDC} 8 | Library 9 | Properties 10 | ScreenGun.Recorder.Capturers.GDIPlus 11 | ScreenGun.Recorder.Capturers.GDIPlus 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | {DDED37F6-F6BC-4A81-90CA-E3128401A635} 53 | ScreenGun.Recorder 54 | 55 | 56 | 57 | 64 | -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder.Capturers.GDIPlus/Win32Stuff.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffijoe/screengun/7bb60297f7c6c6ef3f7eab43377f4c14e9d9232f/Src/ScreenGun.Recorder.Capturers.GDIPlus/Win32Stuff.cs -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder/FFMPEGScreenRecorderOptions.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - FFMPEGScreenRecorderOptions.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | namespace ScreenGun.Recorder 9 | { 10 | /// 11 | /// The ffmpeg screen recorder options. 12 | /// 13 | public class FFMPEGScreenRecorderOptions 14 | { 15 | #region Constructors and Destructors 16 | 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | /// 21 | /// The ffmpeg path. 22 | /// 23 | /// 24 | /// The frame capture backend. 25 | /// 26 | public FFMPEGScreenRecorderOptions(string ffmpegPath, IFrameCaptureBackend frameCaptureBackend) 27 | { 28 | this.FfmpegPath = ffmpegPath; 29 | this.FrameCaptureBackend = frameCaptureBackend; 30 | } 31 | 32 | #endregion 33 | 34 | #region Public Properties 35 | 36 | /// 37 | /// Gets the ffmpeg path. 38 | /// 39 | public string FfmpegPath { get; private set; } 40 | 41 | /// 42 | /// Gets the frame capture backend. 43 | /// 44 | /// 45 | /// The frame capture backend. 46 | /// 47 | public IFrameCaptureBackend FrameCaptureBackend { get; private set; } 48 | 49 | #endregion 50 | } 51 | } -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder/IFrameCaptureBackend.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - IFrameCaptureBackend.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Drawing; 10 | 11 | namespace ScreenGun.Recorder 12 | { 13 | /// 14 | /// Interface for frame capturing back-ends. 15 | /// 16 | public interface IFrameCaptureBackend 17 | { 18 | #region Public Methods and Operators 19 | 20 | /// 21 | /// Captures a frame. 22 | /// 23 | /// 24 | /// The region. 25 | /// 26 | /// 27 | /// A bitmap containing the captured frame. 28 | /// 29 | Bitmap CaptureFrame(Rectangle region); 30 | 31 | #endregion 32 | } 33 | } -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder/IScreenRecorder.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffijoe/screengun/7bb60297f7c6c6ef3f7eab43377f4c14e9d9232f/Src/ScreenGun.Recorder/IScreenRecorder.cs -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder/MicrophoneRecorder.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - MicrophoneRecorder.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using NAudio.Wave; 10 | using System.Diagnostics; 11 | 12 | namespace ScreenGun.Recorder 13 | { 14 | /// 15 | /// The microphone recorder. 16 | /// 17 | public class MicrophoneRecorder 18 | { 19 | #region Fields 20 | 21 | /// 22 | /// The material folder. 23 | /// 24 | private readonly string outputFilePath; 25 | 26 | /// 27 | /// The wave file. 28 | /// 29 | private WaveFileWriter waveFile; 30 | 31 | /// 32 | /// The wave source. 33 | /// 34 | private WaveInEvent waveSource; 35 | 36 | #endregion 37 | 38 | #region Constructors and Destructors 39 | 40 | /// 41 | /// Initializes a new instance of the class. 42 | /// 43 | /// 44 | /// The material folder. 45 | /// 46 | public MicrophoneRecorder(string outputFilePath, int deviceNumber) 47 | { 48 | this.DeviceNumber = deviceNumber; 49 | this.outputFilePath = outputFilePath; 50 | } 51 | 52 | /// 53 | /// The device number. 54 | /// 55 | public int DeviceNumber { get; private set; } 56 | 57 | #endregion 58 | 59 | #region Public Methods and Operators 60 | 61 | /// 62 | /// The start. 63 | /// 64 | public void Start() 65 | { 66 | this.waveSource = new WaveInEvent 67 | { 68 | DeviceNumber = this.DeviceNumber, 69 | WaveFormat = new WaveFormat(44100, 2) 70 | }; 71 | 72 | this.waveFile = new WaveFileWriter( 73 | this.outputFilePath, 74 | this.waveSource.WaveFormat); 75 | this.waveSource.DataAvailable += this.OnWaveSourceOnDataAvailable; 76 | this.waveSource.StartRecording(); 77 | } 78 | 79 | /// 80 | /// The stop. 81 | /// 82 | public void Stop() 83 | { 84 | if (this.waveSource != null) 85 | { 86 | this.waveSource.StopRecording(); 87 | this.waveSource.DataAvailable -= this.OnWaveSourceOnDataAvailable; 88 | this.waveSource.Dispose(); 89 | this.waveSource = null; 90 | } 91 | 92 | if (this.waveFile != null) 93 | { 94 | this.waveFile.Dispose(); 95 | this.waveFile = null; 96 | } 97 | } 98 | 99 | #endregion 100 | 101 | #region Methods 102 | 103 | /// 104 | /// The on wave source on data available. 105 | /// 106 | /// 107 | /// The sender. 108 | /// 109 | /// 110 | /// The args. 111 | /// 112 | private void OnWaveSourceOnDataAvailable(object sender, WaveInEventArgs args) 113 | { 114 | if (this.waveFile != null) 115 | { 116 | this.waveFile.Write(args.Buffer, 0, args.BytesRecorded); 117 | this.waveFile.Flush(); 118 | } 119 | } 120 | 121 | #endregion 122 | } 123 | } -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - AssemblyInfo.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Reflection; 10 | using System.Runtime.InteropServices; 11 | 12 | // General Information about an assembly is controlled through the following 13 | // set of attributes. Change these attribute values to modify the information 14 | // associated with an assembly. 15 | [assembly: AssemblyTitle("ScreenGun.Recorder")] 16 | [assembly: AssemblyDescription("")] 17 | [assembly: AssemblyConfiguration("")] 18 | [assembly: AssemblyCompany("")] 19 | [assembly: AssemblyProduct("ScreenGun.Recorder")] 20 | [assembly: AssemblyCopyright("Copyright © 2015")] 21 | [assembly: AssemblyTrademark("")] 22 | [assembly: AssemblyCulture("")] 23 | 24 | // Setting ComVisible to false makes the types in this assembly not visible 25 | // to COM components. If you need to access a type in this assembly from 26 | // COM, set the ComVisible attribute to true on that type. 27 | [assembly: ComVisible(false)] 28 | 29 | // The following GUID is for the ID of the typelib if this project is exposed to COM 30 | [assembly: Guid("6730ddec-d8cc-42d1-a659-c0a2fa91ae15")] 31 | 32 | // Version information for an assembly consists of the following four values: 33 | // Major Version 34 | // Minor Version 35 | // Build Number 36 | // Revision 37 | // You can specify all the values or you can default the Build and Revision Numbers 38 | // by using the '*' as shown below: 39 | // [assembly: AssemblyVersion("1.0.*")] 40 | [assembly: AssemblyVersion("1.0.0.0")] 41 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder/RecorderReporter.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - RecorderReporter.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | namespace ScreenGun.Recorder 9 | { 10 | /// 11 | /// State telling the application what the recorder is doing. 12 | /// 13 | public class RecorderState 14 | { 15 | #region Constructors and Destructors 16 | 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | /// 21 | /// The stage. 22 | /// 23 | public RecorderState(RecordingStage stage) 24 | { 25 | this.Stage = stage; 26 | } 27 | 28 | #endregion 29 | 30 | #region Public Properties 31 | 32 | /// 33 | /// Gets the stage. 34 | /// 35 | /// 36 | /// The stage. 37 | /// 38 | public RecordingStage Stage { get; private set; } 39 | 40 | #endregion 41 | } 42 | } -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder/RecordingStage.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - RecordingStage.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | namespace ScreenGun.Recorder 9 | { 10 | /// 11 | /// An enumeration describing what is being done right now. 12 | /// 13 | public enum RecordingStage 14 | { 15 | /// 16 | /// Nothing is being done. 17 | /// 18 | DoingNothing, 19 | 20 | /// 21 | /// We are recording. 22 | /// 23 | Recording, 24 | 25 | /// 26 | /// The recording has been stopped, and is currently being encoded. 27 | /// 28 | Encoding, 29 | 30 | /// 31 | /// Encoding is done, recording complete. 32 | /// 33 | Done 34 | } 35 | } -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder/ScreenGun.Recorder.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DDED37F6-F6BC-4A81-90CA-E3128401A635} 8 | Library 9 | Properties 10 | ScreenGun.Recorder 11 | ScreenGun.Recorder 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\NAudio.1.7.3\lib\net35\NAudio.dll 35 | True 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 69 | -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder/ScreenRecorderException.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - ScreenRecorderException.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System; 10 | 11 | namespace ScreenGun.Recorder 12 | { 13 | /// 14 | /// Screen recorder exception. 15 | /// 16 | public class ScreenRecorderException : Exception 17 | { 18 | #region Constructors and Destructors 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | /// 24 | /// The not recording. 25 | /// 26 | public ScreenRecorderException(string message) 27 | : base(message) 28 | { 29 | } 30 | 31 | /// 32 | /// Initializes a new instance of the class. 33 | /// 34 | /// 35 | /// The error message that explains the reason for the exception. 36 | /// 37 | /// 38 | /// The exception that is the cause of the current exception, or a null reference (Nothing in 39 | /// Visual Basic) if no inner exception is specified. 40 | /// 41 | public ScreenRecorderException(string message, Exception innerException) 42 | : base(message, innerException) 43 | { 44 | } 45 | 46 | #endregion 47 | } 48 | } -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder/ScreenRecorderOptions.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - ScreenRecorderOptions.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System; 10 | using System.Drawing; 11 | using System.IO; 12 | using System.Reflection; 13 | 14 | namespace ScreenGun.Recorder 15 | { 16 | /// 17 | /// Options for the screen recorder. 18 | /// 19 | public class ScreenRecorderOptions 20 | { 21 | #region Constructors and Destructors 22 | 23 | /// 24 | /// Initializes a new instance of the class. 25 | /// 26 | /// 27 | /// The recording Region. 28 | /// 29 | public ScreenRecorderOptions(Rectangle recordingRegion) 30 | { 31 | this.RecordingRegion = recordingRegion; 32 | this.MaterialTempFolder = Path.Combine(Path.GetTempPath(), Assembly.GetCallingAssembly().GetName().Name); 33 | this.OutputFilePath = AppDomain.CurrentDomain.BaseDirectory; 34 | } 35 | 36 | #endregion 37 | 38 | #region Public Properties 39 | 40 | /// 41 | /// Gets or sets a value indicating whether to delete material when done. 42 | /// Default is false. 43 | /// 44 | /// 45 | /// true if delete material when done; otherwise, false. 46 | /// 47 | public bool DeleteMaterialWhenDone { get; set; } 48 | 49 | /// 50 | /// Gets or sets the material temporary folder. Default is a temp folder from the user's path. 51 | /// 52 | /// 53 | /// This folder will contain the materials folder, which will be deleted when done, if 54 | /// is true. 55 | /// 56 | /// 57 | /// The screenshots temporary folder. 58 | /// 59 | public string MaterialTempFolder { get; set; } 60 | 61 | /// 62 | /// Gets or sets the output file path. Default is Video.mp4 in the app's folder. 63 | /// 64 | /// 65 | /// The output file. 66 | /// 67 | public string OutputFilePath { get; set; } 68 | 69 | /// 70 | /// Gets or sets a value indicating whether to record the microphone. 71 | /// 72 | /// 73 | /// true if we want to record the microphone; otherwise, false. 74 | /// 75 | public bool RecordMicrophone { get; set; } 76 | 77 | /// 78 | /// Gets or sets the recording region. Not set to any default. 79 | /// 80 | /// 81 | /// The recording region. 82 | /// 83 | public Rectangle RecordingRegion { get; set; } 84 | 85 | /// 86 | /// What device number should we use to record audio on? 87 | /// 88 | public int AudioRecordingDeviceNumber { get; set; } 89 | 90 | #endregion 91 | } 92 | } -------------------------------------------------------------------------------- /Src/ScreenGun.Recorder/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Src/ScreenGun.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScreenGun", "ScreenGun\ScreenGun.csproj", "{ABDA71DA-6ECA-4CD7-8403-C47691AADB00}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScreenGun.Recorder", "ScreenGun.Recorder\ScreenGun.Recorder.csproj", "{DDED37F6-F6BC-4A81-90CA-E3128401A635}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScreenGun.Recorder.Capturers.GDIPlus", "ScreenGun.Recorder.Capturers.GDIPlus\ScreenGun.Recorder.Capturers.GDIPlus.csproj", "{2823434A-15E1-4E83-8A76-E351E39A6CDC}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {ABDA71DA-6ECA-4CD7-8403-C47691AADB00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {ABDA71DA-6ECA-4CD7-8403-C47691AADB00}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {ABDA71DA-6ECA-4CD7-8403-C47691AADB00}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {ABDA71DA-6ECA-4CD7-8403-C47691AADB00}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {DDED37F6-F6BC-4A81-90CA-E3128401A635}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {DDED37F6-F6BC-4A81-90CA-E3128401A635}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {DDED37F6-F6BC-4A81-90CA-E3128401A635}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {DDED37F6-F6BC-4A81-90CA-E3128401A635}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {2823434A-15E1-4E83-8A76-E351E39A6CDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {2823434A-15E1-4E83-8A76-E351E39A6CDC}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {2823434A-15E1-4E83-8A76-E351E39A6CDC}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {2823434A-15E1-4E83-8A76-E351E39A6CDC}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /Src/ScreenGun.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True 3 | True 4 | True 5 | True 6 | ^(.*?)\.?Tests$ 7 | $1 8 | ScreenGun 9 | - $FILENAME$ 10 | -------------------------------------------------------------------- 11 | Authors: 12 | - Jeff Hansen <jeff@jeffijoe.com> 13 | - Bjarke Søgaard <ekrajb123@gmail.com> 14 | Copyright (C) ScreenGun Authors $CURRENT_YEAR$. All rights reserved. 15 | 8 -------------------------------------------------------------------------------- /Src/ScreenGun/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Src/ScreenGun/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Src/ScreenGun/App.xaml.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - App.xaml.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Windows; 10 | 11 | namespace ScreenGun 12 | { 13 | /// 14 | /// Interaction logic for App.xaml 15 | /// 16 | public partial class App : Application 17 | { 18 | #region Constructors and Destructors 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | public App() 24 | { 25 | this.InitializeComponent(); 26 | } 27 | 28 | #endregion 29 | } 30 | } -------------------------------------------------------------------------------- /Src/ScreenGun/AppBootstrapper.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffijoe/screengun/7bb60297f7c6c6ef3f7eab43377f4c14e9d9232f/Src/ScreenGun/AppBootstrapper.cs -------------------------------------------------------------------------------- /Src/ScreenGun/Base/ViewModel.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffijoe/screengun/7bb60297f7c6c6ef3f7eab43377f4c14e9d9232f/Src/ScreenGun/Base/ViewModel.cs -------------------------------------------------------------------------------- /Src/ScreenGun/Converters/BetterBooleanToVisibilityConverter.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - BetterBooleanToVisibilityConverter.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System; 10 | using System.Globalization; 11 | using System.Windows; 12 | using System.Windows.Data; 13 | 14 | namespace ScreenGun.Converters 15 | { 16 | /// 17 | /// The better boolean to visibility converter. 18 | /// 19 | public class BetterBooleanToVisibilityConverter : DependencyObject, IValueConverter 20 | { 21 | #region Static Fields 22 | 23 | /// 24 | /// The false visibility property. 25 | /// 26 | public static readonly DependencyProperty FalseVisibilityProperty = DependencyProperty.Register( 27 | "FalseVisibility", 28 | typeof(Visibility), 29 | typeof(BetterBooleanToVisibilityConverter), 30 | new PropertyMetadata(Visibility.Hidden)); 31 | 32 | /// 33 | /// The true visibility property. 34 | /// 35 | public static readonly DependencyProperty TrueVisibilityProperty = DependencyProperty.Register( 36 | "TrueVisibility", 37 | typeof(Visibility), 38 | typeof(BetterBooleanToVisibilityConverter), 39 | new PropertyMetadata(Visibility.Visible)); 40 | 41 | #endregion 42 | 43 | #region Public Properties 44 | 45 | /// 46 | /// Gets or sets the false visibility. 47 | /// 48 | public Visibility FalseVisibility 49 | { 50 | get 51 | { 52 | return (Visibility)this.GetValue(FalseVisibilityProperty); 53 | } 54 | 55 | set 56 | { 57 | this.SetValue(FalseVisibilityProperty, value); 58 | } 59 | } 60 | 61 | /// 62 | /// Gets or sets the true visibility. 63 | /// 64 | public Visibility TrueVisibility 65 | { 66 | get 67 | { 68 | return (Visibility)this.GetValue(TrueVisibilityProperty); 69 | } 70 | 71 | set 72 | { 73 | this.SetValue(TrueVisibilityProperty, value); 74 | } 75 | } 76 | 77 | #endregion 78 | 79 | #region Public Methods and Operators 80 | 81 | /// 82 | /// Converts a value. 83 | /// 84 | /// 85 | /// The value produced by the binding source. 86 | /// 87 | /// 88 | /// The type of the binding target property. 89 | /// 90 | /// 91 | /// The converter parameter to use. 92 | /// 93 | /// 94 | /// The culture to use in the converter. 95 | /// 96 | /// 97 | /// A converted value. If the method returns null, the valid null value is used. 98 | /// 99 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 100 | { 101 | if (!(value is bool)) 102 | { 103 | throw new InvalidOperationException("I handle bools, nothing else. Go away."); 104 | } 105 | 106 | var b = (bool)value; 107 | return b ? this.TrueVisibility : this.FalseVisibility; 108 | } 109 | 110 | /// 111 | /// Converts a value. 112 | /// 113 | /// 114 | /// The value that is produced by the binding target. 115 | /// 116 | /// 117 | /// The type to convert to. 118 | /// 119 | /// 120 | /// The converter parameter to use. 121 | /// 122 | /// 123 | /// The culture to use in the converter. 124 | /// 125 | /// 126 | /// A converted value. If the method returns null, the valid null value is used. 127 | /// 128 | /// 129 | /// 130 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 131 | { 132 | throw new NotImplementedException(); 133 | } 134 | 135 | #endregion 136 | } 137 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Converters/BooleanToColorConverter.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - BooleanToColorConverter.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System; 10 | using System.Globalization; 11 | using System.Windows; 12 | using System.Windows.Data; 13 | using System.Windows.Media; 14 | 15 | namespace ScreenGun.Converters 16 | { 17 | /// 18 | /// The boolean to color converter. 19 | /// 20 | public class BooleanToColorConverter : DependencyObject, IValueConverter 21 | { 22 | #region Static Fields 23 | 24 | /// 25 | /// The false color property. 26 | /// 27 | public static readonly DependencyProperty FalseColorProperty = DependencyProperty.Register( 28 | "FalseColor", 29 | typeof(Brush), 30 | typeof(BooleanToColorConverter), 31 | new PropertyMetadata(default(Brush))); 32 | 33 | /// 34 | /// The true color property. 35 | /// 36 | public static readonly DependencyProperty TrueColorProperty = DependencyProperty.Register( 37 | "TrueColor", 38 | typeof(Brush), 39 | typeof(BooleanToColorConverter), 40 | new PropertyMetadata(default(Brush))); 41 | 42 | #endregion 43 | 44 | #region Public Properties 45 | 46 | /// 47 | /// Gets or sets the false color. 48 | /// 49 | public Brush FalseColor 50 | { 51 | get 52 | { 53 | return (Brush)this.GetValue(FalseColorProperty); 54 | } 55 | 56 | set 57 | { 58 | this.SetValue(FalseColorProperty, value); 59 | } 60 | } 61 | 62 | /// 63 | /// Gets or sets the true color. 64 | /// 65 | public Brush TrueColor 66 | { 67 | get 68 | { 69 | return (Brush)this.GetValue(TrueColorProperty); 70 | } 71 | 72 | set 73 | { 74 | this.SetValue(TrueColorProperty, value); 75 | } 76 | } 77 | 78 | #endregion 79 | 80 | #region Public Methods and Operators 81 | 82 | /// 83 | /// Converts a value. 84 | /// 85 | /// 86 | /// The value produced by the binding source. 87 | /// 88 | /// 89 | /// The type of the binding target property. 90 | /// 91 | /// 92 | /// The converter parameter to use. 93 | /// 94 | /// 95 | /// The culture to use in the converter. 96 | /// 97 | /// 98 | /// A converted value. If the method returns null, the valid null value is used. 99 | /// 100 | /// 101 | /// I only work with bools, yo. 102 | /// 103 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 104 | { 105 | if (!(value is bool)) 106 | { 107 | throw new InvalidOperationException("I only work with bools, yo."); 108 | } 109 | 110 | var b = (bool)value; 111 | return b ? this.TrueColor : this.FalseColor; 112 | } 113 | 114 | /// 115 | /// The convert back. 116 | /// 117 | /// 118 | /// The value. 119 | /// 120 | /// 121 | /// The target type. 122 | /// 123 | /// 124 | /// The parameter. 125 | /// 126 | /// 127 | /// The culture. 128 | /// 129 | /// 130 | /// The . 131 | /// 132 | /// 133 | /// 134 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 135 | { 136 | throw new NotImplementedException(); 137 | } 138 | 139 | #endregion 140 | } 141 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Events/RecordingCreated.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - RecordingCreated.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using ScreenGun.Modules.Main.ScreenGunFile; 10 | 11 | namespace ScreenGun.Events 12 | { 13 | /// 14 | /// Recording Created event. 15 | /// 16 | public class RecordingCreated 17 | { 18 | #region Constructors and Destructors 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | /// 24 | /// The file. 25 | /// 26 | public RecordingCreated(ScreenGunFileViewModel file) 27 | { 28 | this.File = file; 29 | } 30 | 31 | #endregion 32 | 33 | #region Public Properties 34 | 35 | /// 36 | /// Gets the file for the recording that was just created. 37 | /// 38 | /// 39 | /// The file path. 40 | /// 41 | public ScreenGunFileViewModel File { get; private set; } 42 | 43 | #endregion 44 | } 45 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Events/RecordingViewClosed.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ScreenGun.Events 8 | { 9 | /// 10 | /// Triggered when the recording view closes. 11 | /// 12 | public class RecordingViewClosed 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Src/ScreenGun/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconClose.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconClose.xaml.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - IconClose.xaml.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Windows; 10 | using System.Windows.Controls; 11 | using System.Windows.Media; 12 | 13 | namespace ScreenGun.Icons 14 | { 15 | /// 16 | /// Interaction logic for ic_close_24px.xaml 17 | /// 18 | public partial class IconClose : UserControl 19 | { 20 | #region Static Fields 21 | 22 | /// 23 | /// The icon background property. 24 | /// 25 | public static readonly DependencyProperty IconBackgroundProperty = DependencyProperty.Register( 26 | "IconBackground", 27 | typeof(Brush), 28 | typeof(IconClose), 29 | new PropertyMetadata(Brushes.White)); 30 | 31 | #endregion 32 | 33 | #region Constructors and Destructors 34 | 35 | /// 36 | /// Initializes a new instance of the class. 37 | /// 38 | public IconClose() 39 | { 40 | this.InitializeComponent(); 41 | } 42 | 43 | #endregion 44 | 45 | #region Public Properties 46 | 47 | /// 48 | /// Gets or sets the icon background. 49 | /// 50 | public Brush IconBackground 51 | { 52 | get 53 | { 54 | return (Brush)this.GetValue(IconBackgroundProperty); 55 | } 56 | 57 | set 58 | { 59 | this.SetValue(IconBackgroundProperty, value); 60 | } 61 | } 62 | 63 | #endregion 64 | } 65 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconCogwheel.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconCogwheel.xaml.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - IconCogwheel.xaml.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Windows; 10 | using System.Windows.Controls; 11 | using System.Windows.Media; 12 | 13 | namespace ScreenGun.Icons 14 | { 15 | /// 16 | /// Interaction logic for IconCogwheel.xaml 17 | /// 18 | public partial class IconCogwheel : UserControl 19 | { 20 | #region Static Fields 21 | 22 | /// 23 | /// The icon background property. 24 | /// 25 | public static readonly DependencyProperty IconBackgroundProperty = DependencyProperty.Register( 26 | "IconBackground", 27 | typeof(Brush), 28 | typeof(IconCogwheel), 29 | new PropertyMetadata(Brushes.White)); 30 | 31 | #endregion 32 | 33 | #region Constructors and Destructors 34 | 35 | /// 36 | /// Initializes a new instance of the class. 37 | /// 38 | public IconCogwheel() 39 | { 40 | this.InitializeComponent(); 41 | } 42 | 43 | #endregion 44 | 45 | #region Public Properties 46 | 47 | /// 48 | /// Gets or sets the icon background. 49 | /// 50 | public Brush IconBackground 51 | { 52 | get 53 | { 54 | return (Brush)this.GetValue(IconBackgroundProperty); 55 | } 56 | 57 | set 58 | { 59 | this.SetValue(IconBackgroundProperty, value); 60 | } 61 | } 62 | 63 | #endregion 64 | } 65 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconDelete.xaml: -------------------------------------------------------------------------------- 1 |  8 | 12 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconDelete.xaml.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - IconDelete.xaml.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Windows; 10 | using System.Windows.Controls; 11 | using System.Windows.Media; 12 | 13 | namespace ScreenGun.Icons 14 | { 15 | /// 16 | /// Interaction logic for icon_delete.xaml 17 | /// 18 | public partial class IconDelete : UserControl 19 | { 20 | #region Static Fields 21 | 22 | /// 23 | /// The icon color property. 24 | /// 25 | public static readonly DependencyProperty IconColorProperty = DependencyProperty.Register( 26 | "IconColor", 27 | typeof(Brush), 28 | typeof(IconDelete), 29 | new PropertyMetadata(default(Brush))); 30 | 31 | #endregion 32 | 33 | #region Constructors and Destructors 34 | 35 | /// 36 | /// Initializes a new instance of the class. 37 | /// 38 | public IconDelete() 39 | { 40 | this.InitializeComponent(); 41 | this.LayoutRoot.DataContext = this; 42 | } 43 | 44 | #endregion 45 | 46 | #region Public Properties 47 | 48 | /// 49 | /// Gets or sets the icon color. 50 | /// 51 | public Brush IconColor 52 | { 53 | get 54 | { 55 | return (Brush)this.GetValue(IconColorProperty); 56 | } 57 | 58 | set 59 | { 60 | this.SetValue(IconColorProperty, value); 61 | } 62 | } 63 | 64 | #endregion 65 | } 66 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconFullscreen.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconFullscreen.xaml.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - IconFullscreen.xaml.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Windows; 10 | using System.Windows.Controls; 11 | using System.Windows.Media; 12 | 13 | namespace ScreenGun.Icons 14 | { 15 | /// 16 | /// Interaction logic for ic_fullscreen_24px.xaml 17 | /// 18 | public partial class IconFullscreen : UserControl 19 | { 20 | #region Static Fields 21 | 22 | /// 23 | /// The icon background property. 24 | /// 25 | public static readonly DependencyProperty IconBackgroundProperty = DependencyProperty.Register( 26 | "IconBackground", 27 | typeof(Brush), 28 | typeof(IconFullscreen), 29 | new PropertyMetadata(Brushes.White)); 30 | 31 | #endregion 32 | 33 | #region Constructors and Destructors 34 | 35 | /// 36 | /// Initializes a new instance of the class. 37 | /// 38 | public IconFullscreen() 39 | { 40 | this.InitializeComponent(); 41 | } 42 | 43 | #endregion 44 | 45 | #region Public Properties 46 | 47 | /// 48 | /// Gets or sets the icon background. 49 | /// 50 | public Brush IconBackground 51 | { 52 | get 53 | { 54 | return (Brush)this.GetValue(IconBackgroundProperty); 55 | } 56 | 57 | set 58 | { 59 | this.SetValue(IconBackgroundProperty, value); 60 | } 61 | } 62 | 63 | #endregion 64 | } 65 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconFullscreenExit.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconFullscreenExit.xaml.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - IconFullscreenExit.xaml.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Windows; 10 | using System.Windows.Controls; 11 | using System.Windows.Media; 12 | 13 | namespace ScreenGun.Icons 14 | { 15 | /// 16 | /// Interaction logic for ic_fullscreen_exit_24px.xaml 17 | /// 18 | public partial class IconFullscreenExit : UserControl 19 | { 20 | #region Static Fields 21 | 22 | /// 23 | /// The icon background property. 24 | /// 25 | public static readonly DependencyProperty IconBackgroundProperty = DependencyProperty.Register( 26 | "IconBackground", 27 | typeof(Brush), 28 | typeof(IconFullscreenExit), 29 | new PropertyMetadata(Brushes.White)); 30 | 31 | #endregion 32 | 33 | #region Constructors and Destructors 34 | 35 | /// 36 | /// Initializes a new instance of the class. 37 | /// 38 | public IconFullscreenExit() 39 | { 40 | this.InitializeComponent(); 41 | } 42 | 43 | #endregion 44 | 45 | #region Public Properties 46 | 47 | /// 48 | /// Gets or sets the icon background. 49 | /// 50 | public Brush IconBackground 51 | { 52 | get 53 | { 54 | return (Brush)this.GetValue(IconBackgroundProperty); 55 | } 56 | 57 | set 58 | { 59 | this.SetValue(IconBackgroundProperty, value); 60 | } 61 | } 62 | 63 | #endregion 64 | } 65 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconMic.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconMic.xaml.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - IconMic.xaml.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Windows; 10 | using System.Windows.Controls; 11 | using System.Windows.Media; 12 | 13 | namespace ScreenGun.Icons 14 | { 15 | /// 16 | /// Interaction logic for ic_mic_24px.xaml 17 | /// 18 | public partial class IconMic : UserControl 19 | { 20 | #region Static Fields 21 | 22 | /// 23 | /// The icon background property. 24 | /// 25 | public static readonly DependencyProperty IconBackgroundProperty = DependencyProperty.Register( 26 | "IconBackground", 27 | typeof(Brush), 28 | typeof(IconMic), 29 | new PropertyMetadata(Brushes.White)); 30 | 31 | #endregion 32 | 33 | #region Constructors and Destructors 34 | 35 | /// 36 | /// Initializes a new instance of the class. 37 | /// 38 | public IconMic() 39 | { 40 | this.InitializeComponent(); 41 | } 42 | 43 | #endregion 44 | 45 | #region Public Properties 46 | 47 | /// 48 | /// Gets or sets the icon background. 49 | /// 50 | public Brush IconBackground 51 | { 52 | get 53 | { 54 | return (Brush)this.GetValue(IconBackgroundProperty); 55 | } 56 | 57 | set 58 | { 59 | this.SetValue(IconBackgroundProperty, value); 60 | } 61 | } 62 | 63 | #endregion 64 | } 65 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconMicOff.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconMicOff.xaml.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - IconMicOff.xaml.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Windows; 10 | using System.Windows.Controls; 11 | using System.Windows.Media; 12 | 13 | namespace ScreenGun.Icons 14 | { 15 | /// 16 | /// Interaction logic for ic_mic_off_24px.xaml 17 | /// 18 | public partial class IconMicOff : UserControl 19 | { 20 | #region Static Fields 21 | 22 | /// 23 | /// The icon background property. 24 | /// 25 | public static readonly DependencyProperty IconBackgroundProperty = DependencyProperty.Register( 26 | "IconBackground", 27 | typeof(Brush), 28 | typeof(IconMicOff), 29 | new PropertyMetadata(Brushes.White)); 30 | 31 | #endregion 32 | 33 | #region Constructors and Destructors 34 | 35 | /// 36 | /// Initializes a new instance of the class. 37 | /// 38 | public IconMicOff() 39 | { 40 | this.InitializeComponent(); 41 | } 42 | 43 | #endregion 44 | 45 | #region Public Properties 46 | 47 | /// 48 | /// Gets or sets the icon background. 49 | /// 50 | public Brush IconBackground 51 | { 52 | get 53 | { 54 | return (Brush)this.GetValue(IconBackgroundProperty); 55 | } 56 | 57 | set 58 | { 59 | this.SetValue(IconBackgroundProperty, value); 60 | } 61 | } 62 | 63 | #endregion 64 | } 65 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconRecord.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconRecord.xaml.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - IconRecord.xaml.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Windows; 10 | using System.Windows.Media; 11 | 12 | namespace ScreenGun.Icons 13 | { 14 | /// 15 | /// Interaction logic for IconRecord.xaml 16 | /// 17 | public partial class IconRecord 18 | { 19 | #region Static Fields 20 | 21 | /// 22 | /// The inner color property. 23 | /// 24 | public static readonly DependencyProperty InnerColorProperty = DependencyProperty.Register( 25 | "InnerColor", 26 | typeof(Brush), 27 | typeof(IconRecord), 28 | new PropertyMetadata(Brushes.Red)); 29 | 30 | /// 31 | /// The outer color property. 32 | /// 33 | public static readonly DependencyProperty OuterColorProperty = DependencyProperty.Register( 34 | "OuterColor", 35 | typeof(Brush), 36 | typeof(IconRecord), 37 | new PropertyMetadata(Brushes.DarkSlateGray)); 38 | 39 | /// 40 | /// The size property. 41 | /// 42 | public static readonly DependencyProperty SizeProperty = DependencyProperty.Register( 43 | "Size", 44 | typeof(double), 45 | typeof(IconRecord), 46 | new PropertyMetadata(16d)); 47 | 48 | #endregion 49 | 50 | #region Constructors and Destructors 51 | 52 | /// 53 | /// Initializes a new instance of the class. 54 | /// 55 | public IconRecord() 56 | { 57 | this.InitializeComponent(); 58 | } 59 | 60 | #endregion 61 | 62 | #region Public Properties 63 | 64 | /// 65 | /// Gets or sets the inner color. 66 | /// 67 | public Brush InnerColor 68 | { 69 | get 70 | { 71 | return (Brush)this.GetValue(InnerColorProperty); 72 | } 73 | 74 | set 75 | { 76 | this.SetValue(InnerColorProperty, value); 77 | } 78 | } 79 | 80 | /// 81 | /// Gets or sets the outer color. 82 | /// 83 | public Brush OuterColor 84 | { 85 | get 86 | { 87 | return (Brush)this.GetValue(OuterColorProperty); 88 | } 89 | 90 | set 91 | { 92 | this.SetValue(OuterColorProperty, value); 93 | } 94 | } 95 | 96 | /// 97 | /// Gets or sets the size. 98 | /// 99 | public double Size 100 | { 101 | get 102 | { 103 | return (double)this.GetValue(SizeProperty); 104 | } 105 | 106 | set 107 | { 108 | this.SetValue(SizeProperty, value); 109 | } 110 | } 111 | 112 | /// 113 | /// Gets the size fourth. 114 | /// 115 | public double SizeEighth 116 | { 117 | get 118 | { 119 | return this.Size / 8; 120 | } 121 | } 122 | 123 | /// 124 | /// Gets the size half. 125 | /// 126 | public double SizeHalf 127 | { 128 | get 129 | { 130 | return this.Size / 2; 131 | } 132 | } 133 | 134 | #endregion 135 | } 136 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconSave.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Src/ScreenGun/Icons/IconSave.xaml.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - IconSave.xaml.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Windows; 10 | using System.Windows.Controls; 11 | using System.Windows.Media; 12 | 13 | namespace ScreenGun.Icons 14 | { 15 | /// 16 | /// Interaction logic for IconSave.xaml 17 | /// 18 | public partial class IconSave : UserControl 19 | { 20 | #region Static Fields 21 | 22 | /// 23 | /// The icon background property. 24 | /// 25 | public static readonly DependencyProperty IconBackgroundProperty = DependencyProperty.Register( 26 | "IconBackground", 27 | typeof(Brush), 28 | typeof(IconSave), 29 | new PropertyMetadata(Brushes.White)); 30 | 31 | #endregion 32 | 33 | #region Constructors and Destructors 34 | 35 | /// 36 | /// Initializes a new instance of the class. 37 | /// 38 | public IconSave() 39 | { 40 | this.InitializeComponent(); 41 | } 42 | 43 | #endregion 44 | 45 | #region Public Properties 46 | 47 | /// 48 | /// Gets or sets the icon background. 49 | /// 50 | public Brush IconBackground 51 | { 52 | get 53 | { 54 | return (Brush)this.GetValue(IconBackgroundProperty); 55 | } 56 | 57 | set 58 | { 59 | this.SetValue(IconBackgroundProperty, value); 60 | } 61 | } 62 | 63 | #endregion 64 | } 65 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Misc/Command.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - Command.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System; 10 | using System.Windows.Input; 11 | 12 | namespace ScreenGun.Misc 13 | { 14 | /// 15 | /// The command. 16 | /// 17 | public class Command : ICommand 18 | { 19 | #region Fields 20 | 21 | /// 22 | /// The action. 23 | /// 24 | private readonly Action action; 25 | 26 | #endregion 27 | 28 | #region Constructors and Destructors 29 | 30 | /// 31 | /// Initializes a new instance of the class. 32 | /// 33 | /// 34 | /// The action. 35 | /// 36 | public Command(Action action) 37 | { 38 | this.action = action; 39 | } 40 | 41 | #endregion 42 | 43 | #region Public Events 44 | 45 | /// 46 | /// The can execute changed. 47 | /// 48 | public event EventHandler CanExecuteChanged; 49 | 50 | #endregion 51 | 52 | #region Public Methods and Operators 53 | 54 | /// 55 | /// The can execute. 56 | /// 57 | /// 58 | /// The parameter. 59 | /// 60 | /// 61 | /// The . 62 | /// 63 | public bool CanExecute(object parameter) 64 | { 65 | return true; 66 | } 67 | 68 | /// 69 | /// The execute. 70 | /// 71 | /// 72 | /// The parameter. 73 | /// 74 | public void Execute(object parameter) 75 | { 76 | this.action.Invoke(); 77 | } 78 | 79 | #endregion 80 | } 81 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Misc/NativeWindowHelper.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - NativeWindowHelper.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System; 10 | using System.Diagnostics.CodeAnalysis; 11 | using System.Runtime.InteropServices; 12 | 13 | namespace ScreenGun.Misc 14 | { 15 | /// 16 | /// The native window helper. 17 | /// 18 | public static class NativeWindowHelper 19 | { 20 | #region Constants 21 | 22 | /// 23 | /// The gw l_ exstyle. 24 | /// 25 | [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:FieldNamesMustNotContainUnderscore", 26 | Justification = "Reviewed. Suppression is OK here.")] 27 | private const int GWL_EXSTYLE = -20; 28 | 29 | /// 30 | /// The w s_ e x_ transparent. 31 | /// 32 | [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:FieldNamesMustNotContainUnderscore", 33 | Justification = "Reviewed. Suppression is OK here.")] 34 | private const int WS_EX_TRANSPARENT = 0x00000020; 35 | 36 | #endregion 37 | 38 | #region Public Methods and Operators 39 | 40 | /// 41 | /// The set window ex transparent. 42 | /// 43 | /// 44 | /// The hwnd. 45 | /// 46 | public static void SetWindowExTransparent(IntPtr hwnd) 47 | { 48 | var extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE); 49 | SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_TRANSPARENT); 50 | } 51 | 52 | #endregion 53 | 54 | #region Methods 55 | 56 | /// 57 | /// The get window long. 58 | /// 59 | /// 60 | /// The hwnd. 61 | /// 62 | /// 63 | /// The index. 64 | /// 65 | /// 66 | /// The . 67 | /// 68 | [DllImport("user32.dll")] 69 | private static extern int GetWindowLong(IntPtr hwnd, int index); 70 | 71 | /// 72 | /// The set window long. 73 | /// 74 | /// 75 | /// The hwnd. 76 | /// 77 | /// 78 | /// The index. 79 | /// 80 | /// 81 | /// The new style. 82 | /// 83 | /// 84 | /// The . 85 | /// 86 | [DllImport("user32.dll")] 87 | private static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle); 88 | 89 | #endregion 90 | } 91 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/About/AboutView.xaml: -------------------------------------------------------------------------------- 1 |  22 | 23 | 24 | 31 | 37 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | Copyright © Jeff Hansen 2016 58 | jeffijoe.com 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/About/AboutView.xaml.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - SettingsView.xaml.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.IO; 10 | using System.Linq; 11 | using System.Windows; 12 | using System.Windows.Forms; 13 | using System.Windows.Input; 14 | 15 | using MahApps.Metro.Controls; 16 | 17 | using KeyEventArgs = System.Windows.Input.KeyEventArgs; 18 | 19 | namespace ScreenGun.Modules.Settings 20 | { 21 | /// 22 | /// Interaction logic for AboutView.xaml 23 | /// 24 | public partial class AboutView : MetroWindow 25 | { 26 | #region Static Fields 27 | 28 | /// 29 | /// The invalid path chars 30 | /// 31 | private static readonly char[] InvalidPathChars = Path.GetInvalidPathChars(); 32 | 33 | #endregion 34 | 35 | #region Constructors and Destructors 36 | 37 | /// 38 | /// Initializes a new instance of the class. 39 | /// 40 | public AboutView() 41 | { 42 | this.InitializeComponent(); 43 | } 44 | 45 | #endregion 46 | 47 | #region Public Properties 48 | 49 | /// 50 | /// Gets the view model. 51 | /// 52 | /// 53 | /// The view model. 54 | /// 55 | public AboutViewModel ViewModel 56 | { 57 | get 58 | { 59 | return this.DataContext as AboutViewModel; 60 | } 61 | } 62 | 63 | #endregion 64 | } 65 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/About/AboutViewModel.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - SettingsViewModel.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System; 10 | using System.IO; 11 | 12 | using ScreenGun.Base; 13 | using System.Reflection; 14 | using System.Diagnostics; 15 | 16 | namespace ScreenGun.Modules.Settings 17 | { 18 | /// 19 | /// The about view model. 20 | /// 21 | public class AboutViewModel : ViewModel 22 | { 23 | /// 24 | /// App version. 25 | /// 26 | public string Version 27 | { 28 | get 29 | { 30 | System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); 31 | FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location); 32 | string version = fvi.FileVersion; 33 | return version; 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/Main/ScreenGunFile/RecordingDeletedHandler.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenGun.Modules.Main.ScreenGunFile 2 | { 3 | /// 4 | /// Recording deleted delegate. 5 | /// 6 | /// The file. 7 | public delegate void RecordingDeletedHandler(ScreenGunFileViewModel file); 8 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/Main/ScreenGunFile/ScreenGunFileView.xaml: -------------------------------------------------------------------------------- 1 |  13 | 14 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 43 | 50 | 51 | 52 | 53 | 57 | 58 | 59 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/Main/ScreenGunFile/ScreenGunFileView.xaml.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - ScreenGunFileView.xaml.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.Windows; 10 | using System.Windows.Controls; 11 | using System.Windows.Input; 12 | 13 | namespace ScreenGun.Modules.Main.ScreenGunFile 14 | { 15 | /// 16 | /// Interaction logic for ScreenGunFileView.xaml 17 | /// 18 | public partial class ScreenGunFileView : UserControl 19 | { 20 | #region Constructors and Destructors 21 | 22 | /// 23 | /// Initializes a new instance of the class. 24 | /// 25 | public ScreenGunFileView() 26 | { 27 | this.InitializeComponent(); 28 | } 29 | 30 | #endregion 31 | 32 | #region Public Properties 33 | 34 | /// 35 | /// Gets the view model. 36 | /// 37 | public ScreenGunFileViewModel ViewModel 38 | { 39 | get 40 | { 41 | return (ScreenGunFileViewModel)this.DataContext; 42 | } 43 | } 44 | 45 | #endregion 46 | 47 | #region Methods 48 | 49 | /// 50 | /// The ui element_ on preview mouse left button down. 51 | /// 52 | /// 53 | /// The sender. 54 | /// 55 | /// 56 | /// The e. 57 | /// 58 | private void UIElement_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 59 | { 60 | DragDrop.DoDragDrop( 61 | this, 62 | new DataObject(DataFormats.FileDrop, new[] { this.ViewModel.FilePath }), 63 | DragDropEffects.Copy); 64 | } 65 | 66 | #endregion 67 | } 68 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/Main/ScreenGunFile/ScreenGunFileViewModel.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffijoe/screengun/7bb60297f7c6c6ef3f7eab43377f4c14e9d9232f/Src/ScreenGun/Modules/Main/ScreenGunFile/ScreenGunFileViewModel.cs -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/Main/ShellView.xaml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 39 | 45 | 50 | 51 | 52 | 53 | 54 | 55 | 58 | 59 | 60 | 61 | 62 | 68 | Press the New Recording button to get started! 69 | 70 | 71 | 72 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/Main/ShellView.xaml.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - ShellView.xaml.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using MahApps.Metro.Controls; 10 | 11 | namespace ScreenGun.Modules.Main 12 | { 13 | /// 14 | /// Shell view. 15 | /// 16 | public partial class ShellView : MetroWindow 17 | { 18 | #region Constructors and Destructors 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | public ShellView() 24 | { 25 | this.InitializeComponent(); 26 | this.Loaded += (sender, e) => 27 | { 28 | this.ViewModel.ToggleWindow = (show) => 29 | { 30 | this.WindowState = show ? System.Windows.WindowState.Normal : System.Windows.WindowState.Minimized; 31 | }; 32 | }; 33 | } 34 | 35 | #endregion 36 | 37 | #region Public Properties 38 | 39 | /// 40 | /// Gets the view model. 41 | /// 42 | public ShellViewModel ViewModel 43 | { 44 | get 45 | { 46 | return this.DataContext as ShellViewModel; 47 | } 48 | } 49 | 50 | #endregion 51 | } 52 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/Main/ShellViewModel.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffijoe/screengun/7bb60297f7c6c6ef3f7eab43377f4c14e9d9232f/Src/ScreenGun/Modules/Main/ShellViewModel.cs -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/NotifyIcon/NotifyIconViewModel.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - NotifyIconViewModel.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System; 10 | using System.Drawing; 11 | using System.Windows.Forms; 12 | 13 | using ScreenGun.Base; 14 | 15 | namespace ScreenGun.Modules.NotifyIcon 16 | { 17 | /// 18 | /// The notify icon view model. 19 | /// 20 | public class NotifyIconViewModel : ViewModel, IDisposable 21 | { 22 | #region Fields 23 | 24 | /// 25 | /// The actual icon 26 | /// 27 | private System.Windows.Forms.NotifyIcon actualIcon; 28 | 29 | #endregion 30 | 31 | #region Constructors and Destructors 32 | 33 | /// 34 | /// Initializes a new instance of the class. 35 | /// 36 | /// 37 | /// The icon. 38 | /// 39 | public NotifyIconViewModel(Icon icon) 40 | : this() 41 | { 42 | this.Icon = icon; 43 | this.actualIcon.Visible = true; 44 | } 45 | 46 | /// 47 | /// Prevents a default instance of the class from being created. 48 | /// Sets up default values 49 | /// 50 | private NotifyIconViewModel() 51 | { 52 | this.actualIcon = new System.Windows.Forms.NotifyIcon(); 53 | this.actualIcon.MouseClick += (sender, args) => { 54 | switch (args.Button) 55 | { 56 | case MouseButtons.Left: 57 | this.OnLeftClicked(); 58 | break; 59 | case MouseButtons.Right: 60 | this.OnRightClicked(); 61 | break; 62 | } 63 | }; 64 | this.AddPropertyChangedEvent( 65 | "Icon", 66 | args => { 67 | if (this.actualIcon == null) 68 | { 69 | return; 70 | } 71 | 72 | this.actualIcon.Icon = this.Icon; 73 | }); 74 | } 75 | 76 | #endregion 77 | 78 | #region Public Events 79 | 80 | /// 81 | /// Occurs when [left clicked]. 82 | /// 83 | public event EventHandler LeftClicked; 84 | 85 | /// 86 | /// Occurs when [right clicked]. 87 | /// 88 | public event EventHandler RightClicked; 89 | 90 | #endregion 91 | 92 | #region Public Properties 93 | 94 | /// 95 | /// Gets or sets the icon. 96 | /// 97 | /// 98 | /// The icon. 99 | /// 100 | public Icon Icon { get; set; } 101 | 102 | #endregion 103 | 104 | #region Public Methods and Operators 105 | 106 | /// 107 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 108 | /// 109 | public void Dispose() 110 | { 111 | if (this.actualIcon != null) 112 | { 113 | this.actualIcon.Dispose(); 114 | this.actualIcon = null; 115 | } 116 | 117 | this.LeftClicked = null; 118 | this.RightClicked = null; 119 | } 120 | 121 | /// 122 | /// Hides the balloon tip. 123 | /// 124 | public void HideBalloonTip() 125 | { 126 | this.actualIcon.Visible = false; 127 | this.actualIcon.Visible = true; 128 | } 129 | 130 | /// 131 | /// Shows the balloon tip. 132 | /// 133 | /// 134 | /// The duration ms. 135 | /// 136 | /// 137 | /// The title. 138 | /// 139 | /// 140 | /// The text. 141 | /// 142 | /// 143 | /// The tool tip icon. 144 | /// 145 | /// 146 | /// The click event to invoke when the tooltip is clicked. 147 | /// 148 | public void ShowBalloonTip( 149 | int durationMs, 150 | string title, 151 | string text, 152 | ToolTipIcon toolTipIcon, 153 | EventHandler clicked = null) 154 | { 155 | EventHandler onClicked = null; 156 | EventHandler onClosed = null; 157 | 158 | Action disposeTooltip = () => { 159 | this.actualIcon.BalloonTipClosed -= onClosed; 160 | this.actualIcon.BalloonTipClicked -= onClicked; 161 | }; 162 | 163 | onClosed = (sender, args) => disposeTooltip(); 164 | onClicked = (sender, args) => { 165 | if (clicked != null) 166 | { 167 | clicked(sender, args); 168 | } 169 | 170 | disposeTooltip(); 171 | }; 172 | 173 | this.actualIcon.BalloonTipClicked += onClicked; 174 | this.actualIcon.BalloonTipClosed += onClosed; 175 | this.actualIcon.ShowBalloonTip(durationMs, title, text, toolTipIcon); 176 | } 177 | 178 | #endregion 179 | 180 | #region Methods 181 | 182 | /// 183 | /// Called when [left clicked]. 184 | /// 185 | protected virtual void OnLeftClicked() 186 | { 187 | var handler = this.LeftClicked; 188 | if (handler != null) 189 | { 190 | handler(this, EventArgs.Empty); 191 | } 192 | } 193 | 194 | /// 195 | /// Called when [right clicked]. 196 | /// 197 | protected virtual void OnRightClicked() 198 | { 199 | var handler = this.RightClicked; 200 | if (handler != null) 201 | { 202 | handler(this, EventArgs.Empty); 203 | } 204 | } 205 | 206 | #endregion 207 | } 208 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/Recorder/RecorderView.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - RecorderView.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.ComponentModel; 10 | using System.Windows; 11 | using System.Windows.Input; 12 | using System.Windows.Interop; 13 | 14 | using ScreenGun.Misc; 15 | using ScreenGun.Modules.RegionSelector; 16 | 17 | namespace ScreenGun.Modules.Recorder 18 | { 19 | /// 20 | /// The screenshot view. 21 | /// 22 | public class RecorderView : RegionSelectorWindow 23 | { 24 | #region Constructors and Destructors 25 | 26 | /// 27 | /// Initializes a new instance of the class. 28 | /// 29 | public RecorderView() 30 | { 31 | this.RegionChange += this.OnRegionChange; 32 | this.FullScreenChanged += this.OnFullScreenChange; 33 | this.DataContextChanged += this.OnDataContextChanged; 34 | this.Title = "New Recording"; 35 | var command = new Command(() => this.ViewModel.Close()); 36 | this.InputBindings.Add(new KeyBinding(command, Key.Escape, ModifierKeys.None)); 37 | } 38 | 39 | #endregion 40 | 41 | #region Public Properties 42 | 43 | /// 44 | /// Gets the view model. 45 | /// 46 | /// 47 | /// The view model. 48 | /// 49 | public RecorderViewModel ViewModel 50 | { 51 | get 52 | { 53 | return (RecorderViewModel)this.DataContext; 54 | } 55 | } 56 | 57 | #endregion 58 | 59 | #region Methods 60 | 61 | /// 62 | /// Called when [data context changed]. 63 | /// 64 | /// 65 | /// The sender. 66 | /// 67 | /// 68 | /// The instance 69 | /// containing the event data. 70 | /// 71 | private void OnDataContextChanged( 72 | object sender, 73 | DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) 74 | { 75 | this.ViewModel.PropertyChanged += this.ViewModelOnPropertyChanged; 76 | this.ViewModel.RecordingRegion = this.RecordingArea; 77 | } 78 | 79 | /// 80 | /// Called when full screen changes. 81 | /// 82 | /// 83 | /// The arguments. 84 | /// 85 | private void OnFullScreenChange(FullScreenChangedArgs args) 86 | { 87 | // ReSharper disable once RedundantCheckBeforeAssignment 88 | if (this.ViewModel.IsFullScreen != args.IsFullScreen) 89 | { 90 | this.ViewModel.IsFullScreen = args.IsFullScreen; 91 | } 92 | } 93 | 94 | /// 95 | /// Called when the region changes. 96 | /// 97 | /// 98 | /// The arguments. 99 | /// 100 | private void OnRegionChange(RegionChangeArgs args) 101 | { 102 | this.ViewModel.RecordingRegion = args.Region; 103 | } 104 | 105 | /// 106 | /// The view model on property changed. 107 | /// 108 | /// 109 | /// The sender. 110 | /// 111 | /// 112 | /// The property changed event args. 113 | /// 114 | private void ViewModelOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) 115 | { 116 | if (propertyChangedEventArgs.PropertyName == "IsRecording") 117 | { 118 | this.Locked = this.ViewModel.IsRecording; 119 | if (this.ViewModel.IsRecording) 120 | { 121 | var hwnd = new WindowInteropHelper(this).Handle; 122 | NativeWindowHelper.SetWindowExTransparent(hwnd); 123 | } 124 | } 125 | 126 | if (propertyChangedEventArgs.PropertyName == "IsFullScreen") 127 | { 128 | this.IsFullScreen = this.ViewModel.IsFullScreen; 129 | } 130 | } 131 | 132 | #endregion 133 | } 134 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/Recorder/RecorderViewModel.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - RecorderViewModel.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System; 10 | using System.Drawing; 11 | using System.IO; 12 | using System.Threading.Tasks; 13 | using System.Windows.Forms; 14 | 15 | using Caliburn.Micro; 16 | 17 | using PropertyChanged; 18 | 19 | using ScreenGun.Events; 20 | using ScreenGun.Modules.Main.ScreenGunFile; 21 | using ScreenGun.Modules.NotifyIcon; 22 | using ScreenGun.Modules.Settings; 23 | using ScreenGun.Recorder; 24 | 25 | using Application = System.Windows.Application; 26 | using Screen = Caliburn.Micro.Screen; 27 | 28 | namespace ScreenGun.Modules.Recorder 29 | { 30 | /// 31 | /// View Model for the Recorder. 32 | /// 33 | [ImplementPropertyChanged] 34 | public class RecorderViewModel : Screen 35 | { 36 | #region Fields 37 | 38 | /// 39 | /// The event aggregator. 40 | /// 41 | private readonly IEventAggregator eventAggregator; 42 | 43 | /// 44 | /// The recorder. 45 | /// 46 | private readonly IScreenRecorder recorder; 47 | 48 | /// 49 | /// The settings. 50 | /// 51 | private readonly IScreenGunSettings settings; 52 | 53 | /// 54 | /// The file view model. 55 | /// 56 | private ScreenGunFileViewModel fileViewModel; 57 | 58 | /// 59 | /// The notify icon. 60 | /// 61 | private NotifyIconViewModel notifyIcon; 62 | 63 | #endregion 64 | 65 | #region Constructors and Destructors 66 | 67 | /// 68 | /// Initializes a new instance of the class. 69 | /// 70 | /// 71 | /// The recorder. 72 | /// 73 | /// 74 | /// The settings. 75 | /// 76 | /// 77 | /// The event aggregator. 78 | /// 79 | public RecorderViewModel( 80 | IScreenRecorder recorder, 81 | IScreenGunSettings settings, 82 | IEventAggregator eventAggregator) 83 | { 84 | this.recorder = recorder; 85 | this.settings = settings; 86 | this.eventAggregator = eventAggregator; 87 | this.UseMicrophone = this.settings.DefaultMicEnabled; 88 | this.SetupNotifyIcon(); 89 | } 90 | 91 | #endregion 92 | 93 | #region Public Properties 94 | 95 | /// 96 | /// Gets or sets a value indicating whether this instance is full screen. 97 | /// 98 | /// 99 | /// true if this instance is full screen; otherwise, false. 100 | /// 101 | public bool IsFullScreen { get; set; } 102 | 103 | /// 104 | /// Gets or sets a value indicating whether we are recording. 105 | /// 106 | public bool IsRecording { get; set; } 107 | 108 | /// 109 | /// Gets or sets the recording region. 110 | /// 111 | /// 112 | /// The recording region. 113 | /// 114 | public Rectangle RecordingRegion { get; set; } 115 | 116 | /// 117 | /// Gets or sets a value indicating whether to use microphone or not. 118 | /// 119 | /// 120 | /// true if [use microphone]; otherwise, false. 121 | /// 122 | public bool UseMicrophone { get; set; } 123 | 124 | #endregion 125 | 126 | #region Public Methods and Operators 127 | 128 | /// 129 | /// Cancels this instance. 130 | /// 131 | public void Cancel() 132 | { 133 | this.TryClose(); 134 | this.eventAggregator.PublishOnUIThread(new RecordingViewClosed()); 135 | } 136 | 137 | /// 138 | /// Closes the recorder - can only be done when not recording. 139 | /// 140 | public void Close() 141 | { 142 | if (this.IsRecording == false) 143 | { 144 | this.Cancel(); 145 | } 146 | } 147 | 148 | /// 149 | /// Starts the recording. 150 | /// 151 | public void StartRecording() 152 | { 153 | this.notifyIcon.HideBalloonTip(); 154 | this.IsRecording = true; 155 | 156 | var fileName = string.Format("Recording {0}.mp4", DateTime.Now.ToString("yy-MM-dd HH-mm-ss")); 157 | var outputFilePath = Path.Combine(this.settings.StoragePath, fileName); 158 | this.fileViewModel = new ScreenGunFileViewModel(outputFilePath, RecordingStage.DoingNothing); 159 | 160 | var opts = new ScreenRecorderOptions(this.RecordingRegion) 161 | { 162 | DeleteMaterialWhenDone = true, 163 | OutputFilePath = outputFilePath, 164 | RecordMicrophone = this.UseMicrophone, 165 | AudioRecordingDeviceNumber = this.settings.RecordingDeviceNumber 166 | }; 167 | 168 | var progress = new Progress(state => this.fileViewModel.RecordingStage = state.Stage); 169 | this.recorder.Start(opts, progress); 170 | } 171 | 172 | /// 173 | /// Stops the recording. 174 | /// 175 | public async void StopRecording() 176 | { 177 | if (this.IsRecording) 178 | { 179 | this.TryClose(); 180 | this.eventAggregator.PublishOnUIThread(new RecordingCreated(this.fileViewModel)); 181 | var stopTask = this.recorder.StopAsync(); 182 | this.eventAggregator.BeginPublishOnUIThread(new RecordingViewClosed()); 183 | await stopTask; 184 | this.IsRecording = false; 185 | this.notifyIcon.Dispose(); 186 | } 187 | } 188 | 189 | /// 190 | /// Toggles the full screen. 191 | /// 192 | public void ToggleFullscreen() 193 | { 194 | this.IsFullScreen = !this.IsFullScreen; 195 | } 196 | 197 | /// 198 | /// Toggles the microphone. 199 | /// 200 | public void ToggleMicrophone() 201 | { 202 | this.UseMicrophone = !this.UseMicrophone; 203 | } 204 | 205 | #endregion 206 | 207 | #region Methods 208 | 209 | /// 210 | /// Called when deactivating. 211 | /// 212 | /// 213 | /// Inidicates whether this instance will be closed. 214 | /// 215 | protected override void OnDeactivate(bool close) 216 | { 217 | this.notifyIcon.Dispose(); 218 | base.OnDeactivate(close); 219 | } 220 | 221 | /// 222 | /// Setups the notify icon. 223 | /// 224 | private void SetupNotifyIcon() 225 | { 226 | var icon = 227 | new Icon( 228 | Application.GetResourceStream( 229 | new Uri("Resources/record_icon.ico", UriKind.Relative)).Stream); 230 | this.notifyIcon = new NotifyIconViewModel(icon); 231 | this.notifyIcon.ShowBalloonTip( 232 | 7000, 233 | "ScreenGun", 234 | "When recording, click this icon to stop.", 235 | ToolTipIcon.Info); 236 | this.notifyIcon.LeftClicked += (sender, args) => this.StopRecording(); 237 | } 238 | 239 | #endregion 240 | } 241 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/RegionSelector/FullScreenChanged.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffijoe/screengun/7bb60297f7c6c6ef3f7eab43377f4c14e9d9232f/Src/ScreenGun/Modules/RegionSelector/FullScreenChanged.cs -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/RegionSelector/FullScreenChangedArgs.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffijoe/screengun/7bb60297f7c6c6ef3f7eab43377f4c14e9d9232f/Src/ScreenGun/Modules/RegionSelector/FullScreenChangedArgs.cs -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/RegionSelector/RegionChange.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffijoe/screengun/7bb60297f7c6c6ef3f7eab43377f4c14e9d9232f/Src/ScreenGun/Modules/RegionSelector/RegionChange.cs -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/RegionSelector/RegionChangeArgs.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeffijoe/screengun/7bb60297f7c6c6ef3f7eab43377f4c14e9d9232f/Src/ScreenGun/Modules/RegionSelector/RegionChangeArgs.cs -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/RegionSelector/RegionSelectorWindow.xaml: -------------------------------------------------------------------------------- 1 |  17 | 18 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 48 | 49 | 54 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 80 | 90 | 91 | 92 | 93 | 94 | 95 | 100 | 101 | 106 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 132 | 142 | 143 | 144 | 145 | 146 | 157 | 158 | 167 | 168 | 169 | 178 | 191 | 205 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 235 | 245 | 246 | 247 | 248 | 249 | 250 | 255 | 256 | 261 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 287 | 297 | 298 | 299 | 300 | 301 | 302 | 307 | 308 | 313 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/Settings/IScreenGunSettings.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - IScreenGunSettings.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System; 10 | 11 | namespace ScreenGun.Modules.Settings 12 | { 13 | /// 14 | /// The ScreenGunSettings interface. 15 | /// 16 | public interface IScreenGunSettings 17 | { 18 | #region Public Events 19 | 20 | /// 21 | /// Occurs when the dialog is reset. 22 | /// 23 | event EventHandler DialogReset; 24 | 25 | #endregion 26 | 27 | #region Public Properties 28 | 29 | /// 30 | /// Gets or sets a value indicating whether the mic is enabled by default. 31 | /// 32 | /// 33 | /// true if the mic is enabled by default; otherwise, false. 34 | /// 35 | bool DefaultMicEnabled { get; set; } 36 | 37 | /// 38 | /// Gets or sets the storage path. 39 | /// 40 | /// 41 | /// The storage path. 42 | /// 43 | string StoragePath { get; set; } 44 | 45 | /// 46 | /// The recording device to use. 47 | /// 48 | int RecordingDeviceNumber { get; set; } 49 | 50 | #endregion 51 | 52 | #region Public Methods and Operators 53 | 54 | /// 55 | /// Saves the settings. 56 | /// 57 | void SaveSettings(); 58 | 59 | #endregion 60 | } 61 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/Settings/RecordingDevice.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ScreenGun.Modules.Settings 8 | { 9 | /// 10 | /// The recording device. 11 | /// 12 | public class RecordingDevice 13 | { 14 | /// 15 | /// The display name. 16 | /// 17 | public string DisplayName { get; private set; } 18 | 19 | /// 20 | /// The device number. 21 | /// 22 | public int DeviceNumber { get; private set; } 23 | 24 | /// 25 | /// Constructor. 26 | /// 27 | /// 28 | /// 29 | public RecordingDevice(int deviceNumber, string displayName) 30 | { 31 | this.DisplayName = displayName; 32 | this.DeviceNumber = deviceNumber; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/Settings/SettingsFile.cs: -------------------------------------------------------------------------------- 1 | // ScreenGun 2 | // - SettingsFile.cs 3 | // -------------------------------------------------------------------- 4 | // Authors: 5 | // - Jeff Hansen 6 | // - Bjarke Søgaard 7 | // Copyright (C) ScreenGun Authors 2015. All rights reserved. 8 | 9 | using System.IO; 10 | 11 | using Newtonsoft.Json; 12 | 13 | namespace ScreenGun.Modules.Settings 14 | { 15 | /// 16 | /// The settings file. 17 | /// 18 | public class SettingsFile 19 | { 20 | #region Public Properties 21 | 22 | /// 23 | /// Gets or sets a value indicating whether default mic enabled. 24 | /// 25 | public bool DefaultMicEnabled { get; set; } 26 | 27 | /// 28 | /// Gets or sets the storage path. 29 | /// 30 | public string StoragePath { get; set; } 31 | 32 | /// 33 | /// Recording device number. 34 | /// 35 | public int RecordingDeviceNumber { get; set; } 36 | 37 | #endregion 38 | 39 | #region Public Methods and Operators 40 | 41 | /// 42 | /// Froms the file. 43 | /// 44 | /// 45 | /// The file path. 46 | /// 47 | /// 48 | /// The settings file. 49 | /// 50 | public static SettingsFile FromFile(string filePath) 51 | { 52 | var readAllText = File.ReadAllText(filePath); 53 | var settingsFile = JsonConvert.DeserializeObject(readAllText); 54 | return settingsFile; 55 | } 56 | 57 | /// 58 | /// Creates a settings file from the given settings. 59 | /// 60 | /// 61 | /// The settings view model. 62 | /// 63 | /// 64 | /// The settings file. 65 | /// 66 | public static SettingsFile FromSettings(IScreenGunSettings settings) 67 | { 68 | return new SettingsFile 69 | { 70 | DefaultMicEnabled = settings.DefaultMicEnabled, 71 | StoragePath = settings.StoragePath, 72 | RecordingDeviceNumber = settings.RecordingDeviceNumber 73 | }; 74 | } 75 | 76 | /// 77 | /// Saves the settings. 78 | /// 79 | /// 80 | /// The file path. 81 | /// 82 | /// 83 | /// The settings. 84 | /// 85 | public static void SaveSettings(string filePath, IScreenGunSettings settings) 86 | { 87 | var settingsFile = FromSettings(settings); 88 | var serializeObject = JsonConvert.SerializeObject(settingsFile); 89 | File.WriteAllText(filePath, serializeObject); 90 | } 91 | 92 | #endregion 93 | } 94 | } -------------------------------------------------------------------------------- /Src/ScreenGun/Modules/Settings/SettingsView.xaml: -------------------------------------------------------------------------------- 1 |  22 | 23 | 24 | 31 | 37 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |