Issues of translating js dock to gwt implementation?

15 views
Skip to first unread message

Alex Luya

unread,
Nov 29, 2011, 9:39:14 PM11/29/11
to GWT
I tried to translate this js
dock:http://safalra.com/web-design/javascript/mac-style-dock/ to gwt
implementation.Blow is the complete translation(almost translated line
by line),a little bit long,but logic is quite simple:MouseMove and
MouseOut were registered to each item in the bar.When mouse
move/out,icons size got updated based on a scale factor calculated
from/according to "distance" to current cursor position.The primary
scaling logic is handled by first lines of
functions:processMouseMove/Out(..),actually by timer.The questions
is :Timers:closeTimeout and closeInterval are set in MouseOut,and
are"delet" in MouseMove.But since MouseMove event will be fired just
after MouseOut event immediately,the operations set in MouseOut Timer
will not get executed.But js demo do work,so there are some errors in my
translation.And after 3 hours debugging,I can find them out.So, please
help me to point them out?Thanks. (if you want to run blow code,these
images must be put to war directory:)
http://safalra.com/web-design/javascript/mac-style-dock/mac-icon-160-full.png http://safalra.com/web-design/javascript/mac-style-dock/mac-icon-160.png http://safalra.com/web-design/javascript/mac-style-dock/mac-icon-80.png http://safalra.com/web-design/javascript/mac-style-dock/mac-icon-80-reflection.png

http://safalra.com/web-design/javascript/mac-style-dock/mac-icon-160-reflection.png


-------------------------------------
public class DockViewImpl extends Composite implements ClickHandler,
MouseMoveHandler,
MouseOutHandler
{
private Timer closeInterval = null;
// initialise the time-outs and intervals to 0
private Timer closeTimeout = null;

// create an array to store the DOM nodes of the icons
private final Image[] icons;;
// create an array to store the sizes of the icons
private final double[] iconSizes;
private final FlowPanel iconsNode = new FlowPanel();

private final ImageDetail[] imageDetails;
// create an array to store the DOM nodes of the icons
// private ImageElement[] images;
private final int maxSize;

// initialise the maximum width to 0
private int maxWidth;
private final int minSize;

private final FlowPanel node;

Timer openInterval = null;

private final int range;
// create an array to store the DOM nodes of reflections of the icons
private final Image[] reflectedIcons;

private FlowPanel reflectedIconsNode = new FlowPanel();
// initialise the scale factor to 0
private double scale = 0;

public DockViewImpl()
{
initWidget(node = new FlowPanel());
minSize = 80;
maxSize = 160;
range = 2;
int len = 8;
icons = new Image[len];
iconSizes = new double[len];
reflectedIcons = new Image[len];
imageDetails = new ImageDetail[len];
for (int i = 0; i < len; i++)
{
ImageDetail img = new ImageDetail();
img.setExtension(".png");
img.setName("mac-icon-");
img.setSizes(new int[] { 80, 160 });
imageDetails[i] = img;
}
loopOverImages();
node.add(iconsNode);
node.add(reflectedIconsNode);
}

private void loopOverImages()
{
for (int i = 0, len = imageDetails.length; i < len; i++)
{
// create and store a node for the icon for this image
Image icon = new Image();
icons[i] = icon;

// position the icon for this image relatively
icon.getElement().getStyle().setPosition(Position.RELATIVE);

// store the initial size of the icon for this image
iconSizes[i] = minSize;

// create and store a node for the reflected icon for this image
Image reflectedIcon = new Image();

reflectedIcons[i] = reflectedIcon;

// update the properties of the icon for this image
updateIconProperties(i);

// add the span for this image to the dock
iconsNode.add(icon);

// add the span for this image to the dock
reflectedIconsNode.add(reflectedIcon);

icon.addClickHandler(this);
icon.addMouseMoveHandler(this);
icon.addMouseOutHandler(this);
// loop over the sizes available for this image
// for (int j = 0; j < imageDetails[i].getSizes().length;
// j++){
//
// // create a DOM node containing this image at this size
// ImageElement image = document.createElement("img");
// image.setAttribute(
// "src",
// imageDetails[i).getName()
// + imageDetails[i).sizes[j]
// + imageDetails[i).getExtension());
// // add the DOM node to the array of stored images
// images.push(image);
// }
}
}

@Override
public void onClick(ClickEvent event)
{
Window.alert("You clicked the icon");
}

@Override
public void onMouseMove(MouseMoveEvent event)
{
processMouseMove(event);
}

@Override
public void onMouseOut(MouseOutEvent event)
{
processMouseOut();
}

/*
* Processes a mousemove event on an image in the 'dock'. The parameter
is:
* e - the event object. Window.event will be used if this is
undefined.
*/
private void processMouseMove(MouseMoveEvent e)
{
// clear the closing interval and time-out
if (closeTimeout != null)
{
closeTimeout.cancel();
closeTimeout = null;
}
if (closeInterval != null)
{
closeInterval.cancel();
closeInterval = null;
}

// check that the opening interval is required but does not yet exist
// System.out.println("scale:"+scale
+"---openInterval:"+(openInterval==null?"null":"nonull"));
if (scale != 1 && openInterval == null)
{
// create the opening interval
openInterval = new Timer()
{
public void run()
{
if (scale < 1)
{
scale += 0.125;
}
if (scale >= 1)
{
scale = 1;
openInterval.cancel();
openInterval = null;
}
for (int i = 0, size = icons.length; i < size; i++)
{
updateIconProperties(i);
}
}
};
openInterval.scheduleRepeating(20);

// set the event object if the browser does not supply it
// if (!e)
// e = Window.event;

// find the DOM node on which the mouseover event occured
// var target = e.get;

// obtain the index of the icon on which the mouseover event occured
int idx = 0;
while (icons[idx] != e.getSource())
idx++;

// obtain the fraction across the icon that the mouseover event
// occurred
double across = e.getX() / iconSizes[idx];

// check a distance across the icon was found (in some cases it will
// not be)
if (across != 0)
{
// initialise the current width to 0
int currentWidth = 0;

// loop over the icons
for (int i = 0, len = icons.length; i < len; i++)
{
// check whether the icon is in the range to be resized
if (i < idx - range || i > idx + range)
{
// set the icon size to the minimum size
iconSizes[i] = minSize;
} else if (i == idx)
{
// set the icon size to be the maximum size
iconSizes[i] = maxSize;
} else
{
// set the icon size to the appropriate value
iconSizes[i] = minSize
+ Math.round((maxSize - minSize - 1)
* (Math.cos((i - idx - across + (i < idx ? 1 : 0)) / range
* Math.PI) + 1) / 2);

// add the icon size to the current width
currentWidth += iconSizes[i];
}

}

// update the maximum width if necessary
if (currentWidth > maxWidth)
maxWidth = currentWidth;

// detect if the total size should be corrected
if (idx >= range && idx < iconSizes.length - range && currentWidth <
maxWidth)
{
// correct the size of the smallest magnified icons
iconSizes[idx - range] = iconSizes[idx - range] +
Math.floor((maxWidth - currentWidth) / 2);
iconSizes[idx + range] = iconSizes[idx + range] +
Math.ceil((maxWidth - currentWidth) / 2);
}

// update the sizes of the images
for (int i = 0, len = icons.length; i < len; i++)
updateIconProperties(i);
}
}
}

// Processes a mouseout event on an image in the dock.
private void processMouseOut()
{
// check that neither the closing interval nor time-out are set
if (closeTimeout == null && closeInterval == null)
{
// create the closing time-out
closeTimeout = new Timer()
{
public void run()
{
closeTimeout = null;
if (openInterval != null)
{
openInterval.cancel();
openInterval = null;
}
closeInterval = new Timer()
{
public void run()
{
if (scale > 0)
{
scale -= 0.125;
}
if (scale <= 0)
{
scale = 0;
closeInterval.cancel();
closeInterval = null;
}
for (int i = 0, len = icons.length; i < len; i++)
{
updateIconProperties(i);
}
}
};
closeInterval.scheduleRepeating(20);
}
};
closeTimeout.schedule(100);
}
}

/*
* Sets a toolbar image to the specified size. The parameter is: index
- the
* 0-based index of the image to be sized
*/
private void updateIconProperties(int index)
{
// determine the size for the icon, taking into account the scale
factor
double size = minSize + scale * (iconSizes[index] - minSize);

// find the index of the appropriate image size
int sizeIdx = 0;
ImageDetail image = imageDetails[index];
int[] sizes = image.getSizes();
while (sizes[sizeIdx] < size && sizeIdx + 1 < sizes.length)
{
sizeIdx++;
}

// check whether the full icon with its caption should be displayed
String name = image.getName();
String extension = image.getExtension();
// HP change to iconStyle
Element iconElem = icons[index].getElement();
// set the src attribute of the image for the icon
iconElem.setAttribute("src", name + ((size == maxSize) ? maxSize +
"-full" : sizes[sizeIdx]) + extension);

// set the width and height of the image for the icon and its
reflection
Style style = iconElem.getStyle();
setStyle(style, size);
style.setMarginTop(maxSize - size, Unit.PX);
// HP change to reflectIconStyle
Element reflectIconElem = reflectedIcons[index].getElement();
// set the src attribute of the image for the icon's reflection
reflectIconElem.setAttribute("src", name + sizes[sizeIdx] +
"-reflection" + extension);
setStyle(style = reflectIconElem.getStyle(), size);
style.setMarginBottom(maxSize - size, Unit.PX);
}

private void setStyle(Style style, double size)
{
style.setWidth(size, Unit.PX);
style.setHeight(size, Unit.PX);
}
}

David Vree

unread,
Nov 29, 2011, 11:54:13 PM11/29/11
to google-we...@googlegroups.com
Is there some reason you chose to re-implement in Java instead of using JSNI to wrap the existing Javascript implementation?

Alex Luya

unread,
Nov 30, 2011, 12:36:57 AM11/30/11
to google-we...@googlegroups.com
No very strong reasons.But it seems like this js code doesn't get
maintained anymore and a little bit old.The second reason is for code
clean,I don't like many calls between js and java.the third is that I
would rather to change java but js if some changes must be did in the
future.

On Tue, 2011-11-29 at 20:54 -0800, David Vree wrote:
> Is there some reason you chose to re-implement in Java instead of
> using JSNI to wrap the existing Javascript implementation?
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Google Web Toolkit" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-web-toolkit/-/jif4vjWQQTcJ.
> To post to this group, send email to
> google-we...@googlegroups.com.
> To unsubscribe from this group, send email to google-web-toolkit
> +unsub...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/google-web-toolkit?hl=en.


Reply all
Reply to author
Forward
0 new messages