/******************************************************************************* * Copyright (c) 2008 Angelo Zerr and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation *******************************************************************************/ package org.akrogen.tkui.css.swt.examples.csseditors; import java.io.File; import java.util.ArrayList; import org.akrogen.tkui.css.core.css2.CSS2FontPropertiesHelpers; import org.akrogen.tkui.css.core.dom.IElementProvider; import org.akrogen.tkui.css.core.dom.properties.css2.CSS2FontProperties; import org.akrogen.tkui.css.core.engine.CSSEngine; import org.akrogen.tkui.css.core.examples.csseditors.AbstractCSSEditor; import org.akrogen.tkui.css.core.serializers.CSSSerializerConfiguration; import org.akrogen.tkui.css.swt.dom.SWTElementProvider; import org.akrogen.tkui.css.swt.dom.html.SWTHTMLElementProvider; import org.akrogen.tkui.css.swt.engine.CSSSWTEngineImpl; import org.akrogen.tkui.css.swt.serializers.CSSSWTSerializerConfiguration; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.ColorDialog; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.FontDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.w3c.dom.css.CSSValue; /** * Abstract CSS SWT Editor. * * @version 1.0.0 * @author <a href="mailto:angelo.zerr@gmail.com">Angelo ZERR</a> * */ public abstract class AbstractCSSSWTEditor extends AbstractCSSEditor { protected static final String[] CSS_FILE_EXTENSION = { "*.css" }; private Display display; /** * Textarea wich contains content of CSS style sheet. */ private StyledText textArea; private Button cacheResourcesCheckbox; /** * HTML checkbox to set if CSS must be typed with HTML syntaxe or SWT * syntax. */ private Button htmlCheckbox; /** * Label wich display time elapsed when CSS Engine apply styles. */ private Label statusLabel; /** * Apply style when text area change */ private Button applyStyleWhenTextAreaChangeCheckbox; /** * Launch Apply style */ private Button applyStyleToShellCheckbox; private Shell shell; private Composite leftPanel; private List cssFilesWidget; private java.util.List cssFiles = new ArrayList(); private Text selectedCSSPropertyNameText = null; private Text selectedCSSPropertyValueText = null; protected int currentLine = -1; protected AbstractCSSSWTEditor(String nativeWidgetDir, String[] styleFileExtension) { super(nativeWidgetDir); } protected AbstractCSSSWTEditor() { super("swt"); } public void display() { display = new Display(); shell = new Shell(display, SWT.SHELL_TRIM); GridLayout layout = new GridLayout(); layout.marginWidth = 0; layout.marginHeight = 0; layout.verticalSpacing = 3; shell.setLayout(layout); // create Menus createMenus(shell); /* * Create a sash form. */ SashForm form = new SashForm(shell, SWT.NONE); form.setLayoutData(new GridData(GridData.FILL_BOTH)); /* * Create left panel with SWT Contents. */ createLeftPanel(form); /* * Create right panel with TextArea which contains CSS to load. */ createRightPanel(form); form.setWeights(new int[] { 30, 80 }); /* * Now we open the shell. */ shell.setSize(new Point(800, 600)); shell.open(); shell.setText("CSS Editors"); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } /*-------------------- Menus --------------------**/ /** * Create Menus File, Options * * @param shell */ protected void createMenus(Shell shell) { Menu menu = new Menu(shell, SWT.BAR); shell.setMenuBar(menu); // Create File item Menu createMenuItemFile(menu, shell); // Create Options item Menu // createMenuItemOptions(menu); } /** * Create Menu item File with sub menu New and Open * * @param menu * @param shell */ protected void createMenuItemFile(Menu menu, final Shell shell) { MenuItem menuFileHeader = new MenuItem(menu, SWT.CASCADE); menuFileHeader.setText("&File"); // File menu Menu menuFile = new Menu(shell, SWT.DROP_DOWN); menuFileHeader.setMenu(menuFile); // New item menu MenuItem itemNew = new MenuItem(menuFile, SWT.PUSH); itemNew.setText("&New..."); itemNew.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { fillTextareaWithDefaultStyleSheetContent(); } }); // Open item menu MenuItem itemOpen = new MenuItem(menuFile, SWT.PUSH); itemOpen.setText("&Open..."); itemOpen.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { FileDialog dialog = new FileDialog(shell, SWT.NULL); dialog.setFilterExtensions(CSS_FILE_EXTENSION); dialog.setText("Select CSS style file"); dialog.setFilterPath(getBaseStyleDir().getAbsolutePath()); String path = dialog.open(); if (path != null) { File file = new File(path); fillTextareaWithStyleSheetContent(file); } } }); } /** * Create Menu item Options * * @param menu */ protected void createMenuItemOptions(Menu menu) { MenuItem menuOptionsHeader = new MenuItem(menu, SWT.CASCADE); menuOptionsHeader.setText("&Options"); // Options menu Menu menuOptions = new Menu(shell, SWT.DROP_DOWN); menuOptionsHeader.setMenu(menuOptions); // New item menu MenuItem itemNew = new MenuItem(menuOptions, SWT.CHECK); itemNew.setText("&Cache Resource..."); } /*-------------------- Panel --------------------**/ protected void createLeftPanel(Composite parent) { leftPanel = new Composite(parent, SWT.NONE); leftPanel.setLayout(new FillLayout()); createContent(leftPanel); } protected void createRightPanel(Composite parent) { SashForm form = new SashForm(parent, SWT.NONE); form.setLayoutData(new GridData(GridData.FILL_BOTH)); GridLayout layout = new GridLayout(); layout.marginWidth = 0; layout.marginHeight = 0; layout.verticalSpacing = 3; Composite composite = new Composite(form, SWT.NONE); composite.setLayout(layout); statusLabel = new Label(composite, SWT.NONE); statusLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); // Create TextArea which contains CSS content. textArea = new StyledText(composite, SWT.MULTI | SWT.V_SCROLL | SWT.BORDER); textArea.setLayoutData(new GridData(GridData.FILL_BOTH)); textArea.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { if (applyStyleWhenTextAreaChangeCheckbox.getSelection()) applyStyles(); } }); textArea.addKeyListener(new KeyAdapter() { public void keyReleased(KeyEvent e) { displaySelectedCSSProperty(); } }); textArea.addMouseListener(new MouseAdapter() { public void mouseDown(MouseEvent e) { displaySelectedCSSProperty(); } }); layout = new GridLayout(); layout.marginWidth = 0; layout.marginHeight = 0; layout.verticalSpacing = 3; composite = new Composite(form, SWT.NONE); composite.setLayout(layout); Group group = new Group(composite, SWT.NONE); group.setText("Selected CSS Property"); layout = new GridLayout(2, true); layout.verticalSpacing = 3; group.setLayout(layout); group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Label label = new Label(group, SWT.NONE); label.setText("CSS Property name"); selectedCSSPropertyNameText = new Text(group, SWT.BORDER | SWT.READ_ONLY); selectedCSSPropertyNameText.setLayoutData(new GridData( GridData.FILL_HORIZONTAL)); label = new Label(group, SWT.NONE); label.setText("CSS Property value"); selectedCSSPropertyValueText = new Text(group, SWT.BORDER); selectedCSSPropertyValueText.setLayoutData(new GridData( GridData.FILL_HORIZONTAL)); selectedCSSPropertyValueText.addKeyListener(new KeyAdapter() { public void keyReleased(KeyEvent e) { String property = selectedCSSPropertyNameText.getText(); property += ":"; property += selectedCSSPropertyValueText.getText(); updateSelectedCSSPropertyValue(property); } }); final Button b = new Button(group, SWT.PUSH | SWT.BORDER); b.setText("Change Color"); b.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { ColorDialog colorDialog = new ColorDialog(shell); colorDialog.setText("ColorDialog Demo"); String cssValue = selectedCSSPropertyValueText.getText(); if (cssValue != null && cssValue.length() > 0) { try { CSSValue value = engine.parsePropertyValue(cssValue); RGB rgb = (RGB) engine.convert(value, RGB.class, null); if (rgb != null) colorDialog.setRGB(rgb); } catch (Exception ex) { handleExceptions(ex); } // engine.convert(, RGB.class,); } RGB newColor = colorDialog.open(); if (newColor != null) { try { cssValue = engine.convert(newColor, RGB.class, selectedCSSPropertyNameText.getText()); if (cssValue == null) return; selectedCSSPropertyValueText.setText(cssValue); String property = selectedCSSPropertyNameText.getText(); property += ":"; property += selectedCSSPropertyValueText.getText(); updateSelectedCSSPropertyValue(property); } catch (Exception ex) { handleExceptions(ex); } } } }); final Button b2 = new Button(group, SWT.PUSH | SWT.BORDER); b2.setText("Change Font"); b2.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { FontDialog fontDialog = new FontDialog(shell); fontDialog.setText("Choose the font"); String value = selectedCSSPropertyValueText.getText(); try { String propertyName = selectedCSSPropertyNameText.getText(); CSSValue cssValue = engine.parsePropertyValue(value); CSS2FontProperties fontProperties = CSS2FontPropertiesHelpers .createCSS2FontProperties(cssValue, propertyName); FontData fontData = (FontData) engine.convert(fontProperties, FontData.class, display); if (fontData != null) { FontData[] fontDatas = { fontData }; fontDialog.setFontList(fontDatas); } } catch (Exception ex) { handleExceptions(ex); } FontData newFontData = fontDialog.open(); if (newFontData != null) { try { String cssValue = engine.convert(newFontData, FontData.class, selectedCSSPropertyNameText .getText()); if (cssValue == null) return; selectedCSSPropertyValueText.setText(cssValue); String property = selectedCSSPropertyNameText.getText(); property += ":"; property += selectedCSSPropertyValueText.getText(); updateSelectedCSSPropertyValue(property); } catch (Exception ex) { handleExceptions(ex); } } } }); group = new Group(composite, SWT.NONE); group.setText("CSS Engine options"); layout = new GridLayout(); layout.verticalSpacing = 3; group.setLayout(layout); group.setLayoutData(new GridData(GridData.FILL_BOTH)); cacheResourcesCheckbox = new Button(group, SWT.CHECK); cacheResourcesCheckbox.setText("Cache Color, Font and Cursor"); cacheResourcesCheckbox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { if (!cacheResourcesCheckbox.getSelection()) { engine.getResourcesRegistry().dispose(); } } }); cacheResourcesCheckbox.setSelection(true); applyStyleWhenTextAreaChangeCheckbox = new Button(group, SWT.CHECK); applyStyleWhenTextAreaChangeCheckbox .setText("Apply style when textarea change"); applyStyleWhenTextAreaChangeCheckbox.setSelection(true); htmlCheckbox = new Button(group, SWT.CHECK); htmlCheckbox.setText("is HTML Selector? (otherwise it's SWT Selector)"); htmlCheckbox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { populateCSSFiles(); applyStylesFromSelectedFile(); } }); // Create CSS files list cssFilesWidget = new List(group, SWT.NONE); cssFilesWidget.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); cssFilesWidget.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { applyStylesFromSelectedFile(); } }); populateCSSFiles(); // Create Apply Style Button. applyStyleToShellCheckbox = new Button(group, SWT.CHECK); applyStyleToShellCheckbox.setText("Apply sytle to fully Shell?"); applyStyleToShellCheckbox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { if (applyStyleToShellCheckbox.getSelection()) { applyStyles(); } else { // Apply styles with NONE style to reset // styles applied into TextArea... engine = getCSSEngine(); engine.applyStyles(shell, true); // Apply styles applyStyles(); } } }); Button applyStyleButton = new Button(group, SWT.BORDER); applyStyleButton.setText("Apply style"); applyStyleButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { applyStyles(); } }); form.setWeights(new int[] { 120, 90 }); // Select the first CSS style file applyStylesFromSelectedFile(); } public abstract void createContent(Composite parent); protected void displaySelectedCSSProperty() { selectedCSSPropertyNameText.setText(""); selectedCSSPropertyValueText.setText(""); int start = -1; int end = -1; // if (currentLine != -1) // textArea.setLineBackground(currentLine, 1, null); currentLine = textArea.getLineAtOffset(textArea.getCaretOffset()); if (currentLine + 1 >= textArea.getLineCount()) return; start = textArea.getOffsetAtLine(currentLine); end = textArea.getOffsetAtLine(currentLine + 1) - 2; if (start <= end) { String lineText = textArea.getText(start, end); lineText = lineText.trim(); int index = lineText.indexOf(":"); if (index > 0) { if (lineText.indexOf("{") != -1) return; String property = lineText.substring(0, index); String value = lineText.substring(index + 1, lineText.length()); value = value.replaceAll(";", ""); // Remove comment int commentIndex = value.indexOf("/*"); if (commentIndex > 0) value = value.substring(0, commentIndex); selectedCSSPropertyNameText.setText(property); selectedCSSPropertyValueText.setText(value); // textArea.setLineBackground(currentLine, 1, display // .getSystemColor(SWT.COLOR_MAGENTA)); } } } protected void updateSelectedCSSPropertyValue(String text) { if (currentLine != -1 && currentLine + 1 >= textArea.getLineCount()) return; int start = textArea.getOffsetAtLine(currentLine); int end = textArea.getOffsetAtLine(currentLine + 1) - 2; String startLineText = textArea.getText(0, start); String endLineText = textArea.getText(end, textArea.getCharCount() - 1); if (!text.endsWith(";") && !endLineText.startsWith(";")) text += ";"; if (endLineText.startsWith(":")) endLineText.substring(1, endLineText.length()); String newContent = startLineText + text + endLineText; textArea.setText(newContent); } /*-------------------- AbstractCSSEditor methods implementation --------------------**/ /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#createCSSEngine() */ protected CSSEngine createCSSEngine() { return new CSSSWTEngineImpl(shell.getDisplay()); } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#getHTMLElementProvider() */ protected IElementProvider getHTMLElementProvider() { return SWTHTMLElementProvider.INSTANCE; } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#getNativeWidgetElementProvider() */ protected IElementProvider getNativeWidgetElementProvider() { return SWTElementProvider.INSTANCE; } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#isHTMLSelector() */ protected boolean isHTMLSelector() { return htmlCheckbox.getSelection(); } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#getStyleSheetContent() */ protected String getStyleSheetContent() { return textArea.getText(); } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#setStyleSheetContent(java.lang.String) */ protected void setStyleSheetContent(String content) { textArea.setText(content); } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#setCSSEngineStatuts(java.lang.String) */ protected void setCSSEngineStatuts(String status) { statusLabel.setText(status); } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#mustApplyStylesToWindow() */ protected boolean mustApplyStylesToWindow() { return applyStyleToShellCheckbox.getSelection(); } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#getLeftPanelNativeWidget() */ protected Object getLeftPanelNativeWidget() { return leftPanel; } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#getWindowNativeWidget() */ protected Object getWindowNativeWidget() { return shell; } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#getCSSNativeWidgetSerializerConfiguration() */ protected CSSSerializerConfiguration getCSSNativeWidgetSerializerConfiguration() { return CSSSWTSerializerConfiguration.INSTANCE; } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#getCSSFileWidgetItemCount() */ protected int getCSSFilesWidgetItemCount() { return cssFilesWidget.getItemCount(); } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#getCSSFileWidgetSelectionIndex() */ protected int getCSSFilesWidgetSelectionIndex() { return cssFilesWidget.getSelectionIndex(); } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#selectCSSFileWidget(int) */ protected void selectCSSFilesWidget(int index) { cssFilesWidget.select(index); } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#addCSSFilesWidget(java.lang.String) */ protected void addItemCSSFilesWidget(String item) { cssFilesWidget.add(item); } /* * (non-Javadoc) * * @see org.akrogen.tkui.core.css.examples.csseditors.AbstractCSSEditor#removeAllCSSFilesWidget() */ protected void removeAllCSSFilesWidget() { cssFilesWidget.removeAll(); } }