--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import com.google.gwt.user.client.ui.ClickListener;
+import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class IButton extends com.google.gwt.user.client.ui.Button implements
+ Paintable {
+
+ String id;
+
+ Client client;
+
+ public IButton() {
+ addClickListener(new ClickListener() {
+
+ public void onClick(Widget sender) {
+ if (id == null || client == null)
+ return;
+ client.updateVariable(id, "state", true, true);
+ }
+ });
+ }
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+
+ // Ensure correct implementation
+ if (client.updateComponent(this, uidl, false))
+ return;
+
+ // Save details
+ this.client = client;
+ id = uidl.getId();
+
+ // Set text
+ setText(uidl.getStringAttribute("caption"));
+
+ // TODO Handle description and errormessages
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import com.google.gwt.user.client.ui.ClickListener;
+import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class ICheckBox extends com.google.gwt.user.client.ui.CheckBox
+ implements Paintable {
+
+ String id;
+
+ boolean immediate;
+
+ Client client;
+
+ public ICheckBox() {
+ addClickListener(new ClickListener() {
+
+ public void onClick(Widget sender) {
+ if (id == null || client == null)
+ return;
+ client.updateVariable(id, "state", isChecked(), immediate);
+ }
+
+ });
+ }
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+
+ // Ensure correct implementation
+ if (client.updateComponent(this, uidl, false))
+ return;
+
+ // Save details
+ this.client = client;
+ id = uidl.getId();
+
+ // Set text
+ setText(uidl.getStringAttribute("caption"));
+ setChecked(uidl.getBooleanVariable("state"));
+ immediate = uidl.getBooleanAttribute("immediate");
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import com.google.gwt.user.client.ui.HTML;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class IEmbedded extends HTML implements Paintable {
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+ if(uidl.getStringAttribute("type").equals("image")) {
+ setHTML("<img src=\""+ uidl.getStringAttribute("src") +"\"/>");
+ } else {
+ setText("Terminal don't know how ty handle this type of embed");
+ }
+ }
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import java.util.Iterator;
+
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class IGridLayout extends FlexTable implements Paintable {
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+ clear();
+ if (uidl.hasAttribute("caption"))
+ setTitle(uidl.getStringAttribute("caption"));
+ int row = 0, column = 0;
+ for (Iterator i = uidl.getChildIterator(); i.hasNext();) {
+ UIDL r = (UIDL) i.next();
+ if ("gr".equals(r.getTag())) {
+ row++;
+ column = 0;
+ for (Iterator j = r.getChildIterator(); j.hasNext();) {
+ UIDL c = (UIDL) j.next();
+ if ("gc".equals(c.getTag())) {
+ column++;
+ if (c.hasAttribute("w")) {
+ int w = c.getIntAttribute("w");
+ ((FlexCellFormatter) getCellFormatter())
+ .setColSpan(row, column, w);
+ }
+ UIDL u = c.getChildUIDL(0);
+ if (u != null) {
+ Widget child = client.getWidget(u);
+ setWidget(row, column, child);
+ ((Paintable) child).updateFromUIDL(u, client);
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.CaptionWrapper;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Layout;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class IHorizontalLayout extends HorizontalPanel implements Paintable, Layout {
+
+ private HashMap componentToWrapper = new HashMap();
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+
+ // Ensure correct implementation
+ if (client.updateComponent(this, uidl, false))
+ return;
+
+ // TODO Should update instead of just redraw
+ clear();
+ componentToWrapper.clear();
+
+ for (Iterator i = uidl.getChildIterator(); i.hasNext();) {
+ UIDL uidlForChild = (UIDL) i.next();
+ Widget child = client.getWidget(uidlForChild);
+ add(child);
+ ((Paintable)child).updateFromUIDL(uidlForChild, client);
+ }
+ }
+
+ public void replaceChildComponent(Widget from, Widget to) {
+ CaptionWrapper wrapper = (CaptionWrapper) componentToWrapper.get(from);
+ if (wrapper != null) {
+ componentToWrapper.remove(from);
+ from = wrapper;
+ }
+ int index = getWidgetIndex(from);
+ if (index >= 0) {
+ remove(index);
+ insert(to, index);
+ }
+ }
+
+ public boolean hasChildComponent(Widget component) {
+ return getWidgetIndex(component) >= 0 || componentToWrapper.get(component) != null;
+ }
+
+ public void updateCaption(Widget component, UIDL uidl) {
+
+ CaptionWrapper wrapper = (CaptionWrapper) componentToWrapper.get(component);
+ if (CaptionWrapper.isNeeded(uidl)) {
+ if (wrapper == null) {
+ int index = getWidgetIndex(component);
+ remove(component);
+ wrapper = new CaptionWrapper(component);
+ insert(wrapper, index);
+ componentToWrapper.put(component, wrapper);
+ }
+ wrapper.updateCaption(uidl);
+ } else {
+ if (wrapper != null) {
+ int index = getWidgetIndex(wrapper);
+ remove(wrapper);
+ insert(wrapper.getWidget(), index);
+ componentToWrapper.remove(component);
+ }
+ }
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Label;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class ILabel extends HTML implements Paintable {
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+
+ if (client.updateComponent(this, uidl, true))
+ return;
+
+ String mode = uidl.getStringAttribute("mode");
+ if (mode == null || "text".equals(mode))
+ setText(uidl.getChildString(0));
+ else if ("pre".equals(mode)) {
+ setHTML(uidl.getChildrenAsXML());
+ } else if ("uidl".equals(mode)) {
+ setHTML(uidl.getChildrenAsXML());
+ } else if ("xhtml".equals(mode)) {
+ setHTML(uidl.getChildUIDL(0).getChildUIDL(0).getChildString(0));
+ } else if ("xml".equals(mode)) {
+ setHTML(uidl.getChildUIDL(0).getChildString(0));
+ } else if ("raw".equals(mode)) {
+ setHTML(uidl.getChildUIDL(0).getChildString(0));
+ } else {
+ setText("");
+ }
+ }
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class IPanel extends IVerticalLayout implements Paintable {
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+ super.updateFromUIDL(uidl, client);
+ }
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;\r
+\r
+import com.google.gwt.user.client.DOM;\r
+\r
+/**\r
+ * This class represents a password field.\r
+ * \r
+ * @author IT Mill Ltd.\r
+ *\r
+ */\r
+public class IPasswordField extends ITextField {\r
+ \r
+ public IPasswordField() {\r
+ super(DOM.createInputPassword());\r
+ }\r
+ \r
+}\r
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import com.google.gwt.user.client.ui.ChangeListener;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.ListBox;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class ISelect extends Composite implements Paintable, ChangeListener {
+
+ Label caption = new Label();
+ ListBox select = new ListBox();
+ private Client client;
+ private String id;
+ private boolean immediate;
+
+
+ public ISelect() {
+ VerticalPanel panel = new VerticalPanel();
+ panel.add(caption);
+ panel.add(select);
+ select.addChangeListener(this);
+ initWidget(panel);
+ }
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+ this.client = client;
+ this.id = uidl.getStringAttribute("id");
+ this.immediate = uidl.getBooleanAttribute("immediate");
+
+ if (uidl.hasAttribute("caption")) caption.setText(uidl.getStringAttribute("caption"));
+
+ if(uidl.hasAttribute("selectmode"))
+ select.setMultipleSelect(true);
+ else
+ select.setMultipleSelect(false);
+
+ UIDL options = uidl.getChildUIDL(0);
+
+ select.clear();
+ for (Iterator i = options.getChildIterator(); i.hasNext();) {
+ UIDL optionUidl = (UIDL)i.next();
+ select.addItem(optionUidl.getStringAttribute("caption"), optionUidl.getStringAttribute("key"));
+ if(optionUidl.hasAttribute("selected"))
+ select.setItemSelected(select.getItemCount()-1, true);
+ }
+ }
+
+ public void onChange(Widget sender) {
+ if(select.isMultipleSelect()) {
+ client.updateVariable(id, "selected", getSelectedKeys(), immediate);
+ } else {
+ client.updateVariable(id, "selected", new String[] { "" + select.getValue(select.getSelectedIndex())}, immediate);
+ }
+ }
+
+ private Object[] getSelectedKeys() {
+ Vector selectedItemKeys = new Vector();
+ for(int i = 0; i < select.getItemCount();i++) {
+ if(select.isItemSelected(i))
+ selectedItemKeys.add(select.getValue(i));
+ }
+ return selectedItemKeys.toArray();
+ }
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.ScrollListener;
+import com.google.gwt.user.client.ui.ScrollPanel;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class ITable extends Composite implements Paintable, ScrollListener {
+
+ /**
+ * multiple of pagelenght which component will
+ * cache when requesting more rows
+ */
+ private static final double CACHE_RATE = 3;
+ /**
+ * fraction of pageLenght which can be scrolled without
+ * making new request
+ */
+ private static final double CACHE_REACT_RATE = 1;
+
+ private int firstRendered = 0;
+ private int lastRendered = 0;
+ private int firstRowInViewPort = 1;
+ private int pageLength = 15;
+
+ private int rowHeaders = 0;
+
+ private Map columnOrder = new HashMap();
+
+ private Client client;
+ private String id;
+ private boolean immediate;
+
+ private FlexTable tHead = new FlexTable();
+ private FlexTable tBody = new FlexTable();
+
+ private ScrollPanel bodyContainer = new ScrollPanel();
+ private VerticalPanel bodyContent = new VerticalPanel();
+
+ private ScrollPanel headerContainer = new ScrollPanel();
+
+ private HTML preSpacer = new HTML();
+ private HTML postSpacer = new HTML();
+
+ private boolean colWidthsInitialized = false;
+ private int totalRows;
+ private HashMap columnWidths = new HashMap();
+
+ private int rowHeight = 22;
+ private RowRequestHandler rowRequestHandler;
+
+ public ITable() {
+ headerContainer.add(tHead);
+ DOM.setStyleAttribute(headerContainer.getElement(), "overflow", "hidden");
+
+ bodyContent.add(preSpacer);
+ bodyContent.add(tBody);
+ bodyContent.add(postSpacer);
+ //TODO remove debug color
+ DOM.setStyleAttribute(postSpacer.getElement(), "background", "gray");
+ bodyContainer.add(bodyContent);
+ bodyContainer.addScrollListener(this);
+
+ VerticalPanel panel = new VerticalPanel();
+ panel.add(headerContainer);
+ panel.add(bodyContainer);
+
+ rowRequestHandler = new RowRequestHandler();
+
+ initWidget(panel);
+ }
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+ this.client = client;
+ this.id = uidl.getStringAttribute("id");
+ this.immediate = uidl.getBooleanAttribute("immediate");
+ this.totalRows = uidl.getIntAttribute("totalrows");
+
+ UIDL columnInfo = null;
+ UIDL rowData = null;
+ for(Iterator it = uidl.getChildIterator(); it.hasNext();) {
+ UIDL c = (UIDL) it.next();
+ if(c.getTag().equals("cols"))
+ columnInfo = c;
+ else if(c.getTag().equals("rows"))
+ rowData = c;
+ else if(c.getTag().equals("actions"))
+ updateActionMap(c);
+ else if(c.getTag().equals("visiblecolumns"))
+ ;
+ }
+ updateHeader(columnInfo);
+
+ updateBody(rowData);
+
+ if(!colWidthsInitialized) {
+ DeferredCommand.add(new Command() {
+ public void execute() {
+ initSize();
+ updateSpacers();
+ }
+ });
+ }
+
+ }
+
+ private void updateActionMap(UIDL c) {
+ // TODO Auto-generated method stub
+
+ }
+
+ private void updateHeader(UIDL uidl) {
+ if(uidl == null)
+ return;
+ for(Iterator it = uidl.getChildIterator();it.hasNext();) {
+ UIDL col = (UIDL) it.next();
+ String cid = col.getStringAttribute("cid");
+ int colIndex = getColIndexByKey(cid);
+ if(colIndex > -1)
+ setHeaderText(colIndex, col.getStringAttribute("caption"));
+ DOM.setAttribute(tHead.getFlexCellFormatter().getElement(0, colIndex), "cid", cid);
+ }
+ }
+
+ private void updateBody(UIDL uidl) {
+ if(uidl == null)
+ return;
+
+ Iterator it = uidl.getChildIterator();
+ UIDL row = (UIDL) it.next();
+ if(firstRendered == 0)
+ firstRendered = row.getIntAttribute("key");
+ if(row.getIntAttribute("key") == lastRendered + 1) {
+ while(it.hasNext())
+ appendRow( (UIDL) it.next() );
+ }
+ }
+
+ private void appendRow(UIDL uidl) {
+ lastRendered++;
+ updateRow(uidl, lastRendered);
+ }
+
+ private void updateRow(UIDL uidl, int rowIndex) {
+ int colIndex = 0;
+ for(Iterator it = uidl.getChildIterator(); it.hasNext();) {
+ Object cell = it.next();
+ if (cell instanceof String) {
+ setCellContent(rowIndex, colIndex, (String) cell);
+ } else {
+ setCellContent(rowIndex, colIndex, (UIDL) cell);
+ }
+ colIndex++;
+ }
+
+ }
+
+
+ private int getRowIndex(int rowKey) {
+ return rowKey - firstRendered;
+ }
+
+ private int getColIndexByKey(String colKey) {
+ return Integer.parseInt(colKey) - 1;
+ }
+
+ private String getColKeyByIndex(int index) {
+ return DOM.getAttribute(tHead.getCellFormatter().getElement(0, index), "cid");
+ }
+
+ public void setHeaderText(int colIndex, String text) {
+ tHead.setText(0, colIndex, text);
+ }
+
+ public void setCellContent(int rowId, int colId, UIDL cell) {
+ if(cell == null)
+ return;
+ Widget cellContent = client.getWidget(cell);
+ tBody.setWidget(rowId, colId, cellContent);
+ ((Paintable)cell).updateFromUIDL(cell, client);
+ }
+
+ public void setCellContent(int rowId, int colId, String text) {
+ tBody.setText(rowId, colId, text);
+ }
+
+ /**
+ * Run when receices its initial content. Syncs headers and bodys
+ * "natural widths and saves the values.
+ */
+ private void initSize() {
+ int cols = tHead.getCellCount(0);
+ FlexCellFormatter hf = tHead.getFlexCellFormatter();
+ FlexCellFormatter bf = tBody.getFlexCellFormatter();
+ for (int i = 0; i < cols; i++) {
+ Element hCell = hf.getElement(0, i);
+ Element bCell = bf.getElement(1, i);
+ int hw = DOM.getIntAttribute(hCell, "offsetWidth");
+ int cw = DOM.getIntAttribute(bCell, "offsetWidth");
+ setColWidth(i , hw > cw ? hw : cw);
+ }
+
+ bodyContainer.setHeight(tBody.getOffsetHeight() + "px");
+ bodyContainer.setWidth(tBody.getOffsetWidth() + "px");
+
+ }
+
+ private void setColWidth(int colIndex, int w) {
+ String cid = getColKeyByIndex(colIndex);
+ tHead.getCellFormatter().setWidth(0, colIndex, w + "px");
+ tBody.getCellFormatter().setWidth(0, colIndex, w + "px");
+ columnWidths.put(cid,new Integer(w));
+ }
+
+ private int getColWidth(String colKey) {
+ return ( (Integer) this.columnWidths.get(colKey)).intValue();
+ }
+
+ private void updateSpacers() {
+ rowHeight = tBody.getOffsetHeight()/getRenderedRowCount();
+ int preSpacerHeight = (firstRendered - 1)*rowHeight;
+ int postSpacerHeight = (totalRows - lastRendered)*rowHeight;
+ preSpacer.setHeight(preSpacerHeight+"px");
+ postSpacer.setHeight(postSpacerHeight + "px");
+ }
+
+ private int getRenderedRowCount() {
+ return lastRendered-firstRendered;
+ }
+
+ /**
+ * This method has logick which rows needs to be requested from
+ * server when user scrolls
+ *
+ */
+ public void onScroll(Widget widget, int scrollLeft, int scrollTop) {
+ rowRequestHandler.cancel();
+
+ firstRowInViewPort = scrollTop / rowHeight;
+ client.console.log("At scrolltop: " + scrollTop + " At row " + firstRowInViewPort);
+
+ int postLimit = (int) (firstRowInViewPort + pageLength + pageLength*CACHE_REACT_RATE);
+ int preLimit = (int) (firstRowInViewPort - pageLength*CACHE_REACT_RATE);
+ if(
+ postLimit > lastRendered &&
+ ( preLimit < 1 || preLimit < firstRendered )
+ ) {
+ client.updateVariable(this.id, "firstvisible", firstRowInViewPort, false);
+ return; // scrolled withing "non-react area"
+ }
+
+ if(firstRowInViewPort - pageLength*CACHE_RATE > lastRendered ||
+ firstRowInViewPort + pageLength + pageLength*CACHE_RATE < firstRendered ) {
+ // need a totally new set
+ client.console.log("Table: need a totally new set");
+ rowRequestHandler.setReqFirstRow((int) (firstRowInViewPort - pageLength*CACHE_RATE));
+ rowRequestHandler.setReqRows((int) (2*CACHE_RATE*pageLength + pageLength));
+ rowRequestHandler.deferRowFetch();
+ return;
+ }
+ if(preLimit < firstRendered ) {
+ // need some rows to the beginning of the rendered area
+ client.console.log("Table: need some rows to the beginning of the rendered area");
+ rowRequestHandler.setReqFirstRow((int) (firstRowInViewPort - pageLength*CACHE_RATE));
+ rowRequestHandler.setReqRows((int) (2*CACHE_RATE*pageLength + pageLength));
+ rowRequestHandler.deferRowFetch();
+
+ return;
+ }
+ if(postLimit > lastRendered) {
+ // need some rows to the end of the rendered area
+ client.console.log("need some rows to the end of the rendered area");
+ rowRequestHandler.setReqFirstRow(lastRendered + 1);
+ rowRequestHandler.setReqRows((int) ((firstRowInViewPort + pageLength + pageLength*CACHE_RATE) - lastRendered));
+ rowRequestHandler.deferRowFetch();
+ }
+ }
+
+ private class RowRequestHandler extends Timer {
+
+ private int reqFirstRow;
+ private int reqRows;
+
+ public void deferRowFetch() {
+ schedule(250);
+ }
+
+ public void setReqFirstRow(int reqFirstRow) {
+ if(reqFirstRow < 1)
+ reqFirstRow = 1;
+ this.reqFirstRow = reqFirstRow;
+ }
+
+ public void setReqRows(int reqRows) {
+ this.reqRows = reqRows;
+ }
+
+ public void run() {
+// client.updateVariable(id, "firstvisible", firstRowInViewPort, false);
+ client.updateVariable(id, "reqfirstrow", reqFirstRow, false);
+ client.updateVariable(id, "reqrows", reqRows, true);
+ }
+
+ }
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import com.google.gwt.user.client.ui.DeckPanel;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.SourcesTabEvents;
+import com.google.gwt.user.client.ui.TabBar;
+import com.google.gwt.user.client.ui.TabListener;
+import com.google.gwt.user.client.ui.TabPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class ITabsheet extends TabPanel implements Paintable {
+
+ String id;
+
+ Client client;
+
+ ArrayList tabKeys = new ArrayList();
+
+ ArrayList captions = new ArrayList();
+
+ int activeTabIndex = 0;
+
+ TabListener tl = new TabListener() {
+
+ public void onTabSelected(SourcesTabEvents sender, int tabIndex) {
+ ITabsheet.this.client.updateVariable(id, "selected", tabIndex,
+ true);
+ }
+
+ public boolean onBeforeTabSelected(SourcesTabEvents sender, int tabIndex) {
+ return true;
+ }
+
+ };
+
+ public ITabsheet() {
+ addTabListener(new TabListener() {
+
+ public void onTabSelected(SourcesTabEvents sender, int tabIndex) {
+ if (client != null && activeTabIndex != tabIndex)
+ ITabsheet.this.client.updateVariable(id, "selected", ""
+ + tabKeys.get(tabIndex), true);
+ }
+
+ public boolean onBeforeTabSelected(SourcesTabEvents sender,
+ int tabIndex) {
+ return true;
+ }
+
+ });
+
+ }
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+ this.client = client;
+ id = uidl.getId();
+
+ UIDL tabs = uidl.getChildUIDL(0);
+ boolean keepCurrentTabs = tabKeys.size() == tabs.getNumberOfChildren();
+ for (int i = 0; keepCurrentTabs && i < tabKeys.size(); i++)
+ keepCurrentTabs = tabKeys.get(i).equals(
+ tabs.getChildUIDL(i).getStringAttribute("key"))
+ && captions.get(i).equals(
+ tabs.getChildUIDL(i).getStringAttribute("caption"));
+ if (keepCurrentTabs) {
+ int index = 0;
+ for (Iterator it = tabs.getChildIterator(); it.hasNext();) {
+ UIDL tab = (UIDL) it.next();
+ if (tab.getBooleanAttribute("selected")) {
+ activeTabIndex = index;
+ Widget content = client.getWidget(tab
+ .getChildUIDL(0));
+ getTabBar().selectTab(index);
+ DeckPanel dp = getDeckPanel();
+ dp.remove(index);
+ dp.insert(content, index);
+ ((Paintable)content).updateFromUIDL(tab
+ .getChildUIDL(0), client);
+ dp.showWidget(index);
+ }
+ index++;
+ }
+ } else {
+ tabKeys.clear();
+ captions.clear();
+ clear();
+ int index = 0;
+ for (Iterator it = tabs.getChildIterator(); it.hasNext();) {
+ UIDL tab = (UIDL) it.next();
+ String key = tab.getStringAttribute("key");
+ String caption = tab.getStringAttribute("caption");
+ captions.add(caption);
+ tabKeys.add(key);
+ if (tab.getBooleanAttribute("selected")) {
+ activeTabIndex = index;
+ Widget content = client.getWidget(tab
+ .getChildUIDL(0));
+ this.add(content, caption);
+ ((Paintable)content).updateFromUIDL(tab
+ .getChildUIDL(0), client);
+ this.selectTab(this.getWidgetIndex(content));
+ } else {
+ this.add(new Label(), caption);
+ }
+ index++;
+ }
+ }
+
+ }
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;\r
+\r
+import com.google.gwt.user.client.DOM;\r
+import com.itmill.toolkit.terminal.gwt.client.Client;\r
+import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
+\r
+/**\r
+ * This class represents a multiline textfield (textarea).\r
+ * \r
+ * @author IT Mill Ltd.\r
+ *\r
+ */\r
+public class ITextArea extends ITextField {\r
+\r
+ public ITextArea() {\r
+ super(DOM.createTextArea());\r
+ }\r
+ \r
+ public void updateFromUIDL(UIDL uidl, Client client) {\r
+ // Call parent renderer explicitly\r
+ super.updateFromUIDL(uidl, client);\r
+ \r
+ if(uidl.hasAttribute("rows"))\r
+ setHeight(uidl.getStringAttribute("rows")+"em");\r
+ }\r
+ \r
+}\r
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.ChangeListener;
+import com.google.gwt.user.client.ui.FocusListener;
+import com.google.gwt.user.client.ui.TextBoxBase;
+import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+/**
+ * This class represents a basic text input field with one row.
+ *
+ * @author IT Mill Ltd.
+ *
+ */
+public class ITextField extends TextBoxBase implements
+ Paintable, ChangeListener, FocusListener {
+
+ /**
+ * The input node CSS classname.
+ */
+ private static final String CLASSNAME = "itk-textfield";
+
+ /**
+ * This CSS classname is added to the input node on hover.
+ */
+ private static final String CLASSNAME_FOCUS = "itk-textfield-focus";
+
+ private String id;
+
+ private Client client;
+
+ private boolean immediate = false;
+
+ public ITextField() {
+ this(DOM.createInputText());
+ }
+
+ protected ITextField(Element node) {
+ super(node);
+ setStyleName(CLASSNAME);
+ addChangeListener(this);
+ addFocusListener(this);
+ }
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+ this.client = client;
+ id = uidl.getId();
+
+ if(client.updateComponent(this, uidl, true))
+ return;
+
+ immediate = uidl.getBooleanAttribute("immediate");
+
+ if(uidl.hasAttribute("cols"))
+ setWidth(uidl.getStringAttribute("cols")+"em");
+
+ setText(uidl.getStringVariable("text"));
+
+
+ }
+
+ public void onChange(Widget sender) {
+ client.updateVariable(id, "text", getText() , immediate);
+ }
+
+ public void onFocus(Widget sender) {
+ addStyleName(CLASSNAME_FOCUS);
+ }
+
+ public void onLostFocus(Widget sender) {
+ removeStyleName(CLASSNAME_FOCUS);
+ }
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.Tree;
+import com.google.gwt.user.client.ui.TreeItem;
+import com.google.gwt.user.client.ui.TreeListener;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class ITree extends Composite implements Paintable {
+
+ Label caption = new Label();
+ Tree tree = new Tree();
+ Set selectedIds = new HashSet();
+ Client client;
+ String id;
+ boolean selectable;
+ boolean multiselect;
+
+ public ITree() {
+ VerticalPanel panel = new VerticalPanel();
+ panel.add(caption);
+ panel.add(tree);
+ initWidget(panel);
+ }
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+ this.client = client;
+ id = uidl.getId();
+ if (uidl.hasAttribute("caption")) caption.setText(uidl.getStringAttribute("caption"));
+ tree.clear();
+ for (Iterator i = uidl.getChildIterator(); i.hasNext();) {
+ UIDL childUidl = (UIDL)i.next();
+ if(childUidl.getTag().equals("leaf"))
+ tree.addItem(childUidl.getStringAttribute("caption"));
+ if(childUidl.getTag().equals("node")) {
+ TreeNode childTree = new TreeNode();
+ tree.addItem(childTree);
+ childTree.updateFromUIDL(childUidl, client);
+ }
+ }
+ String selectMode = uidl.getStringAttribute("selectmode");
+ selectable = selectMode != null;
+ multiselect = "multi".equals(selectMode);
+
+ tree.addTreeListener(new TreeListener() {
+
+ public void onTreeItemStateChanged(TreeItem item) {
+ }
+
+ public void onTreeItemSelected(TreeItem item) {
+ if (!selectable) return;
+ item.setSelected(true);
+ String key = ((TreeNode)item).key;
+ if (key != null) {
+ if (!multiselect) selectedIds.clear();
+ if (selectedIds.contains(key)) selectedIds.remove(key);
+ else selectedIds.add(key);
+ ITree.this.client.updateVariable(ITree.this.id, "selected", selectedIds.toArray(), true);
+ }
+ }
+
+ });
+
+ selectedIds = uidl.getStringArrayVariableAsSet("selected");
+
+ }
+ private class TreeNode extends TreeItem {
+
+ String key;
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+ this.setText(uidl.getStringAttribute("caption"));
+ key = uidl.getStringAttribute("key");
+ for (Iterator i = uidl.getChildIterator(); i.hasNext();) {
+ UIDL childUidl = (UIDL)i.next();
+ TreeNode childTree = new TreeNode();
+ this.addItem(childTree);
+ childTree.updateFromUIDL(childUidl, client);
+ }
+ setState(uidl.getBooleanAttribute("expanded"));
+ setSelected(uidl.getBooleanAttribute("selected"));
+ }
+
+
+ }
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.Tree;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class IUnknownComponent extends Composite implements Paintable{
+
+ com.google.gwt.user.client.ui.Label caption = new com.google.gwt.user.client.ui.Label();;
+ Tree uidlTree = new Tree();
+
+ public IUnknownComponent() {
+ VerticalPanel panel = new VerticalPanel();
+ panel.add(caption);
+ panel.add(uidlTree);
+ initWidget(panel);
+ setStyleName("itmtk-unknown");
+ caption.setStyleName("itmtk-unknown-caption");
+ }
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+ setCaption("Client faced an unknown component type. Unrendered UIDL:");
+ uidlTree.addItem(uidl.dir());
+ }
+
+ public void setCaption(String c) {
+ caption.setText(c);
+ }
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.CaptionWrapper;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Layout;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class IVerticalLayout extends VerticalPanel implements Paintable, Layout {
+
+ private HashMap componentToWrapper = new HashMap();
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+
+ // Ensure correct implementation
+ if (client.updateComponent(this, uidl, false))
+ return;
+
+ // TODO Should update instead of just redraw
+ clear();
+ componentToWrapper.clear();
+
+ for (Iterator i = uidl.getChildIterator(); i.hasNext();) {
+ UIDL uidlForChild = (UIDL) i.next();
+ Widget child = client.getWidget(uidlForChild);
+ add(child);
+ ((Paintable)child).updateFromUIDL(uidlForChild, client);
+ }
+ }
+
+ public void replaceChildComponent(Widget from, Widget to) {
+ CaptionWrapper wrapper = (CaptionWrapper) componentToWrapper.get(from);
+ if (wrapper != null) {
+ componentToWrapper.remove(from);
+ from = wrapper;
+ }
+ int index = getWidgetIndex(from);
+ if (index >= 0) {
+ remove(index);
+ insert(to, index);
+ }
+ }
+
+ public boolean hasChildComponent(Widget component) {
+ return getWidgetIndex(component) >= 0 || componentToWrapper.get(component) != null;
+ }
+
+ public void updateCaption(Widget component, UIDL uidl) {
+
+ CaptionWrapper wrapper = (CaptionWrapper) componentToWrapper.get(component);
+ if (CaptionWrapper.isNeeded(uidl)) {
+ if (wrapper == null) {
+ int index = getWidgetIndex(component);
+ remove(component);
+ wrapper = new CaptionWrapper(component);
+ insert(wrapper, index);
+ componentToWrapper.put(component, wrapper);
+ }
+ wrapper.updateCaption(uidl);
+ } else {
+ if (wrapper != null) {
+ int index = getWidgetIndex(wrapper);
+ remove(wrapper);
+ insert(wrapper.getWidget(), index);
+ componentToWrapper.remove(component);
+ }
+ }
+ }
+
+
+
+}
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.itmill.toolkit.terminal.gwt.client.Client;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class IWindow extends IVerticalLayout implements Paintable {
+
+ public void updateFromUIDL(UIDL uidl, Client client) {
+ super.updateFromUIDL( uidl, client);
+ com.google.gwt.user.client.Window.setTitle(uidl.getStringAttribute("caption"));
+ }
+
+}