License text

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER 
 * Copyright  2008, 2010 Oracle and/or its affiliates.  All rights reserved. 
 * Use is subject to license terms.
 * 
 * This file is available and licensed under the following license:
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met: 
 * 
 *   * Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer. 
 *
 *   * Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *
 *   * Neither the name of Oracle Corporation nor the names of its contributors 
 *     may be used to endorse or promote products derived from this software 
 *     without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

    

package screenshotzoom;

import javafx.scene.*;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Circle;
import javafx.geometry.Rectangle2D;
import javafx.stage.*;
import javafx.scene.paint.Color;
import javafx.scene.image.*; 
import javafx.scene.input.*; 
import javafx.animation.*;
import screenshotzoom.*;

public class Main {

	var bgRect: Rectangle;
	var magRect : Rectangle;
	var bgCircle : Circle;
	var lense : Circle ;
    var zoom : Number = 1.0;
    var stage: Stage;
    var magnifierGroup : Group;
    var magnifierImage : Image;
    var magnifierImageView : ImageView;
    var lenseImgView : ImageView;
    var smooth : Boolean;

    var boundsOfCircle : Rectangle;
    var magnifierBound :  javafx.geometry.Rectangle2D ;
	
    var stageDragInitialX:Number;
    var stageDragInitialY:Number;

    	var SCREEN_SHOT_FILE = "{FX.getProperty("javafx.java.io.tmpdir")}screenshot.png";
    	var screenShotTimeline : Timeline;
    
	var stageX : Number on replace {
    	    screenShotTimeline.stop();
    	    screenShotTimeline.playFromStart();
    	}
	var stageY : Number on replace {
    	    screenShotTimeline.stop();
    	    screenShotTimeline.playFromStart();
    	}
    
	init {	
		
    	    SCREEN_SHOT_FILE = "file:///{SCREEN_SHOT_FILE.<<replace>>('\\', '/')}";
    	    
    	    screenShotTimeline = Timeline {
    	        keyFrames: [ 
    	            KeyFrame {
    	                time: 50ms
    	                action: function() {
    	                    updateImage();
    	                }
    	            }
    	        ]
    	    };
        
        
            bgCircle = Circle{
            	focusTraversable: true
            	centerX: 75
                centerY: 75
            	radius: 70
            }
            
            boundsOfCircle = Rectangle{
            	x : bind lenseImgView.boundsInParent.minX
            	y : bind lenseImgView.boundsInParent.minY
            	width :bind lenseImgView.boundsInParent.width
            	height : bind lenseImgView.boundsInParent.height
            	strokeWidth : 10
            	fill : Color.TRANSPARENT
            	stroke : Color.RED
            }
            
        
        lenseImgView = ImageView { 
        	image : Image {
        		width : 150
        		height : 150
        		preserveRatio : true
        		url : "{__DIR__}loupe.png";
        	}
        }
        
	  magnifierImageView = ImageView {
		x: 2
		y: 2
		focusTraversable : true
		fitWidth: bind boundsOfCircle.boundsInParent.width
		fitHeight: bind boundsOfCircle.boundsInParent.height
		preserveRatio : true	
		clip : bgCircle
		image: Image {
			url : "{SCREEN_SHOT_FILE}"
			backgroundLoading: false
		}
		 
		viewport: bind Rectangle2D {
			minX: 2 - 2/zoom
			minY: 2 - 2/zoom
			width: boundsOfCircle.width/zoom
			height: boundsOfCircle.height/zoom
		} 
		
		onMouseWheelMoved : function(e:MouseEvent):Void {
			if(e.wheelRotation > 0) {
				if(zoom <= 3.0) {
					zoom = zoom + 0.1;
				}
			}
			if(e.wheelRotation < 0) {
			    if(zoom > 1) {
				 zoom = zoom - 0.1;
			    }
			}
    	        }
		onMouseClicked : function ( e){
		/*

    	        */
		}
		onKeyPressed: function(e) {
		    if(e.code == KeyCode.VK_UP) {
    	            	if(zoom <= 3.0) {
    	                	zoom = zoom + 0.1;
    	                }
    	            } else if(e.code == KeyCode.VK_DOWN) {
    	                if(zoom > 1) {
    	                    zoom = zoom - 0.1;
    	                }
    	            }	         
		 }
	 }
        
        magnifierGroup = Group {     
            focusTraversable : true
            content: [ magnifierImageView, lenseImgView ]
            onMousePressed: function(e) {
                stageDragInitialX = e.screenX - stage.x;
                stageDragInitialY = e.screenY - stage.y;
            }
             onMouseDragged: function(e) {
                stage.x = e.screenX - stageDragInitialX;
                stage.y = e.screenY - stageDragInitialY;
             }
        }
        
	stage = Stage {
	    title : "Screen Magnifier"
            style: StageStyle.TRANSPARENT
	    resizable : false
            x: bind stageX with inverse
            y: bind stageY with inverse
	    width : bind lenseImgView.image.width
	    height : bind lenseImgView.image.height
	    scene : Scene {
                content: magnifierGroup
                fill: Color.TRANSPARENT
            }
        }
    } // end init

    function updateImage() {
        stage.visible = false;
        ScreenCapture.captureScreen((stageX + 2), (stageY+2),
        				boundsOfCircle.boundsInParent.width , 
        				boundsOfCircle.boundsInParent.height);
    	magnifierImageView.image = Image {    		
	    	url : "{SCREEN_SHOT_FILE}"
	};
        stage.visible = true;
    }
}

function run() {
    var magnifier = Main{};
    magnifier.updateImage();
    magnifier.magnifierImageView.requestFocus();
}