package org.ripple.power.ui.projector.core.graphics; import java.awt.event.MouseEvent; import java.util.ArrayList; import org.ripple.power.ui.graphics.LGraphics; import org.ripple.power.ui.projector.core.LInput; import org.ripple.power.ui.projector.core.LRelease; import org.ripple.power.ui.projector.core.graphics.component.LPanel; public class Desktop implements LRelease { // 空桌面布局 public static final Desktop EMPTY_DESKTOP = new Desktop(); // 输入设备监听 protected final LInput input; private LContainer contentPane; private LComponent modal; private LComponent hoverComponent; private LComponent selectedComponent; private LComponent[] clickComponent = new LComponent[1]; /** * 构造一个可用桌面 * * @param input * @param width * @param height */ public Desktop(LInput input, int width, int height) { this.contentPane = new LPanel(0, 0, width, height); this.input = input; this.setDesktop(this.contentPane); } /** * 空桌面布局 * */ private Desktop() { this.contentPane = new LPanel(0, 0, 1, 1); this.input = null; this.setDesktop(this.contentPane); } public int size() { return contentPane.getComponentCount(); } public void add(LComponent comp) { if (comp == null) { return; } if (comp.isFull) { this.input.setRepaintMode(Screen.SCREEN_NOT_REPAINT); } this.contentPane.add(comp); this.processTouchMotionEvent(); } public int remove(LComponent comp) { int removed = this.removeComponent(this.contentPane, comp); if (removed != -1) { this.processTouchMotionEvent(); } return removed; } public int remove(Class<? extends LComponent> clazz) { int removed = this.removeComponent(this.contentPane, clazz); if (removed != -1) { this.processTouchMotionEvent(); } return removed; } private int removeComponent(LContainer container, LComponent comp) { int removed = container.remove(comp); LComponent[] components = container.getComponents(); int i = 0; while (removed == -1 && i < components.length - 1) { if (components[i].isContainer()) { removed = this .removeComponent((LContainer) components[i], comp); } i++; } return removed; } private int removeComponent(LContainer container, Class<? extends LComponent> clazz) { int removed = container.remove(clazz); LComponent[] components = container.getComponents(); int i = 0; while (removed == -1 && i < components.length - 1) { if (components[i].isContainer()) { removed = this.removeComponent((LContainer) components[i], clazz); } i++; } return removed; } boolean isClicked; /** * 刷新当前桌面 * */ public void update(long timer) { if (!this.contentPane.isVisible()) { return; } this.processEvents(); // 刷新桌面中子容器组件 this.contentPane.update(timer); } public void doClick(int x, int y) { if (!this.contentPane.isVisible()) { return; } LComponent[] components = contentPane.getComponents(); for (int i = 0; i < components.length; i++) { LComponent component = components[i]; if (component != null && component.intersects(x, y)) { component.update(0); component.processTouchPressed(); } } isClicked = true; } public void doClicked(int x, int y) { if (!this.contentPane.isVisible()) { return; } LComponent[] components = contentPane.getComponents(); for (int i = 0; i < components.length; i++) { LComponent component = components[i]; if (component != null && component.intersects(x, y)) { component.update(0); component.processTouchReleased(); component.processTouchClicked(); } } isClicked = true; } public void createUI(LGraphics g) { this.contentPane.createUI(g); } /** * 事件监听 * */ private void processEvents() { // 鼠标滑动 this.processTouchMotionEvent(); // 鼠标事件 if (this.hoverComponent != null && this.hoverComponent.isEnabled()) { this.processTouchEvent(); } // 键盘事件 if (this.selectedComponent != null && this.selectedComponent.isEnabled()) { this.processKeyEvent(); } } /** * 鼠标运动事件 * */ private void processTouchMotionEvent() { if ((this.hoverComponent != null && this.hoverComponent.isEnabled()) && this.input.isMoving()) { if (this.input.getTouchDX() != 0 || this.input.getTouchDY() != 0) { this.hoverComponent.processTouchDragged(); } } else { // 获得当前窗体下鼠标坐标 LComponent comp = this.findComponent(this.input.getTouchX(), this.input.getTouchY()); if (comp != null) { if (this.input.getTouchDX() != 0 || this.input.getTouchDY() != 0) { comp.processTouchMoved(); } if (this.hoverComponent == null) { comp.processTouchEntered(); } else if (comp != this.hoverComponent) { this.hoverComponent.processTouchExited(); comp.processTouchEntered(); } } else { if (this.hoverComponent != null) { this.hoverComponent.processTouchExited(); } } this.hoverComponent = comp; } } /** * 鼠标按下事件 * */ private void processTouchEvent() { int pressed = this.input.getTouchPressed(), released = this.input .getTouchReleased(); if (pressed > LInput.NO_BUTTON) { if (!isClicked) { this.hoverComponent.processTouchPressed(); } this.clickComponent[0] = this.hoverComponent; if (this.hoverComponent.isFocusable()) { if (pressed == MouseEvent.BUTTON1 && this.hoverComponent != this.selectedComponent) { this.selectComponent(this.hoverComponent); } } } if (released > LInput.NO_BUTTON) { if (!isClicked) { this.hoverComponent.processTouchReleased(); // 当释放鼠标时,点击事件生效 if (this.clickComponent[0] == this.hoverComponent) { this.hoverComponent.processTouchClicked(); } } } this.isClicked = false; } /** * 触发键盘事件 * */ private void processKeyEvent() { if (this.input.getKeyPressed() != LInput.NO_KEY) { this.selectedComponent.keyPressed(); } if (this.input.getKeyReleased() != LInput.NO_KEY && this.selectedComponent != null) { this.selectedComponent.processKeyReleased(); } } /** * 查找指定坐标点成员 * * @param x * @param y * @return */ private LComponent findComponent(int x, int y) { if (this.modal != null && !this.modal.isContainer()) { return null; } // 返回子容器 LContainer panel = (this.modal == null) ? this.contentPane : ((LContainer) this.modal); LComponent comp = panel.findComponent(x, y); return comp; } /** * 清除容器焦点 */ public void clearFocus() { this.deselectComponent(); } void deselectComponent() { if (this.selectedComponent == null) { return; } this.selectedComponent.setSelected(false); this.selectedComponent = null; } /** * 查找指定容器 * * @param comp * @return */ boolean selectComponent(LComponent comp) { if (!comp.isVisible() || !comp.isEnabled() || !comp.isFocusable()) { return false; } // 清除最后部分 this.deselectComponent(); // 设定选中状态 comp.setSelected(true); this.selectedComponent = comp; return true; } void setDesktop(LComponent comp) { if (comp.isContainer()) { LComponent[] child = ((LContainer) comp).getComponents(); for (int i = 0; i < child.length; i++) { this.setDesktop(child[i]); } } comp.setDesktop(this); } void setComponentStat(LComponent comp, boolean active) { if (this == Desktop.EMPTY_DESKTOP) { return; } if (active == false) { if (this.hoverComponent == comp) { this.processTouchMotionEvent(); } if (this.selectedComponent == comp) { this.deselectComponent(); } this.clickComponent[0] = null; if (this.modal == comp) { this.modal = null; } } else { this.processTouchMotionEvent(); } if (comp.isContainer()) { LComponent[] components = ((LContainer) comp).getComponents(); int size = ((LContainer) comp).getComponentCount(); for (int i = 0; i < size; i++) { this.setComponentStat(components[i], active); } } } void clearComponentsStat(LComponent[] comp) { if (this == Desktop.EMPTY_DESKTOP) { return; } boolean checkTouchMotion = false; for (int i = 0; i < comp.length; i++) { if (this.hoverComponent == comp[i]) { checkTouchMotion = true; } if (this.selectedComponent == comp[i]) { this.deselectComponent(); } this.clickComponent[0] = null; } if (checkTouchMotion) { this.processTouchMotionEvent(); } } public void validateUI() { this.validateContainer(this.contentPane); } final void validateContainer(LContainer container) { LComponent[] components = container.getComponents(); int size = container.getComponentCount(); for (int i = 0; i < size; i++) { if (components[i].isContainer()) { this.validateContainer((LContainer) components[i]); } } } public ArrayList<LComponent> getComponents(Class<? extends LComponent> clazz) { if (clazz == null) { return null; } LComponent[] components = contentPane.getComponents(); int size = components.length; ArrayList<LComponent> l = new ArrayList<LComponent>(size); for (int i = size; i > 0; i--) { LComponent comp = (LComponent) components[i - 1]; Class<? extends LComponent> cls = comp.getClass(); if (clazz == null || clazz == cls || clazz.isInstance(comp) || clazz.equals(cls)) { l.add(comp); } } return l; } public LComponent getTopComponent() { LComponent[] components = contentPane.getComponents(); int size = components.length; if (size > 1) { return components[1]; } return null; } public LComponent getBottomComponent() { LComponent[] components = contentPane.getComponents(); int size = components.length; if (size > 0) { return components[size - 1]; } return null; } public int getWidth() { return this.contentPane.getWidth(); } public int getHeight() { return this.contentPane.getHeight(); } public void setSize(int w, int h) { this.contentPane.setSize(w, h); } public LContainer getContentPane() { return this.contentPane; } public void setContentPane(LContainer pane) { pane.setBounds(0, 0, this.getWidth(), this.getHeight()); this.contentPane = pane; this.setDesktop(this.contentPane); } public LComponent getHoverComponent() { return this.hoverComponent; } public LComponent getSelectedComponent() { return this.selectedComponent; } public LComponent getModal() { return this.modal; } public void setModal(LComponent comp) { if (comp != null && !comp.isVisible()) { throw new RuntimeException( "Can't set invisible component as modal component!"); } this.modal = comp; } public LComponent get() { return this.contentPane.get(); } public void dispose() { if (contentPane != null) { contentPane.dispose(); } } protected void finalize() throws Throwable { super.finalize(); } }