GWT.create 2013: Themeing GWT Applications with the Appearance Pattern

Post on 22-May-2015

2.209 views 0 download

Tags:

Transcript of GWT.create 2013: Themeing GWT Applications with the Appearance Pattern

Theming GWT Applications with the

Appearance Pattern Colin Alworth / Sencha Inc. colin.alworth@sencha.com

Three years ago Cell API and Appearance Pattern

Two years ago SenchaCon 2011, GXT 3 Preview released

Just over a year ago GXT 3.0.0 uses Cell API in Fields, Appearance

everywhere

Three main responsibilities !

• render initial content • update content based on changes, interaction • answer questions about rendered content

Theming GWTAppearance pattern

Examples

• render text, icon, decoration •update for changes •update for hover, focus, mousedown •find focus element, find menu element

Theming GWTButton Appearance

• render with value, options •update for value, options •update for empty, focus, value •find focus element

Theming GWTText Field

• render static content •update to hide/show header, collapse/expand panel

•ask for icons on buttons, elements to hold title, tools, body, buttons

Theming GWTPanel

•appearance controls rendered html •widget deals with all logic •appearance implementation can choose to use or ignore state changes

Theming GWTAppearance contract

•ColorPalette/DatePicker - widget needs to know relative positions of items

•Grid/Tree - needs to guarantee fast creation/lookups

Theming GWTAppearance contract - exceptions

Implementations should be stateless: !•Ensures that appearances will behave for cells •Enables compiler to rewrite methods to static, inline into owning widget if possible !

Theming GWTAppearance contract

• Widgets should invoke GWT.create on the appearance interface

• Module files can declare replace-with rules to specify an implementation !!

Theming GWTConstructing appearances

<replace-with class="com.sencha.gxt...NeptuneInfoAppearance"> <when-type-is class="com.sencha.gxt...Info.InfoAppearance" /> </replace-with> !!

Theming GWTModule rules

<replace-with class="com.sencha.gxt...NeptuneInfoAppearance"> <when-type-is class="com.sencha.gxt...Info.InfoAppearance" /> <when-property-is name="gxt.theme" value="neptune" /> </replace-with> !!

Theming GWTMultiple themes in one app?

•Widgets should expose an appearance constructor •Enables individual cases to use a custom appearance

•Widget’s appearance field should be private/final •Avoids issues with changing appearance without changing dom structure

•Widgets should expose an appearance getter for subclasses !!

Theming GWTGeneral API tips

•Helpful have default appearance implementations that are easy to extend, changing minor details like styles

•Appearances shouldn’t use generics, since they are created by GWT.create, lose any typesafety !!

Theming GWTGeneral API tips

• render method - SafeHtmlBuilder or SafeHtml, either XTemplates, SafeHtmlTemplates, or hand-written Java !<div class='{style.infoWrap}'> <div class='{style.info}'></div> </div> !public void render(SafeHtmlBuilder sb) { sb.append(template.render(styles)); } !!

Theming GWTImplementing appearances

• find, update methods based on that structure !@Override public Element getContentElement(Element parent) { return parent.getFirstChildElement(); } !!

Theming GWTImplementing appearances

•Declare a default constructor (for GWT.create and replace-with)

• If it makes sense, ensure type can be extended !!

Theming GWTImplementing appearances

•consistent set of appearances •defined as a module made of of replace-with declarations

• in GXT 3.1 comes with a gxt.theme property for permutation switching of themes !!

Theming GWTComposing a theme

Automating theme generation

•Early GXT 3 tried few constants in one file, CssResource to reference these in all appearances

•Works when no images need to be created... !!

Theming GWTAutomating theme generation

Base it on •CSS3 gradients •CSS3 rounded corners •SVG vector images •Starts us with a language we already know (rather than inventing new)

•Enables us to use CSS3 right away (in browsers that support it) !!!

Theming GWTLegacy browser image generation

Info Example

Info.display("Hello world","Testing info popup");

Theming GWT

<div class='{style.infoWrap}'>! <div class='{style.info}'></div>!</div>!.infoWrap {! border-style: none;! border-radius: 8px;! background-color: #000000;! opacity: .8;! margin: 2px 0 0 0;!}!.info {! padding: 10px;!}!!

Theming GWTCSS3 html and css

Theming GWTSlicing Corners

Theming GWTSlicing Edges

<div class="{style.contentArea}"> <div class="{style.content}"> <div class="{style.info}"> </div> </div> <div class="{style.topLeft}"></div> <div class="{style.top}"></div> <div class="{style.topRight}"></div> <div class="{style.bottomLeft}"></div> <div class="{style.bottom}"></div> <div class="{style.bottomRight}"></div> <div class="{style.left}"></div> <div class="{style.right}"></div> </div>

Theming GWTLegacy 9-box html

TabPanel Example !

Theming GWTTabPanelExample

Theming GWTTabPanelExample

Theming GWTTabPanelExample

•start with a CSS3 implementation, render in a browser

•specify images that need images •collect from browser positions, borders, corner radius, gradient direction

•decide which images - background, corners, sides •decide which images to stretch •take a screenshot •slice images from screenshot based on positions !

Theming GWTAutomating image generation

Theming GWT

• takes about 5 seconds, most of which is starting browser and launching sample page !

Theming GWTAutomating image generation

•CSS3 can be transformed to images • images + legacy css used for older browsers

•HTML structure different as well •nothing common except for a few values, sizes - where do we store those?

Theming GWTBack to theme generation

theme {! name = "themeName"! basePackage = "com.company.theme"! ! details {! panel {! }! tabs {! }! //...! }!}!!

Theming GWTTheme config

theme {! details {! info {! backgroundColor = "#ffffff"! borderRadius = 8! opacity = 1.0! border = util.border('solid', '#cccccc', 2)! headerText = util.fontStyle("Tahoma, Arial, Verdana, sans-serif", '15px', '#555555', 'bold');! messageText = util.fontStyle("Tahoma, Arial, Verdana, sans-serif", '14px', '#555555');! margin = util.margins(2,0,0,0)! padding = util.padding(2,7)! }! }!}!!!

Theming GWTTheme config

•namespaced properties for easier organization

•values can be string, int, double •some expressions supported •values can be referenced by path •basic set of util methods

Theming GWTTheme config

$ bin/themer.sh !Command missing config files!usage: ThemeBuilder [options] [config ...]! -f,--force force output overwrite! -gen <path> directory to generate code to! -generateConfig <outputFile> Generate sample configuration! -h,--help print this message! -imageFile <path> captured image used for slicing images! -manifestFile <manifestFile> json manifest file of the captured image! -out <jar> path to jar file to generate. Default is! a jar named <theme.name>.jar in the! current directory! -warDir <warDir> directory to compile the css3-based theme! to before images are sliced from it!!

Theming GWTRunning the themed

$ themebuilder/bin/themer.sh themebuilder/examples/quick-start/quick-start.theme!template generation started!template generation complete!image generation started!generating tool icons!!...!!slice complete!packaging started!packaging complete!!

Theming GWTExample config

•quick-start.theme •skeleton-config.theme •maven-jar/ •maven-source/

Theming GWTIncluded samples