xworker.swt.design.Designer Maven / Gradle / Ivy
/*******************************************************************************
* Copyright 2007-2013 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package xworker.swt.design;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmeta.ActionContext;
import org.xmeta.Thing;
import org.xmeta.World;
import xworker.swt.ActionContainer;
/**
* SWT设计器。
*
* 如果创建控件的事物的create方法使用了设计器的attach绑定控件,那么改控件可以是设计状态,
* 当一个控件是设计状态时,使用鼠标中键可以选择控件,并通过鼠标中键的双击打开设计菜单。
*
* @author zyx
*
*/
public class Designer {
private static Logger log = LoggerFactory.getLogger(Designer.class);
public static final String DATA_THING = "_designer_thingPath";
public static final String DATA_ACTIONCONTEXT = "_designer_actionContext";
public static final String DATA_ISATTRIBUTE = "_designer_isAttribute";
public static final String DATA_DESING_SELECTED = "_design_selected";
public static final String DATA_MARKED = "__design_marked__";
public static final String DATA_MARKED_PAINTED = "__design_marked__painted";
public static final String DATA_RESIZE_TYPE = "__design_resize__type__";
public static final String DATA_RESIZEING = "__design_resizeing__";
public static final String TRUE = "true";
public static final String FALSE = "false";
private static ActionContainer explorerActions = null;
private static Display explorerDisplay = null;
private static boolean enabled = false;
private static boolean designEditMode = false;
/** SWT控件Attach时如果大于0,那么先sleep,为测试用 */
private static long attachSleepTime = 0;
private static DesignListener listener = new DesignListener();
private static Map> controlMap = new HashMap>();
private static List markedControls = new ArrayList();
/** 标记提示的窗口 */
private static Shell markTooltipShell = null;
private static final byte BOTTOM = 1;
private static final byte UP = 2;
private static final byte RIGHT = 3;
private static final byte LEFT = 4;
private static Thread markControlThread = new Thread( new Runnable(){
public void run(){
while(true){
try{
synchronized(markedControls){
for(int i=0;i ctls = controlMap.get(thingPath);
if(ctls == null){
ctls = new ArrayList();
controlMap.put(thingPath, ctls);
}
boolean have = false; //避免重复插入,虽然应该不可能
synchronized(ctls){
for(int i=0; i < ctls.size(); i++){
if(ctls.get(i) == control){
have = true;
break;
}
}
if(!have){
ctls.add(control);
}
}
if(Designer.attachSleepTime > 0){
control.getShell().layout();
if(control.getParent() != null){
control.getParent().layout();
}
Thread.sleep(Designer.attachSleepTime);
}
}catch(Throwable t){
log.error("attach " + thingPath, t);
}
}
/**
* 标记控件。
*
* @param control
*/
public static void markControl(final Control control){
control.getDisplay().asyncExec(new Runnable(){
public void run(){
control.setData(Designer.DATA_MARKED, Designer.TRUE);
redraw(control);
synchronized(markedControls){
markedControls.add(control);
}
}
});
}
public static void redraw(final Control control){
if(control != null && !control.isDisposed()){
control.getDisplay().asyncExec(new Runnable(){
public void run(){
control.redraw();
}
});
}
}
/**
* 取消标记控件。
*
* @param control
*/
public static void unmarkControl(final Control control){
control.getDisplay().asyncExec(new Runnable(){
public void run(){
control.setData(Designer.DATA_MARKED, null);
redraw(control);
synchronized(markedControls){
markedControls.remove(control);
}
}
});
}
/**
* 解除绑定,在控件销毁时解除。
*
* @param control
*/
protected static void detach(Widget control){
String thingPath = (String) control.getData(DATA_THING);
//ActionContext actionContext = (ActionContext) control.getData("_designer_actionContext");
if(thingPath != null){
List ctls = controlMap.get(thingPath);
if(ctls != null){
synchronized(ctls){
for(int i=0; i < ctls.size(); i++){
if(ctls.get(i) == control){
ctls.remove(i);
i--;
//break;
}
}
}
}
}
}
/**
* 返回当前编辑器中的指定的控件列表。
*
* @param controlPaths
* @return
*/
public static Map> getControlsInCurrentEditor(List controlPaths){
Control currentEditor = getActiveEditorRootControl();
if(currentEditor == null){
return null;
}
return getControlsInSameParnet(controlPaths, currentEditor);
}
/**
* 返回编辑器区域内所有编辑器的列表,通常是TabItem或CTabItem。
*
* @return
*/
@SuppressWarnings("unchecked")
public static List getAllEditorRootControls(){
if(explorerActions != null){
return (List) explorerActions.doAction("getActiveEditorRootControl");
}
return null;
}
/**
* 获取编辑器列表中激活的那个编辑器。
*
* @return
*/
public static Control getActiveEditorRootControl(){
if(explorerActions != null){
return (Control) explorerActions.doAction("getActiveEditorRootControl");
}
return null;
}
/**
* 获取指定路径的控件列表,并且这些控件都属于指定的父控件。
*
* @param controlPaths
* @param parent
* @return
*/
public static Map> getControlsInSameParnet(List controlPaths, Control parent){
if(controlPaths == null || controlPaths.size() == 0){
return null;
}
Map> controls = new HashMap>();
for(String path : controlPaths){
//根据控件路径查找控件
List widgets = controlMap.get(path);
if(widgets != null){
for(int i=0; i clist = controls.get(path);
if(clist == null){
clist = new ArrayList();
controls.put(path, clist);
}
clist.add(control);
}
}
}
}
}
return controls;
}
private static boolean isSameParent(Control control, Control parent){
Control theParent = control;
while(theParent != null){
if(theParent == parent){
return true;
}
theParent = theParent.getParent();
}
return false;
}
/**
* 返回创建控件的事物路径。
*
* @param control
* @return
*/
public static String getControlThingPath(Control control){
return (String) control.getData(Designer.DATA_THING);
}
/**
* 从一个父Control开始寻找对应指定事物的控件,一般该控件是由这个事物创建的。
*
* @param control
* @param thingPath
* @return
*/
public static Control findControl(Control control, String thingPath){
String cpath = getControlThingPath(control);
if(cpath != null && cpath.equals(thingPath)){
return control;
}
if(control instanceof Composite){
Composite composite = (Composite) control;
for(Control child : composite.getChildren()){
Control c = findControl(child, thingPath);
if(c != null){
return c;
}
}
}
return null;
}
/**
* 获取属于同一个shell的控件集合,可能或返回多个集合,值返回全部空间都同时存在的集合。
*
* @param controlPaths
* @return
*/
public static List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy