diff mupdf-source/thirdparty/tesseract/java/com/google/scrollview/events/SVEventHandler.java @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mupdf-source/thirdparty/tesseract/java/com/google/scrollview/events/SVEventHandler.java	Mon Sep 15 11:43:07 2025 +0200
@@ -0,0 +1,301 @@
+// Copyright 2007 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); You may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+// applicable law or agreed to in writing, software distributed under the
+// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+// OF ANY KIND, either express or implied. See the License for the specific
+// language governing permissions and limitations under the License.
+
+package com.google.scrollview.events;
+
+import com.google.scrollview.ScrollView;
+import com.google.scrollview.events.SVEvent;
+import com.google.scrollview.events.SVEventType;
+import com.google.scrollview.ui.SVWindow;
+
+import org.piccolo2d.PCamera;
+import org.piccolo2d.PNode;
+import org.piccolo2d.event.PBasicInputEventHandler;
+import org.piccolo2d.event.PInputEvent;
+import org.piccolo2d.nodes.PPath;
+
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.awt.Window;
+
+import javax.swing.Timer;
+
+/**
+ * The ScrollViewEventHandler takes care of any events which might happen on the
+ * canvas and converts them to an according SVEvent, which is (using the
+ * processEvent method) then added to a message queue. All events from the
+ * message queue get sent gradually.
+ *
+ * @author wanke@google.com
+ */
+public class SVEventHandler extends PBasicInputEventHandler implements
+    ActionListener, KeyListener, WindowListener {
+
+  /** Necessary to wait for a defined period of time (for SVET_HOVER). */
+  public Timer timer;
+
+  /** The window which the event corresponds to. */
+  private SVWindow svWindow;
+
+  /** These are used to determine a selection size (for SVET_SELECTION). */
+  private int lastX = 0;
+  private int lastY = 0;
+
+  /**
+   * These are used in case we want to transmit our position, but do not get it
+   * because it was no MouseEvent, in particular SVET_HOVER and SVET_INPUT.
+   */
+  private int lastXMove = 0;
+  private int lastYMove = 0;
+
+  /** For Drawing a rubber-band rectangle for selection. */
+  private int startX = 0;
+  private int startY = 0;
+  private float rubberBandTransparency = 0.5f;
+  private PNode selection = null;
+
+  /** The string entered since the last enter. Since the client
+   *  end eats all newlines, we can't use the newline
+   *  character, so use ! for now, as it cannot be entered
+   *  directly anyway and therefore can never show up for real. */
+  private String keyStr = "!";
+
+  /** Setup the timer. */
+  public SVEventHandler(SVWindow wdw) {
+    timer = new Timer(1000, this);
+    svWindow = wdw;
+  }
+
+  /**
+   * Store the newest x,y values, add the message to the queue and restart the
+   * timer.
+   */
+  private void processEvent(SVEvent e) {
+    lastXMove = e.x;
+    lastYMove = e.y;
+    ScrollView.addMessage(e);
+    timer.restart();
+  }
+
+  /** Show the associated popup menu at (x,y) (relative position of the window). */
+  private void showPopup(PInputEvent e) {
+    double x = e.getCanvasPosition().getX();
+    double y = e.getCanvasPosition().getY();
+
+    if (svWindow.svPuMenu != null) {
+      svWindow.svPuMenu.show(svWindow, (int) x, (int) y);
+    }
+  }
+
+
+  /** The mouse is clicked - create an SVET_CLICK event. */
+  @Override
+  public void mouseClicked(PInputEvent e) {
+    if (e.isPopupTrigger()) {
+      showPopup(e);
+    } else {
+      processEvent(new SVEvent(SVEventType.SVET_CLICK, svWindow, (int) e
+          .getPosition().getX(), (int) e.getPosition().getY(), 0, 0, null));
+    }
+  }
+
+  /**
+   * The mouse key is pressed (and keeps getting pressed).
+   * Depending on the OS, show a popup menu (if the button pressed is associated
+   * with popup menus, like the RMB under windows&linux) or otherwise save the
+   * position (in case it is a selection).
+   */
+  @Override
+  public void mousePressed(PInputEvent e) {
+    if (e.isPopupTrigger()) {
+      showPopup(e);
+    } else {
+      lastX = (int) e.getPosition().getX();
+      lastY = (int) e.getPosition().getY();
+      timer.restart();
+    }
+  }
+
+  /** The mouse is getting dragged - create an SVET_MOUSE event. */
+  @Override
+  public void mouseDragged(PInputEvent e) {
+    processEvent(new SVEvent(SVEventType.SVET_MOUSE, svWindow, (int) e
+        .getPosition().getX(), (int) e.getPosition().getY(), (int) e
+        .getPosition().getX()
+        - lastX, (int) e.getPosition().getY() - lastY, null));
+
+    // Paint a selection rectangle.
+    if (selection == null) {
+      startX = (int) e.getPosition().getX();
+      startY = (int) e.getPosition().getY();
+      selection = PPath.createRectangle(startX, startY, 1, 1);
+      selection.setTransparency(rubberBandTransparency);
+      svWindow.canvas.getLayer().addChild(selection);
+    } else {
+      int right = Math.max(startX, (int) e.getPosition().getX());
+      int left = Math.min(startX, (int) e.getPosition().getX());
+      int bottom = Math.max(startY, (int) e.getPosition().getY());
+      int top = Math.min(startY, (int) e.getPosition().getY());
+      svWindow.canvas.getLayer().removeChild(selection);
+      selection = PPath.createRectangle(left, top, right - left, bottom - top);
+      selection.setPaint(Color.YELLOW);
+      selection.setTransparency(rubberBandTransparency);
+      svWindow.canvas.getLayer().addChild(selection);
+    }
+  }
+
+  /**
+   * The mouse was released.
+   * Depending on the OS, show a popup menu (if the button pressed is associated
+   * with popup menus, like the RMB under windows&linux) or otherwise create an
+   * SVET_SELECTION event.
+   */
+  @Override
+  public void mouseReleased(PInputEvent e) {
+    if (e.isPopupTrigger()) {
+      showPopup(e);
+    } else {
+      processEvent(new SVEvent(SVEventType.SVET_SELECTION, svWindow, (int) e
+          .getPosition().getX(), (int) e.getPosition().getY(), (int) e
+          .getPosition().getX()
+          - lastX, (int) e.getPosition().getY() - lastY, null));
+    }
+    if (selection != null) {
+      svWindow.canvas.getLayer().removeChild(selection);
+      selection = null;
+    }
+  }
+
+  /**
+   * The mouse wheel is used to zoom in and out of the viewport and center on
+   * the (x,y) position the mouse is currently on.
+   */
+  @Override
+  public void mouseWheelRotated(PInputEvent e) {
+    PCamera lc = svWindow.canvas.getCamera();
+    double sf = SVWindow.SCALING_FACTOR;
+
+    if (e.getWheelRotation() < 0) {
+      sf = 1 / sf;
+    }
+    lc.scaleViewAboutPoint(lc.getScale() / sf, e.getPosition().getX(), e
+        .getPosition().getY());
+  }
+
+  /**
+   * The mouse was moved - create an SVET_MOTION event. NOTE: This obviously
+   * creates a lot of traffic and, depending on the type of application, could
+   * quite possibly be disabled.
+   */
+  @Override
+  public void mouseMoved(PInputEvent e) {
+    processEvent(new SVEvent(SVEventType.SVET_MOTION, svWindow, (int) e
+        .getPosition().getX(), (int) e.getPosition().getY(), 0, 0, null));
+  }
+
+  /**
+   * The mouse entered the window.
+   * Start the timer, which will then emit SVET_HOVER events every X ms. */
+  @Override
+  public void mouseEntered(PInputEvent e) {
+    timer.restart();
+  }
+
+  /**
+   * The mouse exited the window
+   * Stop the timer, so no more SVET_HOVER events will emit. */
+  @Override
+  public void mouseExited(PInputEvent e) {
+    timer.stop();
+  }
+
+  /**
+   * The only associated object with this is the timer, so we use it to send a
+   * SVET_HOVER event.
+   */
+  public void actionPerformed(ActionEvent e) {
+    processEvent(new SVEvent(SVEventType.SVET_HOVER, svWindow, lastXMove,
+        lastYMove, 0, 0, null));
+  }
+
+  /**
+   * A key was pressed - create an SVET_INPUT event.
+   *
+   * NOTE: Might be useful to specify hotkeys.
+   *
+   * Implementation note: The keyListener provided by Piccolo seems to be
+   * broken, so we use the AWT listener directly.
+   * There are never any keyTyped events received either so we are
+   * stuck with physical keys, which is very ugly.
+   */
+  public void keyPressed(KeyEvent e) {
+    char keyCh = e.getKeyChar();
+    if (keyCh == '\r' || keyCh == '\n' || keyCh == '\0' || keyCh == '?') {
+      processEvent(new SVEvent(SVEventType.SVET_INPUT, svWindow, lastXMove,
+                               lastYMove, 0, 0, keyStr));
+      // Send newline characters as '!' as '!' can never be a keypressed
+      // and the client eats all newline characters.
+      keyStr = "!";
+    } else {
+      processEvent(new SVEvent(SVEventType.SVET_INPUT, svWindow, lastXMove,
+                               lastYMove, 0, 0, String.valueOf(keyCh)));
+      keyStr += keyCh;
+    }
+  }
+
+  /**
+   * A window is closed (by the 'x') - create an SVET_DESTROY event. If it was
+   * the last open Window, also send an SVET_EXIT event (but do not exit unless
+   * the client says so).
+   */
+  public void windowClosing(WindowEvent e) {
+    processEvent(new SVEvent(SVEventType.SVET_DESTROY, svWindow, lastXMove,
+        lastYMove, 0, 0, null));
+    Window w = e.getWindow();
+    if (w != null) {
+      w.dispose();
+    }
+    SVWindow.nrWindows--;
+    if (SVWindow.nrWindows == 0) {
+      processEvent(new SVEvent(SVEventType.SVET_EXIT, svWindow, lastXMove,
+          lastYMove, 0, 0, null));
+    }
+  }
+
+  /** These are all events we do not care about and throw away. */
+  public void keyReleased(KeyEvent e) {
+  }
+
+  public void keyTyped(KeyEvent e) {
+  }
+
+  public void windowActivated(WindowEvent e) {
+  }
+
+  public void windowClosed(WindowEvent e) {
+  }
+
+  public void windowDeactivated(WindowEvent e) {
+  }
+
+  public void windowDeiconified(WindowEvent e) {
+  }
+
+  public void windowIconified(WindowEvent e) {
+  }
+
+  public void windowOpened(WindowEvent e) {
+  }
+}