-FilterSelect styles 60% done.
-Panel sizing (iLayout) refactored (again).
-Tabsheet sizing now done before content rendering.
-Util.isIE refactored to isIE6.
-ExpandLayout(int orientation) constructor added.
-API change: Select now has setColumns().
svn changeset:2454/svn branch:trunk
return "com.itmill.toolkit.terminal.gwt.client.ui.ITextField";
}
} else if ("table".equals(tag)) {
- if (uidl.hasAttribute("style")) {
- if ("paging".equals(uidl.getStringAttribute("style"))) {
- return "com.itmill.toolkit.terminal.gwt.client.ui.ITablePaging";
- }
- } else {
return "com.itmill.toolkit.terminal.gwt.client.ui.IScrollTable";
- }
+ } else if("pagingtable".equals(tag)) {
+ return "com.itmill.toolkit.terminal.gwt.client.ui.ITablePaging";
} else if ("datefield".equals(tag)) {
if (uidl.hasAttribute("style")) {
if ("calendar".equals(uidl.getStringAttribute("style"))) {
}-*/;
/**
- * Detects if current browser is IE6. Use to isola
+ * Detects if current browser is IE.
*
- * @return true if IE6
+ * @return true if IE
*/
- public static native boolean isIE6() /*-{
+ public static native boolean isIE() /*-{
var browser=$wnd.navigator.appName;
- var version=parseFloat($wnd.navigator.appVersion);
- if (browser=="Microsoft Internet Explorer" && (version < 7) ) {
+ if (browser=="Microsoft Internet Explorer") {
return true;
}
return false;
// add temp element to make some measurements
Element meter = createWidgetWrappper();
DOM.setStyleAttribute(meter, "overflow", "hidden");
- DOM.setStyleAttribute(meter, "height", "0px");
+ DOM.setStyleAttribute(meter, "height", "0");
DOM.appendChild(childContainer, meter);
int usedSpace = DOM.getElementPropertyInt(meter, "offsetTop")
- DOM.getElementPropertyInt(DOM.getFirstChild(childContainer),
int freeSpace = getOffsetHeight() - usedSpace;
DOM.setStyleAttribute(expandedElement, "height", freeSpace + "px");
+ // Component margins will bleed if overflow is not hidden
+ DOM.setStyleAttribute(expandedElement, "overflow", "hidden");
DOM.setStyleAttribute(expandedWidget.getElement(), "position", origiginalPositioning);
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
import com.itmill.toolkit.terminal.gwt.client.Paintable;
import com.itmill.toolkit.terminal.gwt.client.UIDL;
+import com.itmill.toolkit.terminal.gwt.client.Util;
/**
*
private final SuggestionPopup suggestionPopup = new SuggestionPopup();
- private final HTML popupOpener = new HTML("v");
+ private final HTML popupOpener = new HTML("");
private final Image selectedItemIcon = new Image();
currentSuggestions.clear();
UIDL options = uidl.getChildUIDL(0);
totalSuggestions = options.getIntAttribute("totalMatches");
+ String captions = "";
if (clientSideFiltering) {
allSuggestions = new ArrayList();
}
tb.setText(suggestion.getReplacementString());
currentSuggestion = suggestion;
}
+
+ // Collect captions so we can calculate minimum width for textarea
+ if(captions.length() > 0)
+ captions += "|";
+ captions += suggestion.getReplacementString();
}
if (filtering && lastFilter.equals(uidl.getStringVariable("filter"))) {
totalSuggestions);
filtering = false;
}
+
+ // Calculate minumum textarea width
+ int minw = minWidth(captions);
+ if(Util.isIE()) {
+ Element spacer = DOM.createDiv();
+ DOM.setStyleAttribute(spacer, "width", minw+"px");
+ DOM.setStyleAttribute(spacer, "height", "0");
+ DOM.setStyleAttribute(spacer, "overflow", "hidden");
+ DOM.appendChild(panel.getElement(), spacer);
+ } else {
+ DOM.setStyleAttribute(tb.getElement(), "minWidth", minw+"px");
+ }
+
+ // Set columns (width) is given
+ if(uidl.hasAttribute("cols"))
+ DOM.setStyleAttribute(getElement(), "width", uidl.getIntAttribute("cols")+"em");
+
}
public void onSuggestionSelected(FilterSelectSuggestion suggestion) {
tb.setFocus(true);
tb.selectAll();
}
+
+ /*
+ * Calculate minumum width for FilterSelect textarea
+ */
+ private native int minWidth(String captions) /*-{
+ if(!captions || captions.length <= 0)
+ return 0;
+ captions = captions.split("|");
+ var d = $wnd.document.createElement("div");
+ var html = "";
+ for(var i=0; i < captions.length; i++) {
+ html += "<div>" + captions[i] + "</div>";
+ // TODO apply same CSS classname as in suggestionmenu
+ }
+ d.style.position = "absolute";
+ d.style.top = "0";
+ d.style.left = "0";
+ d.style.visibility = "hidden";
+ d.innerHTML = html;
+ $wnd.document.body.appendChild(d);
+ var w = d.offsetWidth;
+ $wnd.document.body.removeChild(d);
+ return w;
+ }-*/;
}
private Element bottomDecoration = DOM.createDiv();
private Element contentNode = DOM.createDiv();
+
+ private String height;
public IPanel() {
super();
this.client = client;
this.id = uidl.getId();
- // Size panel
- String h = uidl.hasVariable("height") ? uidl
- .getStringVariable("height") : null;
+ // Panel size. Height needs to be saved for later use
String w = uidl.hasVariable("width") ? uidl.getStringVariable("width")
: null;
-
+ height = uidl.hasVariable("height") ? uidl.getStringVariable("height")
+ : null;
setWidth(w != null ? w : "");
- if (h != null) {
- setHeight(h);
- } else {
- DOM.setStyleAttribute(contentNode, "height", "");
- // We don't need overflow:auto when panel height is not set
- // (overflow:auto causes rendering errors at least in Firefox when a
- // a panel is inside a tabsheet with overflow:auto set)
- DOM.setStyleAttribute(contentNode, "overflow", "hidden");
- }
-
// TODO optimize: if only the caption has changed, don't re-render whole
// content
if (getWidget() != null) {
clear();
}
+ // Add proper style name for root element
+ // TODO refactor to support additional styles set from server-side
if (uidl.hasAttribute("style"))
setStyleName(CLASSNAME + " " + CLASSNAME + "-"
+ uidl.getStringAttribute("style"));
DOM.setElementProperty(captionNode, "className", CLASSNAME
+ "-caption");
} else {
- // Theme needs this to work around different paddings
+ // Theme needs this to work around different styling
DOM.setElementProperty(captionNode, "className", CLASSNAME
+ "-nocaption");
DOM.setInnerHTML(captionNode, "");
}
-
+
+ // Height adjustment
iLayout();
-
+
// Render content
UIDL layoutUidl = uidl.getChildUIDL(0);
Widget layout = client.getWidget(layoutUidl);
}
public void iLayout() {
- String h = DOM.getStyleAttribute(getElement(), "height");
- if (h != null && h != "") {
- // need to fix containers height properly
-
- boolean hasChildren = getWidget() != null;
- Element contentEl = null;
- String origPositioning = null;
- if (hasChildren) {
- // remove children temporary form normal flow to detect proper
- // size
- contentEl = getWidget().getElement();
- origPositioning = DOM.getStyleAttribute(contentEl, "position");
- DOM.setStyleAttribute(contentEl, "position", "absolute");
- }
+ // In this case we need to fix containers height properly
+ if (height != null && height != "") {
+ // First, calculate needed pixel height
+ setHeight(height);
+ int neededHeight = getOffsetHeight();
+ setHeight("");
+ // Then calculate the size the content area needs to be
+ DOM.setStyleAttribute(contentNode, "height", "0");
+ DOM.setStyleAttribute(contentNode, "overflow", "hidden");
+ int h = getOffsetHeight();
+ int total = neededHeight-h;
+ if(total < 0)
+ total = 0;
+ DOM.setStyleAttribute(contentNode, "height", total + "px");
+ DOM.setStyleAttribute(contentNode, "overflow", "");
+ } else {
DOM.setStyleAttribute(contentNode, "height", "");
- int availableH = DOM.getElementPropertyInt(getElement(),
- "clientHeight");
-
- int usedH = DOM
- .getElementPropertyInt(bottomDecoration, "offsetTop")
- - DOM.getElementPropertyInt(getElement(), "offsetTop")
- + DOM.getElementPropertyInt(bottomDecoration,
- "offsetHeight");
- int contentH = availableH - usedH;
- if (contentH < 0)
- contentH = 0;
- DOM.setStyleAttribute(contentNode, "height", contentH + "px");
- if (hasChildren) {
- DOM.setStyleAttribute(contentEl, "position", origPositioning);
- }
+ // We don't need overflow:auto when height is not set
+ DOM.setStyleAttribute(contentNode, "overflow", "hidden");
}
Util.runAnchestorsLayout(this);
}
// Use cached sub-tree if available
if(uidl.getBooleanAttribute("cached"))
return;
+
+ // Adjust width and height
+ String h = uidl.hasAttribute("height")? uidl.getStringAttribute("height") : null;
+ String w = uidl.hasAttribute("width")? uidl.getStringAttribute("width") : null;
+ setWidth(w!=null?w:"auto");
+
+ // Try to calculate the height as close as possible
+ if(h!=null) {
+ // First, calculate needed pixel height
+ setHeight(h);
+ int neededHeight = getOffsetHeight();
+ setHeight("");
+ // Then calculate the size the content area needs to be
+ tp.setHeight("0");
+ DOM.setStyleAttribute(tp.getElement(), "overflow", "hidden");
+ int height = getOffsetHeight();
+ tp.setHeight(neededHeight-height + "px");
+ DOM.setStyleAttribute(tp.getElement(), "overflow", "");
+ } else {
+ tp.setHeight("auto");
+ // We don't need overflow:auto when tabsheet height is not set
+ DOM.setStyleAttribute(tp.getElement(), "overflow", "hidden");
+ }
UIDL tabs = uidl.getChildUIDL(0);
boolean keepCurrentTabs = tabKeys.size() == tabs.getNumberOfChildren();
if (tab.getBooleanAttribute("selected")) {
activeTabIndex = index;
UIDL contentUIDL = tab.getChildUIDL(0);
-
- // Otherwise render new content
Widget content = client.getWidget(contentUIDL);
((Paintable)content).updateFromUIDL(contentUIDL, client);
tp.remove(index);
// Open selected tab
tb.selectTab(activeTabIndex);
tp.showWidget(activeTabIndex);
-
- // Adjust width and height
- String h = uidl.hasAttribute("height")? uidl.getStringAttribute("height") : null;
- String w = uidl.hasAttribute("width")? uidl.getStringAttribute("width") : null;
- setWidth(w!=null?w:"auto");
-
- // Try to approximate the height as close as possible
- if(h!=null) {
- // First, calculate needed pixel height
- setHeight(h);
- int neededHeight = getOffsetHeight();
- setHeight("auto");
- // Then calculate the size the content area needs to be
- tp.setHeight("0");
- int height = getOffsetHeight();
- tp.setHeight(neededHeight-height + "px");
- } else {
- tp.setHeight("auto");
- // We don't need overflow:auto when tabsheet height is not set
- DOM.setStyleAttribute(tp.getElement(), "overflow", "hidden");
- }
}
height:100%;
}
-#itmtk-ajax-window {\r
- background: #e9eced;\r
- font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif;\r
- color: #464f52;\r
- font-size: 12px;\r
- line-height: 18px;\r
- height:100%;
+#itmtk-ajax-window {
+ background: #e9eced;
+ font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif;
+ color: #464f52;
+ font-size: 13px;
+ line-height: 18px;
}
.i-view {
height:100%;
-}\r
-\r
-input, select, textarea, button {\r
- font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif;\r
- color: #464f52;\r
-}\r
-\r
-select {\r
- padding: 0;\r
- margin: 0;\r
-}\r
-\r
-.i-disabled {\r
- opacity: 0.3;\r
- filter: Alpha(opacity=30);\r
-}\r
-\r
+}
+
+input, select, textarea, button {
+ font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif;
+ color: #464f52;
+}
+
+select {
+ padding: 0;
+ margin: 0;
+}
+
+.i-disabled {
+ opacity: 0.3;
+ filter: Alpha(opacity=30);
+}
+
+/**
+ * Layout styles
+ */
+
+.i-orderedlayout {
+ margin: 15px 18px;
+}
+
+/**
+ * Context menu styles
+ */
+
.i-contextmenu {
background: #e9eced;
font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif;
margin-right: 10px;
vertical-align: middle;
}
-\r
-/* Provide some extra whitespace for wrapped elements\r
- (these elements usuallly need the extra space, since \r
- they aren't even handling their own caption) */\r
-.i-captionwrapper {\r
- margin: 0.3em 0 0 0;\r
+
+/* Provide some extra whitespace for wrapped elements
+ (these elements usually need the extra space, since
+ they aren't even handling their own caption) */
+.i-captionwrapper {
+ margin: 0.3em 0 0 0;
}
+.i-datefield .i-button {\r
+ width: 22px;\r
+ height: 20px;\r
+ padding: 0;\r
+ overflow: hidden;\r
+ border: none;\r
+ background: transparent url(../icons/16/calendar.png) no-repeat 50% 50%;\r
+ text-indent: -90000px;\r
+}\r
.i-datefield-calendarpanel {\r
width: 22em;\r
}\r
.i-datefield-calendarpanel .i-button {\r
width: 22px;\r
height: 22px;\r
- font-size: 1.1em;\r
+ font-size: 0.9em;\r
padding: 0;\r
- line-height: 1em;\r
+ line-height: 0.9em;\r
}\r
.i-datefield-calendarpanel-month {\r
- font-size: 1.1em;\r
+ font-size: 1em;\r
}\r
.i-datefield-calendarpanel-day {\r
cursor: pointer;\r
padding: 5px;\r
background: #fff;\r
}\r
-.i-datefield-calendar:before {\r
- display: block;\r
- height: 2px;\r
- overflow: hidden;\r
- background: transparent url(../../panel/img/top-right-small.png) no-repeat right top;\r
- content: url(../../panel/img/top-left-small.png);\r
- margin: -6px -6px 3px -6px;\r
-}\r
-.i-datefield-calendar:after {\r
- display: block;\r
- height: 2px;\r
- overflow: hidden;\r
- background: transparent url(../../panel/img/bottom-right.png) no-repeat right top;\r
- content: url(../../panel/img/bottom-left.png);\r
- margin: 5px -6px -6px -6px;\r
-}\r
+\r
+\r
\r
.i-datefield-entrycalendar-hours {\r
height: 150px;\r
border-bottom: none;\r
background-color: #fff;\r
overflow: auto;\r
- padding: 15px 18px 6px 18px;\r
+ /*padding: 15px 18px 6px 18px;*/\r
}\r
\r
.i-panel-deco {\r
.i-tabsheet .i-panel-light .i-panel-caption {\r
border-left: none;\r
border-right: none;\r
- margin: -16px -18px 0 -18px;\r
+ /*margin: -16px -18px 0 -18px;*/\r
+ margin-top: -1px;\r
padding-top: 14px;\r
border-top: 1px solid #babfc0;\r
}\r
.i-panel .i-panel-light .i-panel-content,\r
.i-tabsheet .i-panel-light .i-panel-content {\r
- margin: 0 -18px 16px -18px;\r
+ /*margin: 0 -18px 16px -18px;*/\r
}\r
\r
\r
-.i-filterselect-suggestpopup {
- background: #fff;
- font-size:small;
+.i-filterselect {
+ height: 23px;
+ background: transparent url(img/bg-left-filter.png) no-repeat;
+ margin-right: 1px;
+ white-space: nowrap;
}
-.i-filterselect-suggestmenu .gwt-MenuItem {
- border: 1px solid black;
- border-width: 0 1px 1px 1px;
+.i-filterselect-input {
+ border: none;
+ background: transparent;
+ width: 97%;
+ height: 20px;
+ margin: 3px 0 0 4px;
+ padding: 0;
+ font-size: 13px;
}
-.i-filterselect-suggestmenu .gwt-MenuItem-selected {
- background: yellow;
+.i-filterselect-button {
+ float: right;
+ margin: -23px -1px 0 0;
+ width: 25px;
+ height: 23px;
+ cursor: pointer;
+ background: transparent url(img/bg-right-filter.png);
+ position: relative;
+}
+.i-filterselect-button:hover {
+ background-position: bottom left;
}
-.i-filterselect {
- white-space: nowrap;
+.i-filterselect-suggestpopup {
+ background: #f6f7f7;
+ border: 1px solid #b6bbbc;
+ font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif;
+ color: #464f52;
+ font-size: 12px;
+ line-height: 18px;
}
-.i-filterselect-button {
- display:inline;
- background:red;
+.i-filterselect-suggestmenu .gwt-MenuItem {
+ padding: 1px 5px;
+ cursor: pointer;
+}
+
+.i-filterselect-suggestmenu .gwt-MenuItem-selected {
+ background: #c6cccd;
+ color: #444d4e;
}
.i-filterselect-nextpage-on,
color: #666;
}
+
+
+
+/* IE specific styles */
+
+* html .i-filterselect {
+
+}
+* html .i-filterselect-input {
+ margin-top: 2px;
+}
+
+/* For some silly reason IE6 leaks some negative margins to the text input */
+* html .i-panel .i-panel-light .i-panel-content .i-filterselect-input,
+* html .i-tabsheet .i-panel-light .i-panel-content .i-filterselect-input {
+ margin-left: 22px;
+}
+*+html .i-filterselect-input {
+ margin-top: 1px;
+}
+* html .i-filterselect-button {
+ position: static;
+ display: inline;
+ margin-top: -24px;
+}
+*+html .i-filterselect-button {
+ position: static;
+}
+
overflow: hidden;
}
+.i-table.table-inline {
+ border-left: none;
+ border-right: none;
+ /*margin: -16px -18px 0 -18px;*/
+}
+
.i-table-header-wrap {
height: 36px;
background: #e7edf3 url(img/header-bg.png) repeat-x;
border-bottom: none;\r
background-color: #fff;\r
overflow: auto;\r
- padding: 15px 18px 6px 18px;\r
+ /*padding: 15px 18px 6px 18px;*/\r
}\r
\r
.i-tabsheet-deco {\r
.i-textfield {\r
- font-size: 1.1em;\r
- color: #444;\r
- background: #fff url(../img/bg.png) repeat-x;\r
+ background: #fff url(img/bg.png) repeat-x;\r
padding: 2px;\r
border: 1px solid #b6b6b6;\r
border-top-color: #9d9d9d;\r
}\r
\r
.i-textfield-focus {\r
- color: #111;\r
border-color: #4376c3;\r
border-bottom-color: #6696dd;\r
border-right-color: #6696dd;\r
public ExpandLayout() {
}
+
+ public ExpandLayout(int orientation) {
+ this();
+ setOrientation(orientation);
+ }
/**
* @param c
package com.itmill.toolkit.ui;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
-import com.itmill.toolkit.Application;
import com.itmill.toolkit.data.Container;
import com.itmill.toolkit.data.Item;
import com.itmill.toolkit.data.Property;
import com.itmill.toolkit.data.util.IndexedContainer;
-import com.itmill.toolkit.terminal.DownloadStream;
import com.itmill.toolkit.terminal.KeyMapper;
import com.itmill.toolkit.terminal.PaintException;
import com.itmill.toolkit.terminal.PaintTarget;
import com.itmill.toolkit.terminal.Resource;
-import com.itmill.toolkit.terminal.URIHandler;
import com.itmill.toolkit.ui.select.OptionFilter;
import com.itmill.toolkit.ui.select.StartsWithFilter;
private String filterstring;
+ /**
+ * How many visible columns (~characters) does select occupy visually.
+ * Used to size select appropriately. Minus one sets to 100% width.
+ */
+ private int columns = -1;
+
/* Constructors ********************************************************* */
/**
target.addAttribute("selectmode", "multi");
if (isNewItemsAllowed())
target.addAttribute("allownewitem", true);
+ if (getColumns() > -1)
+ target.addAttribute("cols", getColumns());
// Constructs selected keys array
String[] selectedKeys;
return optionFilter;
}
+ /**
+ * Set visible columns.
+ */
+ public void setColumns(int cols) {
+ this.columns = cols;
+ }
+
+ /**
+ * Get visible columns.
+ */
+ public int getColumns() {
+ return this.columns;
+ }
+
}