Fridge: allow clicks in addition to drag and drop. Don't remove magnets when dnd-ing.

This commit is contained in:
bjorn
2008-11-06 13:42:16 +00:00
parent 58bd23759f
commit 637bdfdb93
7 changed files with 247 additions and 78 deletions

View File

@@ -1,23 +1,35 @@
package se.chalmers.cs.gf.gwt.client; package se.chalmers.cs.gf.gwt.client;
import java.util.List;
import com.allen_sauer.gwt.dnd.client.PickupDragController; import com.allen_sauer.gwt.dnd.client.PickupDragController;
import com.allen_sauer.gwt.dnd.client.drop.DropController; import com.allen_sauer.gwt.dnd.client.drop.DropController;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.History; import com.google.gwt.user.client.History;
import com.google.gwt.user.client.HistoryListener;
import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ChangeListener; import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener; import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.Widget;
public class FridgeApp extends TranslateApp { public class FridgeApp implements EntryPoint {
protected static final String pgfBaseURL = "/pgf";
protected PGFWrapper pgf;
protected JSONRequest translateRequest = null;
private FridgeBagPanel bagPanel; private FridgeBagPanel bagPanel;
private FridgeTextPanel textPanel; private FridgeTextPanel textPanel;
protected VerticalPanel outputPanel;
protected StatusPopup statusPopup;
private MagnetFactory magnetFactory; private MagnetFactory magnetFactory;
@@ -34,49 +46,102 @@ public class FridgeApp extends TranslateApp {
// Translation // Translation
// //
protected Widget createTranslation(String language, String text) { protected void translate() {
Hyperlink l = new Hyperlink(text, makeToken(language, text)); outputPanel.clear();
l.addStyleName("my-translation"); outputPanel.addStyleDependentName("working");
String lang = pgf.getLanguageCode(language); if (translateRequest != null) {
if (lang != null) { translateRequest.cancel();
l.getElement().setLang(lang);
} }
return l; translateRequest = pgf.translate(getText(),
new PGF.TranslateCallback() {
public void onResult (PGF.Translations translations) {
outputPanel.removeStyleDependentName("working");
for (PGF.Translation t : translations.iterable()) {
outputPanel.add(createTranslation(t.getTo(), t.getText()));
}
}
public void onError (Throwable e) {
showError("Translation failed", e);
}
});
} }
// protected ClickListener translationClickListener = new ClickListener () {
// Available words public void onClick(Widget widget) {
// Magnet magnet = (Magnet)widget;
setInputLanguage(magnet.getLanguage()); // FIXME: this causes an unnecessary update()
setText(magnet.getText(), magnet.getLanguage());
}
};
private String makeToken (String language, String text) { protected Widget createTranslation(String language, String text) {
return pgf.getPGFName() + "/" + language + "/" + text; Magnet magnet = magnetFactory.createUsedMagnet(text, language);
magnet.addClickListener(translationClickListener);
String lang = pgf.getLanguageCode(language);
if (lang != null) {
magnet.getElement().setLang(lang);
}
return magnet;
} }
// //
// Current text // Current text
// //
public String getText () {
return textPanel.getText();
}
public void setText(String text, String language) {
textPanel.setText(text, language);
}
private void clear() { private void clear() {
textPanel.clear(); textPanel.clear();
} }
// History stuff //
// Status stuff
//
protected void updateSettingsFromHistoryToken(String[] tokenParts) { protected void setStatus(String msg) {
super.updateSettingsFromHistoryToken(tokenParts); statusPopup.setStatus(msg);
if (tokenParts.length >= 3 && tokenParts[2].length() > 0) {
setText(tokenParts[2]);
update();
}
} }
protected void showError(String msg, Throwable e) {
statusPopup.showError(msg, e);
}
protected void clearStatus() {
statusPopup.clearStatus();
}
// GUI // GUI
protected Widget createUI() { protected Widget createUI() {
PickupDragController dragController = new PickupDragController(RootPanel.get(), false); PickupDragController dragController = new PickupDragController(RootPanel.get(), false);
magnetFactory = new MagnetFactory(dragController); dragController.setBehaviorDragStartSensitivity(1);
dragController.setBehaviorDragProxy(true);
dragController.setBehaviorConstrainedToBoundaryPanel(true);
/*
dragController.addDragHandler(new DragHandlerAdapter() {
public void onDragStart(DragStartEvent event) {
Widget w = event.getContext().draggable;
if (w instanceof Magnet) {
bagPanel.cloneMagnet((Magnet)w);
}
}
});
*/
ClickListener magnetClickListener = new ClickListener () {
public void onClick(Widget widget) {
Magnet magnet = (Magnet)widget;
textPanel.addMagnet(magnet);
}
};
magnetFactory = new MagnetFactory(dragController, magnetClickListener);
VerticalPanel vPanel = new VerticalPanel(); VerticalPanel vPanel = new VerticalPanel();
vPanel.setWidth("100%"); vPanel.setWidth("100%");
@@ -101,8 +166,6 @@ public class FridgeApp extends TranslateApp {
} }
}); });
textSource = textPanel;
return textPanel; return textPanel;
} }
@@ -121,8 +184,84 @@ public class FridgeApp extends TranslateApp {
return bagPanel; return bagPanel;
} }
protected Widget createSettingsPanel () {
return new SettingsPanel(pgf, true, false);
}
protected Widget createTranslationsPanel () {
outputPanel = new VerticalPanel();
outputPanel.addStyleName("my-translations");
return outputPanel;
}
//
// History stuff
//
protected class MyHistoryListener implements HistoryListener {
public void onHistoryChanged(String historyToken) {
updateSettingsFromHistoryToken();
}
};
protected void updateSettingsFromHistoryToken() {
updateSettingsFromHistoryToken(History.getToken().split("/"));
}
protected void updateSettingsFromHistoryToken(String[] tokenParts) {
if (tokenParts.length >= 1 && tokenParts[0].length() > 0) {
setPGFName(tokenParts[0]);
}
if (tokenParts.length >= 2 && tokenParts[1].length() > 0) {
setInputLanguage(tokenParts[1]);
}
}
protected void setPGFName (String pgfName) {
if (pgfName != null && !pgfName.equals(pgf.getPGFName())) {
pgf.setPGFName(pgfName);
}
}
protected void setInputLanguage (String inputLanguage) {
if (inputLanguage != null && !inputLanguage.equals(pgf.getInputLanguage())) {
pgf.setInputLanguage(inputLanguage);
}
}
//
// Initialization // Initialization
//
protected class MySettingsListener implements PGFWrapper.SettingsListener {
// Will only happen on load
public void onAvailableGrammarsChanged() {
if (pgf.getPGFName() == null) {
List<String> grammars = pgf.getGrammars();
if (!grammars.isEmpty()) {
pgf.setPGFName(grammars.get(0));
}
}
}
public void onAvailableLanguagesChanged() {
if (pgf.getInputLanguage() == null) {
GWT.log("Setting input language to user language: " + pgf.getUserLanguage(), null);
pgf.setInputLanguage(pgf.getUserLanguage());
}
}
public void onInputLanguageChanged() {
clear();
}
public void onOutputLanguageChanged() {
update();
}
public void onCatChanged() {
update();
}
public void onSettingsError(String msg, Throwable e) {
showError(msg,e);
}
}
public void onModuleLoad() { public void onModuleLoad() {
statusPopup = new StatusPopup(); statusPopup = new StatusPopup();

View File

@@ -1,22 +1,19 @@
package se.chalmers.cs.gf.gwt.client; package se.chalmers.cs.gf.gwt.client;
import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FlowPanel;
public class FridgeBagPanel extends Composite { public class FridgeBagPanel extends FlowPanel {
private PGFWrapper pgf; private PGFWrapper pgf;
private MagnetFactory magnetFactory; private MagnetFactory magnetFactory;
private FlowPanel mainPanel; protected JSONRequest completeRequest = null;
public FridgeBagPanel (PGFWrapper pgf, MagnetFactory magnetFactory) { public FridgeBagPanel (PGFWrapper pgf, MagnetFactory magnetFactory) {
this.pgf = pgf; this.pgf = pgf;
this.magnetFactory = magnetFactory; this.magnetFactory = magnetFactory;
mainPanel = new FlowPanel();
initWidget(mainPanel);
setStylePrimaryName("my-FridgeBagPanel"); setStylePrimaryName("my-FridgeBagPanel");
} }
@@ -24,21 +21,24 @@ public class FridgeBagPanel extends Composite {
updateBag(text, ""); updateBag(text, "");
} }
public void updateBag (String text, String prefix) { public void updateBag (final String text, String prefix) {
mainPanel.clear(); clear();
int limit = 100; int limit = 100;
pgf.complete(text + " " + prefix, if (completeRequest != null) {
completeRequest.cancel();
}
completeRequest = pgf.complete(text + " " + prefix,
limit, new PGF.CompleteCallback() { limit, new PGF.CompleteCallback() {
public void onResult(PGF.Completions completions) { public void onResult(PGF.Completions completions) {
mainPanel.clear(); clear();
for (PGF.Completion completion : completions.iterable()) { for (PGF.Completion completion : completions.iterable()) {
String text = completion.getText(); String newText = completion.getText();
if (!completion.getText().equals(text + " ")) { if (!newText.equals(text + " ")) {
String[] words = text.split("\\s+"); String[] words = newText.split("\\s+");
if (words.length > 0) { if (words.length > 0) {
String word = words[words.length - 1]; String word = words[words.length - 1];
Magnet magnet = magnetFactory.createMagnet(word); Magnet magnet = magnetFactory.createMagnet(word, completion.getFrom());
mainPanel.add(magnet); add(magnet);
} }
} }
} }
@@ -49,5 +49,16 @@ public class FridgeBagPanel extends Composite {
} }
}); });
} }
/*
public void cloneMagnet (Magnet magnet) {
int i = getWidgetIndex(magnet);
GWT.log("cloneMagnet: " + magnet.getParent(), null);
if (i != -1) {
GWT.log("cloning", null);
insert(magnetFactory.createMagnet(magnet), i);
}
}
*/
} }

View File

@@ -4,15 +4,13 @@ import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ChangeListenerCollection; import com.google.gwt.user.client.ui.ChangeListenerCollection;
import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel; 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; import com.google.gwt.user.client.ui.Widget;
public class FridgeTextPanel extends Composite implements HasText { public class FridgeTextPanel extends Composite {
private MagnetFactory magnetFactory; private MagnetFactory magnetFactory;
private Panel mainPanel; private FlowPanel mainPanel;
private ChangeListenerCollection listeners = null; private ChangeListenerCollection listeners = null;
@@ -30,7 +28,7 @@ public class FridgeTextPanel extends Composite implements HasText {
removeStyleDependentName("engage"); removeStyleDependentName("engage");
} }
} }
public String getText () { public String getText () {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (Widget w : mainPanel) { for (Widget w : mainPanel) {
@@ -43,12 +41,15 @@ public class FridgeTextPanel extends Composite implements HasText {
return sb.toString(); return sb.toString();
} }
public void setText (String text) { public void setText (String text, String language) {
clear(); if (!text.equals(getText())) {
for (String word : text.split("\\s+")) { mainPanel.clear();
if (word.length() > 0) { for (String word : text.split("\\s+")) {
addMagnet(magnetFactory.createMagnet(word)); if (word.length() > 0) {
mainPanel.add(magnetFactory.createUsedMagnet(word, language));
}
} }
fireChange();
} }
} }
@@ -56,16 +57,16 @@ public class FridgeTextPanel extends Composite implements HasText {
mainPanel.clear(); mainPanel.clear();
fireChange(); fireChange();
} }
public void addMagnet (Magnet magnet) { public void addMagnet (Magnet magnet) {
mainPanel.add(magnet); mainPanel.add(magnetFactory.createUsedMagnet(magnet));
fireChange(); fireChange();
} }
protected void fireChange() { protected void fireChange() {
listeners.fireChange(this); listeners.fireChange(this);
} }
public void addChangeListener(ChangeListener listener) { public void addChangeListener(ChangeListener listener) {
if (listeners == null) { if (listeners == null) {
listeners = new ChangeListenerCollection(); listeners = new ChangeListenerCollection();

View File

@@ -1,12 +1,19 @@
package se.chalmers.cs.gf.gwt.client; package se.chalmers.cs.gf.gwt.client;
import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.HTML;
public class Magnet extends Label { public class Magnet extends HTML {
public Magnet (String text) { private String language;
setText(text);
public Magnet (String text, String language) {
this.language = language;
setHTML(text);
setStylePrimaryName("my-Magnet"); setStylePrimaryName("my-Magnet");
} }
public String getLanguage() {
return language;
}
} }

View File

@@ -1,17 +1,34 @@
package se.chalmers.cs.gf.gwt.client; package se.chalmers.cs.gf.gwt.client;
import com.allen_sauer.gwt.dnd.client.PickupDragController; import com.allen_sauer.gwt.dnd.client.PickupDragController;
import com.google.gwt.user.client.ui.ClickListener;
public class MagnetFactory { public class MagnetFactory {
private PickupDragController dragController; private PickupDragController dragController;
public MagnetFactory (PickupDragController dragController) { private ClickListener clickListener;
public MagnetFactory (PickupDragController dragController, ClickListener clickListener) {
this.dragController = dragController; this.dragController = dragController;
this.clickListener = clickListener;
} }
public Magnet createMagnet(String text) { public Magnet createUsedMagnet(Magnet magnet) {
Magnet magnet = new Magnet(text); return createUsedMagnet(magnet.getText(), magnet.getLanguage());
}
public Magnet createUsedMagnet(String text, String language) {
return new Magnet(text, language);
}
public Magnet createMagnet(Magnet magnet) {
return createMagnet(magnet.getText(), magnet.getLanguage());
}
public Magnet createMagnet(String text, String language) {
Magnet magnet = new Magnet(text, language);
magnet.addClickListener(clickListener);
dragController.makeDraggable(magnet); dragController.makeDraggable(magnet);
return magnet; return magnet;
} }

View File

@@ -6,7 +6,6 @@ import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.History; import com.google.gwt.user.client.History;
import com.google.gwt.user.client.HistoryListener; import com.google.gwt.user.client.HistoryListener;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.VerticalPanel;
@@ -19,7 +18,7 @@ public class TranslateApp implements EntryPoint {
protected PGFWrapper pgf; protected PGFWrapper pgf;
protected HasText textSource; protected SuggestPanel suggestPanel;
protected VerticalPanel outputPanel; protected VerticalPanel outputPanel;
protected StatusPopup statusPopup; protected StatusPopup statusPopup;
@@ -28,12 +27,7 @@ public class TranslateApp implements EntryPoint {
// //
public String getText () { public String getText () {
return textSource.getText(); return suggestPanel.getText();
}
public void setText(String text) {
textSource.setText(text);
update();
} }
protected void update () { protected void update () {
@@ -47,9 +41,10 @@ public class TranslateApp implements EntryPoint {
protected void translate() { protected void translate() {
outputPanel.clear(); outputPanel.clear();
outputPanel.addStyleDependentName("working"); outputPanel.addStyleDependentName("working");
pgf.translate(textSource.getText(), pgf.translate(getText(),
new PGF.TranslateCallback() { new PGF.TranslateCallback() {
public void onResult (PGF.Translations translations) { public void onResult (PGF.Translations translations) {
outputPanel.clear();
outputPanel.removeStyleDependentName("working"); outputPanel.removeStyleDependentName("working");
for (PGF.Translation t : translations.iterable()) { for (PGF.Translation t : translations.iterable()) {
outputPanel.add(createTranslation(t.getTo(), t.getText())); outputPanel.add(createTranslation(t.getTo(), t.getText()));
@@ -102,16 +97,13 @@ public class TranslateApp implements EntryPoint {
} }
protected Widget createSuggestPanel () { protected Widget createSuggestPanel () {
SuggestPanel suggestPanel = new SuggestPanel(pgf); suggestPanel = new SuggestPanel(pgf);
suggestPanel.setButtonText("Translate"); suggestPanel.setButtonText("Translate");
suggestPanel.addSubmitListener(new SuggestPanel.SubmitListener() { suggestPanel.addSubmitListener(new SuggestPanel.SubmitListener() {
public void onSubmit(String text) { public void onSubmit(String text) {
translate(); translate();
} }
}); });
textSource = suggestPanel;
return suggestPanel; return suggestPanel;
} }

View File

@@ -7,7 +7,7 @@ body {
} }
.my-FridgeTextPanel, .my-FridgeBagPanel { .my-FridgeTextPanel, .my-FridgeBagPanel {
min-height: 2em; min-height: 2.4em;
padding: 0.2em; padding: 0.2em;
overflow: auto; overflow: auto;
} }
@@ -18,8 +18,8 @@ body {
} }
.my-FridgeTextPanel-engage { .my-FridgeTextPanel-engage {
border-color: #aaaaaa; border-color: #666666;
background-color: #ccff99; background-color: #dddddd;
} }
.my-FridgeBagPanel { .my-FridgeBagPanel {
@@ -38,7 +38,9 @@ body {
} }
.my-translations { .my-translations {
border: 1px solid silver; min-height: 2.4em;
padding: 0.2em;
border: 3px solid silver;
} }
.my-translation { .my-translation {