/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems 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 mosaic;
import java.lang.Exception;
import java.lang.Object;
import javafx.io.http.HttpRequest;
import javafx.io.http.URLConverter;
import javafx.lang.FX;
import javafx.scene.control.Button;
import javafx.scene.control.TextBox;
import javafx.scene.Group;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.Scene;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import mosaic.ImageButton;
import mosaic.Photo;
import mosaic.PhotoPullParser;
import mosaic.ThumbImage;
var stageDragInitialX:Number;
var stageDragInitialY:Number;
var tag = "garden";
def apiKey = "c383a2f8d22a3e3788568cb1c64386fc";
def license = "&license=Attribution-NonCommercial-ShareAlike";
def count = "30";
public var width : Number = bind scene.width;
public var height : Number = bind scene.height;
var urlConverter = URLConverter{};
var request: HttpRequest;
function loadImageMetadata() : Void {
for(node in thumbGroup.content) {
(node as ThumbImage).cancel();
}
println("Searching for tag - \"{tag}\"");
var httpRequestError: Boolean = false;
request = HttpRequest {
location: "http:
"&sort=date-posted-desc&tags={tag}&per_page={count}{license}";
method: HttpRequest.GET
onException: function(exception: Exception) {
exception.printStackTrace();
println("Error - {exception}");
httpRequestError = true;
}
onResponseCode: function(responseCode:Integer) {
if (responseCode != 200) {
println("failed, response: {responseCode} {request.responseMessage}");
}
}
onInput: function(input: java.io.InputStream) {
try {
var parser = PhotoPullParser {
onDone: updateImages
};
parser.parse(input);
if(parser.errorMessage.length() > 0) {
println("Error - {parser.errorMessage}");
httpRequestError = true;
}
} finally {
input.close();
}
}
onDone: function() {
tagTextBox.disable = false;
searchButton.disable = false;
}
}
request.start();
}
function search() : Void {
tagTextBox.commit();
tag = urlConverter.encodeURL(tagTextBox.text);
loadImageMetadata();
tagTextBox.disable = true;
searchButton.disable = true;
}
var thumbGroup = Group { };
function updateImages(photos : Photo[]) {
delete thumbGroup.content;
if(photos == null) {
return;
}
for(photo in photos) {
insert ThumbImage {
url: "http:;
} into thumbGroup.content;
}
}
var bottomRect : Rectangle = Rectangle {
y: bind (height - bottomRect.height)
height: bind (tagTextBox.boundsInLocal.height + 15)
width: bind width
fill: LinearGradient {
startX: 0.0, startY: 0.0, endX: 0.0, endY: 1.0
proportional: true
stops: [
Stop { offset: 0.0 color: Color.GRAY },
Stop { offset: 0.5 color: Color.BLACK }
]
}
}
var tagTextBox : TextBox = TextBox {
promptText: "Search Tags"
action: function() {
search();
}
}
var searchButton : Button = Button {
text: "Search"
strong: true
action: function() {
search();
}
}
var searchBox : HBox = HBox {
spacing: 10
translateX: bind (width - searchBox.boundsInLocal.width - 50)
translateY: bind (bottomRect.y + (bottomRect.height - searchBox.height)/2.0)
content: [ tagTextBox, searchButton ]
}
var topRect : Rectangle = Rectangle {
height: bind bottomRect.height
width: bind width
fill: LinearGradient {
startX: 0.0, startY: 0.0, endX: 0.0, endY: 1.0
proportional: true
stops: [
Stop { offset: 0.5 color: Color.BLACK },
Stop { offset: 1.0 color: Color.GRAY }
]
}
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;
}
}
var minButton = ImageButton {
name: "min"
onMouseClicked: function(e) {
stage.fullScreen = false;
stage.iconified = true;
}
}
var closeButton = ImageButton {
name: "close"
onMouseClicked: function(e) {
FX.exit();
}
}
var controlBox : HBox = HBox {
translateX: bind (width - controlBox.boundsInLocal.width - 15)
translateY: bind ((topRect.boundsInLocal.height - 24)/2.0)
content: [ minButton, closeButton ]
visible: bind ("{__PROFILE__}" != "browser")
}
var scene : Scene = Scene {
fill: Color.BLACK
content: [
thumbGroup, bottomRect, topRect, controlBox, searchBox
]
};
var stage : Stage = Stage {
title: "Mosaic"
resizable: false
style: StageStyle.UNDECORATED
width: 800
height: 600
scene: scene
}
function run() {
loadImageMetadata();
}