package br.com.etyllica.core; import java.util.ArrayList; import java.util.List; import br.com.etyllica.awt.AWTArrowDrawer; import br.com.etyllica.awt.core.input.AWTController; import br.com.etyllica.core.animation.AnimationHandler; import br.com.etyllica.core.animation.script.AnimationScript; import br.com.etyllica.core.animation.script.SingleIntervalAnimation; import br.com.etyllica.core.context.Application; import br.com.etyllica.core.context.Context; import br.com.etyllica.core.context.UpdateIntervalListener; import br.com.etyllica.core.context.load.ApplicationLoader; import br.com.etyllica.core.context.load.LoaderListener; import br.com.etyllica.core.effect.GlobalEffect; import br.com.etyllica.core.error.ErrorMessages; import br.com.etyllica.core.event.GUIEvent; import br.com.etyllica.core.event.KeyEvent; import br.com.etyllica.core.event.KeyEventListener; import br.com.etyllica.core.event.MouseEvent; import br.com.etyllica.core.event.PointerEvent; import br.com.etyllica.core.event.PointerState; import br.com.etyllica.core.graphics.ArrowDrawer; import br.com.etyllica.core.graphics.Graphics; import br.com.etyllica.core.graphics.Monitor; import br.com.etyllica.core.i18n.Language; import br.com.etyllica.core.i18n.LanguageChangerListener; import br.com.etyllica.core.i18n.LanguageHandler; import br.com.etyllica.core.input.keyboard.Keyboard; import br.com.etyllica.core.input.mouse.Mouse; import br.com.etyllica.core.ui.UIComponent; import br.com.etyllica.core.ui.UICore; import br.com.etyllica.core.ui.UICoreListener; import br.com.etyllica.gui.View; import br.com.etyllica.gui.Window; import br.com.etyllica.gui.theme.Theme; import br.com.etyllica.gui.theme.ThemeManager; import br.com.etyllica.gui.theme.listener.ThemeListener; import br.com.etyllica.theme.etyllic.EtyllicArrowTheme; /** * * @author yuripourre * */ public abstract class InnerCore implements Core, KeyEventListener, Updatable, ThemeListener, LanguageChangerListener, LoaderListener, UICoreListener { private static final int TITLE_BAR_HEIGHT = 50; //External Windows private Window activeWindow = null; protected AWTController control; private Mouse mouse; private Keyboard keyboard; //private List<KeyEvent> joyEvents; private Window mainWindow; private boolean drawCursor = true; private boolean fullScreenEnable = false; private boolean needReload = false; private boolean locked = false; private boolean fixEventPosition = false; private int fps = 0; //FullScreen Stuff private boolean enableFullScreen = false; private boolean disableFullScreen = false; private boolean alt = false; private boolean enter = false; private boolean esc = false; protected GUIEvent superEvent = GUIEvent.NONE; //Create an Arrow Drawer private ArrowDrawer arrowDrawer; private LanguageHandler languageHandler; private List<Updatable> updatables = new ArrayList<Updatable>(); private List<SingleIntervalAnimation> globalScripts = new ArrayList<SingleIntervalAnimation>(); protected List<Monitor> monitors = new ArrayList<Monitor>(); protected ApplicationLoader applicationLoader; protected UICore uiCore; public InnerCore(int w, int h) { super(); control = new AWTController(this); setMouse(control.getMouse()); setKeyboard(control.getKeyboard()); arrowDrawer = new AWTArrowDrawer(); uiCore = new UICore(w, h, this); uiCore.setArrowDrawer(arrowDrawer); uiCore.setMouse(control.getMouse()); languageHandler = new LanguageHandler(); initTheme(); updatables.add(AnimationHandler.getInstance()); applicationLoader = new ApplicationLoader(w, h); } private void initTheme() { ThemeManager.getInstance().setThemeListener(this); ThemeManager.getInstance().setArrowThemeListener(arrowDrawer); ThemeManager.getInstance().setArrowTheme(new EtyllicArrowTheme()); } public Window getWindow() { return mainWindow; } public void update(long now) { if(!currentContext().isLoaded()) { return; } else if (needReload) { fastReload(); } superEvent = GUIEvent.NONE; updateActiveWindow(now); updateEffects(now); Context application = currentContext(); updateApplication(application, now); if(checkApplicationChange(application)) { return; } updateInput(application, now); //Update in another thread //Joystick locks the application //JoystickLoader.getInstance().update(now); handleFullScreen(); } private void updateInput(Context application, long now) { //Update All components //List<View> components = new CopyOnWriteArrayList<View>(application.getViews()); List<View> components = application.getViews(); uiCore.updateGui(components); List<PointerEvent> events = getMouse().lock(); updatePointerEvents(events, application, components); getMouse().unlock(); updateHelperUI(now); //updateKeyboard(); getKeyboard().update(now); } private boolean checkApplicationChange(Context application) { //if activeWindow, receive command to change application if(application.getNextApplication() != application) { this.changeApplication(); return true; } return false; } private void handleFullScreen() { if(enableFullScreen) { enableFullScreen = false; superEvent = GUIEvent.ENABLE_FULL_SCREEN; } if(disableFullScreen) { disableFullScreen = false; superEvent = GUIEvent.DISABLE_FULL_SCREEN; } } public void resizeApplication(int w, int h) { Context application = currentContext(); application.resize(w, h); application.setW(w); application.setH(h); } public boolean updateApplication(Context context, long now) { if(context.isLocked()) { return false; } if (context.getUpdateInterval() == 0) { context.update(now); context.setLastUpdate(now); //Update Components for (UIComponent component:context.getComponents()) { component.update(now); } }else if(now-context.getLastUpdate() >= context.getUpdateInterval()) { UpdateIntervalListener updated = context.getUpdated(); if(updated==null) { return false; } updated.timeUpdate(now); context.setLastUpdate(now); for (UIComponent component:context.getComponents()) { component.update(now); } } return true; } private void updateActiveWindow(long now) { List<Window> windows = activeWindow.getWindows(); //Creating Windows //if application has windows if(!windows.isEmpty()) { //For each new window in application.windows for(Window window : windows) { //if this !windows.contains(window) replaceWindow(window); } activeWindow.getWindows().clear(); } /*if(activeWindow.isClose()) { if(windows.size()>0) { windows.remove(activeWindow); activeWindow = windows.get(windows.size()-1); }else{ System.exit(0); } }*/ } @Override public void updateJoystickEvent(KeyEvent event) { Context context = currentContext(); //Debug Joystick Commands //System.out.println("UpdateJoystick "+event.getKey()); handleApplicationKeyEvents(context, event); } public void updatePointerEvents(List<PointerEvent> events, Context context, List<View> components) { int eventSize = events.size(); for(int i=0; i < eventSize; i++) { PointerEvent event = events.get(i); context.updateMouse(event); updatePointerEvent(event, components); } } public void updatePointerEvent(PointerEvent event, List<View> components) { if(fixEventPosition) { fixEventPosition(event); } uiCore.updateMouseViews(event, components); updateWindowEvent(event, activeWindow); } private void updateWindowEvent(PointerEvent event, Window window) { GUIEvent frameEvent = updateFrameEvents(event); if(frameEvent != GUIEvent.NONE) { superEvent = frameEvent; } } public void draw(Graphics g) { if(!canDraw()) return; drawContext(currentContext(), g); drawGlobalEffects(g); if(drawCursor) { if(currentContext().isDrawCursor()) { uiCore.drawCursor(g); } } } protected boolean canDraw() { return !locked && !needReload; } private void drawContext(Context context, Graphics g) { if(context.isClearBeforeDraw()) { g.setColor(context.getBackgroundColor()); g.fillRect(0, 0, context.getW(), context.getH()); } context.draw(g); //Draw Components for (UIComponent component:context.getComponents()) { component.draw(g); } uiCore.drawUIViews(g, context); } private void updateEffects(long now) { for(Updatable updatable: updatables) { updatable.update(now); } } private void drawGlobalEffects(Graphics g) { List<AnimationScript> remove = new ArrayList<AnimationScript>(); for(SingleIntervalAnimation script: globalScripts) { if(!script.isStopped()) { script.getTarget().draw(g); } else { remove.add(script); } } for(AnimationScript script: remove) { globalScripts.remove(script); } } public boolean isMouseOver() { return uiCore.mouseOver != null; } public View getMouseOver() { return uiCore.mouseOver; } public void addEffect(GlobalEffect effect) { AnimationHandler.getInstance().add(effect.getScript()); globalScripts.add(effect.getScript()); //TODO add animation //globalEffects.add(effect); } private void updateKeyboardEvents(KeyEvent event) { if(event.isKeyDown(KeyEvent.VK_ALT_RIGHT)||event.isKeyDown(KeyEvent.VK_ALT_LEFT)) { alt = true; } else if(event.isKeyUp(KeyEvent.VK_ALT_RIGHT)||event.isKeyUp(KeyEvent.VK_ALT_LEFT)) { alt = false; } if(event.isKeyDown(KeyEvent.VK_ENTER)) { enter = true; } else if(event.isKeyUp(KeyEvent.VK_ENTER)) { enter = false; } if(event.isKeyDown(KeyEvent.VK_ESC)) { esc = true; } else if(event.isKeyUp(KeyEvent.VK_ESC)) { esc = false; } if(alt&&enter) { alt = false; enter = false; if(!isFullScreenEnable()) { enableFullScreen = true; } } if(esc) { esc = false; if(isFullScreenEnable()) { disableFullScreen = true; } } } private void updateNumpadMouse(KeyEvent event) { if(Configuration.getInstance().isNumpadMouse()) { int speed = 1; //Move Left/Right if(event.isKeyDown(KeyEvent.VK_NUMPAD_LEFT_ARROW)) { getMouse().setX(getMouse().getX()-speed); getMouse().addEvent(new PointerEvent(MouseEvent.MOUSE_NONE, PointerState.MOVE, getMouse().getX(), getMouse().getY())); }else if(event.isKeyDown(KeyEvent.VK_NUMPAD_RIGHT_ARROW)) { getMouse().setX(getMouse().getX()+speed); getMouse().addEvent(new PointerEvent(MouseEvent.MOUSE_NONE, PointerState.MOVE, getMouse().getX(), getMouse().getY())); } //Move Up/Down if(event.isKeyDown(KeyEvent.VK_NUMPAD_UP_ARROW)) { getMouse().setX(getMouse().getY()-speed); getMouse().addEvent(new PointerEvent(MouseEvent.MOUSE_NONE, PointerState.MOVE, getMouse().getX(), getMouse().getY())); }else if(event.isKeyDown(KeyEvent.VK_NUMPAD_DOWN_ARROW)) { getMouse().setX(getMouse().getY()+speed); getMouse().addEvent(new PointerEvent(MouseEvent.MOUSE_NONE, PointerState.MOVE, getMouse().getX(), getMouse().getY())); } //Mouse Left Button if(event.isKeyDown(KeyEvent.VK_NUMPAD_INS)) { getMouse().addEvent(new PointerEvent(MouseEvent.MOUSE_BUTTON_LEFT, PointerState.PRESSED)); }else if(event.isKeyUp(KeyEvent.VK_NUMPAD_INS)) { getMouse().addEvent(new PointerEvent(MouseEvent.MOUSE_BUTTON_LEFT, PointerState.RELEASED)); }/*else if(event.getKeyTyped(Tecla.VK_NUMPAD_INS)) { Gui.getInstance().addEvent(new Event(Tecla.MOUSE_BUTTON_LEFT, KeyState.CLICK)); }*/ //Mouse Right Button if(event.isKeyDown(KeyEvent.VK_NUMPAD_DEL)) { getMouse().addEvent(new PointerEvent(MouseEvent.MOUSE_BUTTON_RIGHT, PointerState.PRESSED)); }else if(event.isKeyUp(KeyEvent.VK_NUMPAD_DEL)) { getMouse().addEvent(new PointerEvent(MouseEvent.MOUSE_BUTTON_RIGHT, PointerState.RELEASED)); }/*else if(event.getKeyTyped(Tecla.VK_NUMPAD_DEL)) { getMouse().addEvent(new PointerEvent(MouseButton.MOUSE_BUTTON_RIGHT, KeyState.CLICK)); }*/ } } private GUIEvent updateFrameEvents(PointerEvent event) { if(event.getState() == PointerState.CLICK) { return GUIEvent.REQUEST_FOCUS; } if(event.getState() == PointerState.DRAGGED) { if(getMouse().getY() <= TITLE_BAR_HEIGHT) { return GUIEvent.WINDOW_MOVE; } } return GUIEvent.NONE; } public void replaceWindow(Window window) { if(activeWindow != window) { window.setClose(false); activeWindow = window; //Avoid unnecessary reload reload(window.getContext()); } } public void setMainApplication(Application application) { reload(application); } public void changeApplication() { Context currentApplication = currentContext(); currentApplication.getComponents().remove(AnimationHandler.getInstance()); currentApplication.dispose(); reload(currentApplication.getNextApplication()); } public Context currentContext() { return activeWindow.getContext(); } private void reload(Context application) { if(application == null) { System.err.println(ErrorMessages.APPLICATION_NULL); return; } application.setParent(activeWindow); application.setDrawCursor(drawCursor); application.setMouseStateListener(arrowDrawer); application.setLanguageChangerListener(this); application.getComponents().add(AnimationHandler.getInstance()); if (application.isLoaded()) { activeWindow.setApplication(applicationLoader.reloadApplication(this, application)); } } private void fastReload() { locked = true; currentContext().getViews().clear(); currentContext().load(); needReload = false; locked = false; } private void updateHelperUI(long now) { uiCore.updateTimerClick(now); } @Override public void updateKeyEvent(KeyEvent event) { Context context = currentContext(); handleApplicationKeyEvents(context, event); uiCore.updateKeyboard(event); updateKeyboardEvents(event); updateNumpadMouse(event); } protected void handleApplicationKeyEvents(Context context, KeyEvent event) { //Handle Application commands context.updateKeyboard(event); } private void fixEventPosition(PointerEvent event) { event.setX(event.getX()-activeWindow.getX()); event.setY(event.getY()-activeWindow.getY()); } public AWTController getControl() { return control; } public GUIEvent getSuperEvent() { return superEvent; } public void hideCursor() { drawCursor = false; } public void showCursor() { drawCursor = true; } public int getFps() { return fps; } public void setFps(int fps) { this.fps = fps; this.activeWindow.getContext().setFps(fps); } @Override public void updateTheme(Theme theme) { needReload = true; } @Override public void changeLanguage(Language language) { languageHandler.changeLanguage(language); List<View> components = currentContext().getViews(); uiCore.updateGuiEvent(components, GUIEvent.LANGUAGE_CHANGED); } @Override public void onLoad(Context context) { activeWindow.setApplication(context); context.setLoaded(true); } public List<Monitor> getMonitors() { return monitors; } public boolean isFullScreenEnable() { return fullScreenEnable; } public void setFullScreenEnable(boolean fullScreenEnable) { this.fullScreenEnable = fullScreenEnable; } public Mouse getMouse() { return mouse; } public void setMouse(Mouse mouse) { this.mouse = mouse; } public Keyboard getKeyboard() { return keyboard; } public void setKeyboard(Keyboard keyboard) { this.keyboard = keyboard; } }