diff --git a/src/server/gwt/.classpath b/src/server/gwt/.classpath index 2a4886461..88918ea5b 100644 --- a/src/server/gwt/.classpath +++ b/src/server/gwt/.classpath @@ -3,5 +3,6 @@ + diff --git a/src/server/gwt/Fridge-compile b/src/server/gwt/Fridge-compile index 1a421c5d5..7e9af5d2c 100644 --- a/src/server/gwt/Fridge-compile +++ b/src/server/gwt/Fridge-compile @@ -14,4 +14,6 @@ if [ `uname` = "Darwin" ]; then GWT_JAVA_OPTS=-XstartOnFirstThread fi -java $GWT_JAVA_OPTS -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:$GWT_CLASSPATH" com.google.gwt.dev.GWTCompiler -out "$APPDIR/www" "$@" se.chalmers.cs.gf.gwt.FridgeApp; +LIBS=$APPDIR/lib/gwt-dnd-2.5.6.jar + +java $GWT_JAVA_OPTS -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:$LIBS:$GWT_CLASSPATH" com.google.gwt.dev.GWTCompiler -out "$APPDIR/www" "$@" se.chalmers.cs.gf.gwt.FridgeApp; diff --git a/src/server/gwt/Fridge-shell-external b/src/server/gwt/Fridge-shell-external index b6261e63a..5434038b9 100644 --- a/src/server/gwt/Fridge-shell-external +++ b/src/server/gwt/Fridge-shell-external @@ -14,4 +14,6 @@ if [ `uname` = "Darwin" ]; then GWT_JAVA_OPTS=-XstartOnFirstThread fi -java $GWT_JAVA_OPTS -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:$GWT_CLASSPATH" com.google.gwt.dev.GWTShell -out "$APPDIR/www" -noserver "$@" http://localhost:41296/gwt/www/se.chalmers.cs.gf.gwt.FridgeApp/Fridge.html; +LIBS=$APPDIR/lib/gwt-dnd-2.5.6.jar + +java $GWT_JAVA_OPTS -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:$LIBS:$GWT_CLASSPATH" com.google.gwt.dev.GWTShell -out "$APPDIR/www" -noserver "$@" http://localhost:41296/gwt/www/se.chalmers.cs.gf.gwt.FridgeApp/Fridge.html; diff --git a/src/server/gwt/Translate-compile b/src/server/gwt/Translate-compile index 5b2e5ee0a..3feec0315 100644 --- a/src/server/gwt/Translate-compile +++ b/src/server/gwt/Translate-compile @@ -14,4 +14,6 @@ if [ `uname` = "Darwin" ]; then GWT_JAVA_OPTS=-XstartOnFirstThread fi -java $GWT_JAVA_OPTS -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:$GWT_CLASSPATH" com.google.gwt.dev.GWTCompiler -out "$APPDIR/www" "$@" se.chalmers.cs.gf.gwt.TranslateApp; +LIBS=$APPDIR/lib/gwt-dnd-2.5.6.jar + +java $GWT_JAVA_OPTS -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:$LIBS:$GWT_CLASSPATH" com.google.gwt.dev.GWTCompiler -out "$APPDIR/www" "$@" se.chalmers.cs.gf.gwt.TranslateApp; diff --git a/src/server/gwt/Translate-shell-external b/src/server/gwt/Translate-shell-external index 0a18912fd..fc2688bd4 100644 --- a/src/server/gwt/Translate-shell-external +++ b/src/server/gwt/Translate-shell-external @@ -14,4 +14,6 @@ if [ `uname` = "Darwin" ]; then GWT_JAVA_OPTS=-XstartOnFirstThread fi -java $GWT_JAVA_OPTS -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:$GWT_CLASSPATH" com.google.gwt.dev.GWTShell -out "$APPDIR/www" -noserver "$@" http://localhost:41296/gwt/www/se.chalmers.cs.gf.gwt.TranslateApp/Translate.html; +LIBS=$APPDIR/lib/gwt-dnd-2.5.6.jar + +java $GWT_JAVA_OPTS -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:$LIBS:$GWT_CLASSPATH" com.google.gwt.dev.GWTShell -out "$APPDIR/www" -noserver "$@" http://localhost:41296/gwt/www/se.chalmers.cs.gf.gwt.TranslateApp/Translate.html; diff --git a/src/server/gwt/lib/gwt-dnd-2.5.6.jar b/src/server/gwt/lib/gwt-dnd-2.5.6.jar new file mode 100644 index 000000000..fcb838b75 Binary files /dev/null and b/src/server/gwt/lib/gwt-dnd-2.5.6.jar differ diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/FridgeApp.gwt.xml b/src/server/gwt/src/se/chalmers/cs/gf/gwt/FridgeApp.gwt.xml index c1a7fbf0e..1a27d21d6 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/FridgeApp.gwt.xml +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/FridgeApp.gwt.xml @@ -13,6 +13,9 @@ + + + diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeApp.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeApp.java index 370b918ea..da639d796 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeApp.java +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeApp.java @@ -1,27 +1,32 @@ package se.chalmers.cs.gf.gwt.client; +import com.allen_sauer.gwt.dnd.client.PickupDragController; +import com.allen_sauer.gwt.dnd.client.drop.DropController; +import com.google.gwt.user.client.History; import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.ChangeListener; import com.google.gwt.user.client.ui.ClickListener; -import com.google.gwt.user.client.ui.FlowPanel; -import com.google.gwt.user.client.ui.HasText; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Hyperlink; -import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Panel; +import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; public class FridgeApp extends TranslateApp { - private FlowPanel bagPanel; + private FridgeBagPanel bagPanel; + private FridgeTextPanel textPanel; + + private MagnetFactory magnetFactory; // // Text // protected void update () { - updateBag(); + bagPanel.updateBag(getText()); translate(); } @@ -47,90 +52,32 @@ public class FridgeApp extends TranslateApp { return pgf.getPGFName() + "/" + language + "/" + text; } - private void updateBag () { - updateBag(""); - } - - private void updateBag (String prefix) { - int limit = 100; - pgf.complete(getText() + " " + prefix, - limit, new PGF.CompleteCallback() { - public void onResult(PGF.Completions completions) { - bagPanel.clear(); - for (PGF.Completion completion : completions.iterable()) { - String text = completion.getText(); - if (!completion.getText().equals(getText() + " ")) { - String[] words = text.split("\\s+"); - String word = (words.length > 0) ? words[words.length - 1] : ""; - String token = makeToken(completion.getFrom(), text); - Hyperlink magnet = new Hyperlink(word, token); - magnet.addStyleName("my-Magnet"); - bagPanel.add(magnet); - } - } - if (bagPanel.getWidgetCount() == 0) { - bagPanel.add(new Label("")); - } - } - public void onError(Throwable e) { - showError("Error getting completions.", e); - } - }); - } - // // Current text // - private class TextPanel extends FlowPanel implements HasText { - - public TextPanel () { } - - public String getText () { - StringBuilder sb = new StringBuilder(); - for (Widget w : this) { - String word = ((UsedMagnet)w).getText(); - if (sb.length() > 0) { - sb.append(' '); - } - sb.append(word); - } - return sb.toString(); - } - - public void setText (String text) { - String inputLanguage = pgf.getInputLanguage(); - clear(); - for (String word : text.split("\\s+")) { - if (word.length() > 0) { - add(new UsedMagnet(inputLanguage, word)); - } - } - } - - } - private void clear() { - setText(""); + textPanel.clear(); } - // + // History stuff - // protected void updateSettingsFromHistoryToken(String[] tokenParts) { super.updateSettingsFromHistoryToken(tokenParts); if (tokenParts.length >= 3 && tokenParts[2].length() > 0) { - textSource.setText(tokenParts[2]); + setText(tokenParts[2]); update(); } } - // - // GUI - // - protected Widget createTranslationUI() { + // GUI + + protected Widget createUI() { + PickupDragController dragController = new PickupDragController(RootPanel.get(), false); + magnetFactory = new MagnetFactory(dragController); + VerticalPanel vPanel = new VerticalPanel(); vPanel.setWidth("100%"); vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER); @@ -139,12 +86,20 @@ public class FridgeApp extends TranslateApp { vPanel.add(createBagPanel()); vPanel.add(createSettingsPanel()); vPanel.add(createTranslationsPanel()); + + DropController dropController = new FridgeTextPanelDropController(textPanel); + dragController.registerDropController(dropController); + return vPanel; } protected Widget createTextPanel () { - TextPanel textPanel = new TextPanel(); - textPanel.setStylePrimaryName("my-TextPanel"); + textPanel = new FridgeTextPanel(magnetFactory); + textPanel.addChangeListener(new ChangeListener() { + public void onChange(Widget widget) { + update(); + } + }); textSource = textPanel; @@ -162,17 +117,23 @@ public class FridgeApp extends TranslateApp { } protected Widget createBagPanel () { - bagPanel = new FlowPanel(); - bagPanel.setStylePrimaryName("my-BagPanel"); + bagPanel = new FridgeBagPanel(pgf, magnetFactory); return bagPanel; } - // + // Initialization - // public void onModuleLoad() { - super.onModuleLoad(); + statusPopup = new StatusPopup(); + + pgf = new PGFWrapper(new PGF(pgfBaseURL), new MySettingsListener()); + + RootPanel.get().add(createUI()); + + History.addHistoryListener(new MyHistoryListener()); + + updateSettingsFromHistoryToken(); } } diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeBagPanel.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeBagPanel.java new file mode 100644 index 000000000..46579c578 --- /dev/null +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeBagPanel.java @@ -0,0 +1,53 @@ +package se.chalmers.cs.gf.gwt.client; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; + +public class FridgeBagPanel extends Composite { + + private PGFWrapper pgf; + + private MagnetFactory magnetFactory; + + private FlowPanel mainPanel; + + public FridgeBagPanel (PGFWrapper pgf, MagnetFactory magnetFactory) { + this.pgf = pgf; + this.magnetFactory = magnetFactory; + mainPanel = new FlowPanel(); + initWidget(mainPanel); + setStylePrimaryName("my-FridgeBagPanel"); + } + + public void updateBag (String text) { + updateBag(text, ""); + } + + public void updateBag (String text, String prefix) { + mainPanel.clear(); + int limit = 100; + pgf.complete(text + " " + prefix, + limit, new PGF.CompleteCallback() { + public void onResult(PGF.Completions completions) { + mainPanel.clear(); + for (PGF.Completion completion : completions.iterable()) { + String text = completion.getText(); + if (!completion.getText().equals(text + " ")) { + String[] words = text.split("\\s+"); + if (words.length > 0) { + String word = words[words.length - 1]; + Magnet magnet = magnetFactory.createMagnet(word); + mainPanel.add(magnet); + } + } + } + } + public void onError(Throwable e) { + // FIXME: show message to user? + GWT.log("Error getting completions.", e); + } + }); + } + +} diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeTextPanel.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeTextPanel.java new file mode 100644 index 000000000..b16b10ed1 --- /dev/null +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeTextPanel.java @@ -0,0 +1,75 @@ +package se.chalmers.cs.gf.gwt.client; + +import com.google.gwt.user.client.ui.ChangeListener; +import com.google.gwt.user.client.ui.ChangeListenerCollection; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HasText; +import com.google.gwt.user.client.ui.Panel; +import com.google.gwt.user.client.ui.Widget; + +public class FridgeTextPanel extends Composite implements HasText { + + private MagnetFactory magnetFactory; + + private Panel mainPanel; + + private ChangeListenerCollection listeners = null; + + public FridgeTextPanel (MagnetFactory magnetFactory) { + this.magnetFactory = magnetFactory; + mainPanel = new FlowPanel(); + initWidget(mainPanel); + setStylePrimaryName("my-FridgeTextPanel"); + } + + public void setEngaged(boolean engaged) { + if (engaged) { + addStyleDependentName("engage"); + } else { + removeStyleDependentName("engage"); + } + } + + public String getText () { + StringBuilder sb = new StringBuilder(); + for (Widget w : mainPanel) { + String word = ((Magnet)w).getText(); + if (sb.length() > 0) { + sb.append(' '); + } + sb.append(word); + } + return sb.toString(); + } + + public void setText (String text) { + clear(); + for (String word : text.split("\\s+")) { + if (word.length() > 0) { + addMagnet(magnetFactory.createMagnet(word)); + } + } + } + + public void clear () { + mainPanel.clear(); + fireChange(); + } + + public void addMagnet (Magnet magnet) { + mainPanel.add(magnet); + fireChange(); + } + + protected void fireChange() { + listeners.fireChange(this); + } + + public void addChangeListener(ChangeListener listener) { + if (listeners == null) { + listeners = new ChangeListenerCollection(); + } + listeners.add(listener); + } +} diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeTextPanelDropController.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeTextPanelDropController.java new file mode 100644 index 000000000..76e5706d5 --- /dev/null +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeTextPanelDropController.java @@ -0,0 +1,34 @@ +package se.chalmers.cs.gf.gwt.client; + +import com.allen_sauer.gwt.dnd.client.DragContext; +import com.allen_sauer.gwt.dnd.client.drop.SimpleDropController; +import com.google.gwt.user.client.ui.Widget; + +public class FridgeTextPanelDropController extends SimpleDropController { + + private FridgeTextPanel textPanel; + + public FridgeTextPanelDropController (FridgeTextPanel textPanel) { + super(textPanel); + this.textPanel = textPanel; + } + + public void onEnter(DragContext context) { + super.onEnter(context); + textPanel.setEngaged(true); + } + + public void onLeave(DragContext context) { + textPanel.setEngaged(false); + super.onLeave(context); + } + + public void onDrop(DragContext context) { + for (Widget widget : context.selectedWidgets) { + Magnet magnet = (Magnet)widget; + textPanel.addMagnet(magnet); + } + super.onDrop(context); + } + +} diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/Magnet.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/Magnet.java new file mode 100644 index 000000000..12eca5e97 --- /dev/null +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/Magnet.java @@ -0,0 +1,12 @@ +package se.chalmers.cs.gf.gwt.client; + +import com.google.gwt.user.client.ui.Label; + +public class Magnet extends Label { + + public Magnet (String text) { + setText(text); + setStylePrimaryName("my-Magnet"); + } + +} diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/MagnetFactory.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/MagnetFactory.java new file mode 100644 index 000000000..496cb4fb5 --- /dev/null +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/MagnetFactory.java @@ -0,0 +1,19 @@ +package se.chalmers.cs.gf.gwt.client; + +import com.allen_sauer.gwt.dnd.client.PickupDragController; + +public class MagnetFactory { + + private PickupDragController dragController; + + public MagnetFactory (PickupDragController dragController) { + this.dragController = dragController; + } + + public Magnet createMagnet(String text) { + Magnet magnet = new Magnet(text); + dragController.makeDraggable(magnet); + return magnet; + } + +} diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/TranslateApp.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/TranslateApp.java index 6d3be2f43..1a5dea6c8 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/TranslateApp.java +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/TranslateApp.java @@ -15,12 +15,10 @@ import com.google.gwt.user.client.ui.Widget; public class TranslateApp implements EntryPoint { - private static final String pgfBaseURL = "/pgf"; + protected static final String pgfBaseURL = "/pgf"; protected PGFWrapper pgf; - protected Widget translationUI; - protected HasText textSource; protected VerticalPanel outputPanel; protected StatusPopup statusPopup; @@ -92,8 +90,8 @@ public class TranslateApp implements EntryPoint { // // GUI // - - protected Widget createTranslationUI() { + + protected Widget createUI() { VerticalPanel vPanel = new VerticalPanel(); vPanel.setWidth("100%"); vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER); @@ -138,7 +136,7 @@ public class TranslateApp implements EntryPoint { // History stuff // - private HistoryListener historyListener = new HistoryListener() { + protected class MyHistoryListener implements HistoryListener { public void onHistoryChanged(String historyToken) { updateSettingsFromHistoryToken(); } @@ -182,8 +180,6 @@ public class TranslateApp implements EntryPoint { pgf.setPGFName(grammars.get(0)); } } - RootPanel.get().clear(); - RootPanel.get().add(translationUI); } public void onAvailableLanguagesChanged() { if (pgf.getInputLanguage() == null) { @@ -209,13 +205,11 @@ public class TranslateApp implements EntryPoint { public void onModuleLoad() { statusPopup = new StatusPopup(); - RootPanel.get().add(createLoadingWidget()); - pgf = new PGFWrapper(new PGF(pgfBaseURL), new MySettingsListener()); + + RootPanel.get().add(createUI()); - translationUI = createTranslationUI(); - - History.addHistoryListener(historyListener); + History.addHistoryListener(new MyHistoryListener()); updateSettingsFromHistoryToken(); } diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/UsedMagnet.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/UsedMagnet.java deleted file mode 100644 index 1388ae811..000000000 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/UsedMagnet.java +++ /dev/null @@ -1,20 +0,0 @@ -package se.chalmers.cs.gf.gwt.client; - -import com.google.gwt.user.client.ui.Composite; -import com.google.gwt.user.client.ui.Label; - -public class UsedMagnet extends Composite { - - private String word; - - public UsedMagnet(String language, String word) { - this.word = word; - initWidget(new Label(word)); - setStylePrimaryName("my-UsedMagnet"); - } - - public String getText() { - return word; - } - -} diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Fridge.css b/src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Fridge.css index c703e229c..22ec8adad 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Fridge.css +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Fridge.css @@ -2,23 +2,31 @@ body { background: url("brushed-metal.png"); } -.my-TextPanel, .my-BagPanel, .my-translations, .my-SettingsPanel { +.my-FridgeTextPanel, .my-FridgeBagPanel, .my-translations, .my-SettingsPanel { margin: 1em; } -.my-TextPanel { - font-size: 150%; +.my-FridgeTextPanel, .my-FridgeBagPanel { min-height: 2em; + padding: 0.2em; + overflow: auto; +} + +.my-FridgeTextPanel { + font-size: 150%; border: 3px dashed #dddddd; - overflow: auto; } -.my-BagPanel { +.my-FridgeTextPanel-engage { + border-color: #aaaaaa; + background-color: #ccff99; +} + +.my-FridgeBagPanel { border: 3px solid #dddddd; - overflow: auto; } -.my-Magnet, .my-UsedMagnet { +.my-Magnet { float: left; margin: 0.3em; border-width: 1px; @@ -29,11 +37,6 @@ body { background-color: white; } -.my-Magnet a, .my-UsedMagnet a { - color: black; - text-decoration: none; -} - .my-translations { border: 1px solid silver; }