windowcapture
исходный код / UI/EditorForm.Keyboard.cs

EditorForm.Keyboard.cs

274 строк · 9,116 байт · модуль UI
  1using System;
  2using System.Collections.Generic;
  3using System.Drawing;
  4using System.Drawing.Drawing2D;
  5using System.Drawing.Imaging;
  6using System.Drawing.Text;
  7using System.IO;
  8using System.Linq;
  9using System.Runtime.InteropServices;
 10using System.Windows.Forms;
 11using WindowCapture.App;
 12using WindowCapture.Detection;
 13using WindowCapture.Effects;
 14using WindowCapture.Helpers;
 15using WindowCapture.Integration;
 16using WindowCapture.Models;
 17using WindowCapture.Native;
 18
 19namespace WindowCapture.UI
 20{
 21    public partial class EditorForm
 22    {
 23        // ===== Keyboard input =====
 24
 25        private void EditorForm_KeyDown(object sender, KeyEventArgs e)
 26        {
 27            // Video playback shortcuts
 28            if (isVideoFile && (videoBrowser != null || dsMedia != null))
 29            {
 30                if (e.KeyCode == Keys.Space && !e.Control)
 31                {
 32                    VideoJS("vToggle");
 33                    e.SuppressKeyPress = true;
 34                    e.Handled = true;
 35                    return;
 36                }
 37                if (e.KeyCode == Keys.Left && !e.Control)
 38                {
 39                    // Seek back 5 seconds
 40                    double t = Math.Max(0, videoCurrentTime - 5);
 41                    VideoJS("vSeek", t.ToString(System.Globalization.CultureInfo.InvariantCulture));
 42                    e.Handled = true;
 43                    return;
 44                }
 45                if (e.KeyCode == Keys.Right && !e.Control)
 46                {
 47                    // Seek forward 5 seconds
 48                    double t = Math.Min(videoDuration, videoCurrentTime + 5);
 49                    VideoJS("vSeek", t.ToString(System.Globalization.CultureInfo.InvariantCulture));
 50                    e.Handled = true;
 51                    return;
 52                }
 53                if (e.KeyCode == Keys.M)
 54                {
 55                    VideoJS("vMute");
 56                    e.Handled = true;
 57                    return;
 58                }
 59            }
 60
 61            // Ctrl+Space when Word panel is open - insert
 62            if (e.KeyCode == Keys.Space && e.Control && wordSidePanel != null && wordSidePanel.IsExpanded)
 63            {
 64                e.SuppressKeyPress = true;
 65                e.Handled = true;
 66                wordSidePanel.DoInsert();
 67                return;
 68            }
 69
 70            // Ctrl+Space when Word panel is NOT open - quick AI insert
 71            if (e.KeyCode == Keys.Space && e.Control && (wordSidePanel == null || !wordSidePanel.IsExpanded))
 72            {
 73                e.SuppressKeyPress = true;
 74                e.Handled = true;
 75                QuickAIInsert();
 76                return;
 77            }
 78
 79            // Ignore hotkeys when text input is active (let TextBox handle them)
 80            if (canvas != null && canvas.IsTextInputActive)
 81            {
 82                return;
 83            }
 84
 85            // Space - short press: copy and close, long press (250ms): export to Word
 86            if (e.KeyCode == Keys.Space && !spaceHeld)
 87            {
 88                spaceHeld = true;
 89                spaceDownTime = DateTime.Now;
 90
 91                // Start timer to check for long press
 92                if (spaceHoldTimer == null)
 93                {
 94                    spaceHoldTimer = new System.Windows.Forms.Timer();
 95                    spaceHoldTimer.Interval = SpaceHoldThreshold;
 96                    spaceHoldTimer.Tick += SpaceHoldTimer_Tick;
 97                }
 98                spaceHoldTimer.Start();
 99                e.Handled = true;
100                return;
101            }
102
103            // Ctrl+Z - undo
104            if (e.Control && e.KeyCode == Keys.Z)
105            {
106                Undo();
107                e.Handled = true;
108                return;
109            }
110
111            // Escape - close
112            if (e.KeyCode == Keys.Escape)
113            {
114                Close();
115                e.Handled = true;
116                return;
117            }
118
119            // Ctrl+S - save
120            if (e.Control && e.KeyCode == Keys.S)
121            {
122                SaveImage();
123                e.Handled = true;
124                return;
125            }
126
127            // Ctrl+O - open file (viewer mode)
128            if (e.Control && e.KeyCode == Keys.O)
129            {
130                OpenFileDialog();
131                e.Handled = true;
132                return;
133            }
134
135            // Ctrl+T - grab text from image (OCR) -> clipboard
136            if (e.Control && e.KeyCode == Keys.T)
137            {
138                GrabText();
139                e.Handled = true;
140                return;
141            }
142
143            // Viewer mode shortcuts
144            if (viewerMode)
145            {
146                // Left/Right arrow: browse images
147                if (e.KeyCode == Keys.Left && !e.Control)
148                {
149                    BrowseFile(-1);
150                    e.Handled = true;
151                    return;
152                }
153                if (e.KeyCode == Keys.Right && !e.Control)
154                {
155                    BrowseFile(1);
156                    e.Handled = true;
157                    return;
158                }
159                if (e.KeyCode == Keys.R)
160                {
161                    FitToWindow();
162                    e.Handled = true;
163                    return;
164                }
165                if (e.KeyCode == Keys.F)
166                {
167                    SetZoom(1.0f);
168                    e.Handled = true;
169                    return;
170                }
171                // F11 or double-click: toggle maximize
172                if (e.KeyCode == Keys.F11)
173                {
174                    WindowState = WindowState == FormWindowState.Maximized
175                        ? FormWindowState.Normal : FormWindowState.Maximized;
176                    e.Handled = true;
177                    return;
178                }
179            }
180
181            // Plus/Minus for zoom
182            if (e.KeyCode == Keys.Oemplus || e.KeyCode == Keys.Add)
183            {
184                ApplyZoom(1f);
185                e.Handled = true;
186                return;
187            }
188            if (e.KeyCode == Keys.OemMinus || e.KeyCode == Keys.Subtract)
189            {
190                ApplyZoom(-1f);
191                e.Handled = true;
192                return;
193            }
194
195            // Alt - enable auto-detect mode (only after Alt was released once)
196            if (e.Alt && !altPressed && altWasReleasedOnce)
197            {
198                altPressed = true;
199                canvas.Cursor = Cursors.Cross;
200                var mousePos = canvas.PointToClient(Cursor.Position);
201                var imgPt = new Point((int)(mousePos.X / zoomLevel), (int)(mousePos.Y / zoomLevel));
202                UpdateAutoDetect(imgPt);
203                canvas.Invalidate();
204            }
205        }
206
207        private void EditorForm_KeyUp(object sender, KeyEventArgs e)
208        {
209            // Handle space key release for Word panel - must be processed even when wordDialogOpen
210            if (e.KeyCode == Keys.Space)
211            {
212                // Notify side panel that space was released (for focus handling)
213                if (wordSidePanel != null && wordSidePanel.IsExpanded)
214                {
215                    wordSidePanel.OnSpaceReleased();
216                }
217
218                // If space was held (short press detection)
219                if (spaceHeld)
220                {
221                    spaceHeld = false;
222                    if (spaceHoldTimer != null)
223                    {
224                        spaceHoldTimer.Stop();
225                    }
226
227                    // Check if it was a short press (timer didn't fire yet)
228                    var elapsed = (DateTime.Now - spaceDownTime).TotalMilliseconds;
229                    if (elapsed < SpaceHoldThreshold && !wordDialogOpen)
230                    {
231                        CopyToClipboard();
232                        Close();
233                        return;
234                    }
235                }
236                return;
237            }
238
239            // Ignore other KeyUp events if Word dialog is open
240            if (wordDialogOpen) return;
241
242            if (e.KeyCode == Keys.LMenu || e.KeyCode == Keys.RMenu || e.KeyCode == Keys.Menu)
243            {
244                if (!altWasReleasedOnce)
245                {
246                    altWasReleasedOnce = true;
247                    return;
248                }
249
250                if (altPressed && autoDetectedRect.Width > 5 && autoDetectedRect.Height > 5)
251                {
252                    var hl = new HighlightRect(autoDetectedRect);
253                    canvas.Highlights.Add(hl);
254                    canvas.UndoStack.Add(new UndoAction("highlight", hl));
255                }
256                altPressed = false;
257                autoDetectedRect = Rectangle.Empty;
258                canvas.Cursor = Cursors.Default;
259                canvas.Invalidate();
260            }
261        }
262
263        private void SpaceHoldTimer_Tick(object sender, EventArgs e)
264        {
265            spaceHoldTimer.Stop();
266
267            if (!spaceHeld) return;
268            spaceHeld = false;
269
270            // Long press detected - open Word export dialog
271            ExportToWord();
272        }
273    }
274}