diff --git a/IDE/Contents/Include/SettingsWindow.h b/IDE/Contents/Include/SettingsWindow.h index 63630988e..895148faa 100644 --- a/IDE/Contents/Include/SettingsWindow.h +++ b/IDE/Contents/Include/SettingsWindow.h @@ -41,12 +41,28 @@ class SettingsWindow : public UIWindow { void handleEvent(Event *event); void updateUI(); + /** + * Set the key properties + * @param keyString String of the selected label + * @return int describing which keys you use + */ + int setKeyProp(String keyString); + + UITab *keys, *general; + UITabFrame *tabFrame; + + UIElement *rootGeneral; UICheckBox *useExternalTextEditorBox; UITextInput *externalTextEditorCommand; UIButton *browseButton; UIComboBox *syntaxThemeBox; UIComboBox *uiThemeBox; UIComboBox *textureFilteringBox; + + UIElement *rootKeys; + UIComboBox *keyPan; + UIComboBox *keyRot; + UIComboBox *keyZoom; UIButton *cancelButton; UIButton *okButton; diff --git a/IDE/Contents/Include/TrackballCamera.h b/IDE/Contents/Include/TrackballCamera.h index 231d579c2..0d24515b2 100644 --- a/IDE/Contents/Include/TrackballCamera.h +++ b/IDE/Contents/Include/TrackballCamera.h @@ -39,7 +39,13 @@ class TrackballCamera : public EventDispatcher { void setCameraPosition(Vector3 cameraPosition); - + + /** + * Function to check if the keys needed for an action (like zooming) + * @param actionKey String with keyPan, keyRot or keyZoom for the saved key to return + * @return true if all keys for this action are down + */ + bool isActionKeyDown(String actionKey); bool isNavKeyDown(); void disableRotation(bool val); diff --git a/IDE/Contents/Source/PolycodeIDEApp.cpp b/IDE/Contents/Source/PolycodeIDEApp.cpp index 90e9a5edf..3a946b355 100644 --- a/IDE/Contents/Source/PolycodeIDEApp.cpp +++ b/IDE/Contents/Source/PolycodeIDEApp.cpp @@ -1181,6 +1181,11 @@ void PolycodeIDEApp::saveConfigFile() { ObjectEntry *textEditorEntry = configFile.root["settings"]->addChild("text_editor"); textEditorEntry->addChild("use_external", config->getStringValue("Polycode", "useExternalTextEditor")); textEditorEntry->addChild("command", config->getStringValue("Polycode", "externalTextEditorCommand")); + + ObjectEntry *keysEntry = configFile.root["settings"]->addChild("keys"); + keysEntry->addChild("key_pan", config->getNumericValue("Polycode", "keyPan")); + keysEntry->addChild("key_rot", config->getNumericValue("Polycode", "keyRot")); + keysEntry->addChild("key_zoom", config->getNumericValue("Polycode", "keyZoom")); #if defined(__APPLE__) && defined(__MACH__) core->createFolder(core->getUserHomeDirectory()+"/Library/Application Support/Polycode"); @@ -1240,25 +1245,50 @@ void PolycodeIDEApp::loadConfigFile() { } } - if(configFile.root["settings"]) { + if (configFile.root["settings"]) { ObjectEntry *settings = configFile.root["settings"]; ObjectEntry *textEditor = (*settings)["text_editor"]; - if(textEditor) { - if((*textEditor)["use_external"]) { + ObjectEntry *keysEntry = (*settings)["keys"]; + if (textEditor) { + if ((*textEditor)["use_external"]) { config->setStringValue("Polycode", "useExternalTextEditor", (*textEditor)["use_external"]->stringVal); } else { config->setStringValue("Polycode", "useExternalTextEditor", "false"); } - if((*textEditor)["command"]) { + if ((*textEditor)["command"]) { config->setStringValue("Polycode", "externalTextEditorCommand", (*textEditor)["command"]->stringVal); } else { config->setStringValue("Polycode", "externalTextEditorCommand", ""); } } + if (keysEntry){ + if ((*keysEntry)["key_pan"]){ + config->setNumericValue("Polycode", "keyPan", (*keysEntry)["key_pan"]->NumberVal); + } else { + config->setNumericValue("Polycode", "keyPan", 5); + } + if ((*keysEntry)["key_rot"]){ + config->setNumericValue("Polycode", "keyRot", (*keysEntry)["key_rot"]->NumberVal); + } else { + config->setNumericValue("Polycode", "keyRot", 0); + } + if ((*keysEntry)["key_zoom"]){ + config->setNumericValue("Polycode", "keyZoom", (*keysEntry)["key_zoom"]->NumberVal); + } else { + config->setNumericValue("Polycode", "keyZoom", 6); + } + } else { + config->setNumericValue("Polycode", "keyPan", 5); + config->setNumericValue("Polycode", "keyRot", 0); + config->setNumericValue("Polycode", "keyZoom", 6); + } } else { - config->setStringValue("Polycode","useExternalTextEditor", "false"); + config->setStringValue("Polycode", "useExternalTextEditor", "false"); config->setStringValue("Polycode", "externalTextEditorCommand", ""); + config->setNumericValue("Polycode", "keyPan", 5); + config->setNumericValue("Polycode", "keyRot", 0); + config->setNumericValue("Polycode", "keyZoom", 6); } } diff --git a/IDE/Contents/Source/SettingsWindow.cpp b/IDE/Contents/Source/SettingsWindow.cpp index 58504e638..4a505df97 100644 --- a/IDE/Contents/Source/SettingsWindow.cpp +++ b/IDE/Contents/Source/SettingsWindow.cpp @@ -25,113 +25,209 @@ extern UIGlobalMenu *globalMenu; extern SyntaxHighlightTheme *globalSyntaxTheme; SettingsWindow::SettingsWindow() : UIWindow(L"Settings", SETTINGS_WINDOW_WIDTH, SETTINGS_WINDOW_HEIGHT) { - + Config *config = CoreServices::getInstance()->getConfig(); closeOnEscape = true; + rootGeneral = new UIElement(SETTINGS_WINDOW_WIDTH - (padding * 2), SETTINGS_WINDOW_HEIGHT - 50); + + rootKeys = new UIElement(SETTINGS_WINDOW_WIDTH - (padding * 2), SETTINGS_WINDOW_HEIGHT - 50); + + general = new UITab("General", rootGeneral); + keys = new UITab("Keys", rootKeys); + + tabFrame = new UITabFrame(general, SETTINGS_WINDOW_WIDTH - (padding * 2), SETTINGS_WINDOW_HEIGHT - 25); + tabFrame->addNewTab(keys); + tabFrame->showTab(general); + tabFrame->setPositionY(25); + + addChild(tabFrame); + UILabel *label = new UILabel("TEXT EDITING", 22, "section", Label::ANTIALIAS_FULL); - addChild(label); + rootGeneral->addChild(label); label->color.a = 1.0; - label->setPosition(padding, 50); + label->setPosition(padding, 0); useExternalTextEditorBox = new UICheckBox("Use external text editor", false); - addChild(useExternalTextEditorBox); - useExternalTextEditorBox->setPosition(padding, 85); + rootGeneral->addChild(useExternalTextEditorBox); + useExternalTextEditorBox->setPosition(padding, 35); - #define BUTTON_WIDTH 80 - #define BUTTON_PADDING 10 - #define EDITOR_BROWSE_POS 110 - #define TEXTBOX_HEIGHT 12 +#define BUTTON_WIDTH 80 +#define BUTTON_PADDING 10 +#define EDITOR_BROWSE_POS 60 +#define TEXTBOX_HEIGHT 12 - externalTextEditorCommand = new UITextInput(false, SETTINGS_WINDOW_WIDTH - (padding*2 + BUTTON_WIDTH + BUTTON_PADDING/2), TEXTBOX_HEIGHT); - addChild(externalTextEditorCommand); + externalTextEditorCommand = new UITextInput(false, SETTINGS_WINDOW_WIDTH - (padding * 2 + BUTTON_WIDTH + BUTTON_PADDING / 2), TEXTBOX_HEIGHT); + rootGeneral->addChild(externalTextEditorCommand); externalTextEditorCommand->setPosition(padding, EDITOR_BROWSE_POS); - - + + label = new UILabel("Syntax highlighting theme", 12); - addChild(label); + rootGeneral->addChild(label); label->color.a = 1.0; label->setPosition(padding, EDITOR_BROWSE_POS + 35); - + syntaxThemeBox = new UIComboBox(globalMenu, 300); - addChild(syntaxThemeBox); + rootGeneral->addChild(syntaxThemeBox); syntaxThemeBox->setPosition(padding, EDITOR_BROWSE_POS + 55); syntaxThemeBox->addEventListener(this, UIEvent::CHANGE_EVENT); - + std::vector themes = OSBasics::parseFolder(CoreServices::getInstance()->getCore()->getDefaultWorkingDirectory() + "/SyntaxThemes", false); - - for(int i=0; i < themes.size(); i++) { - if(themes[i].extension == "xml") { + + for (int i = 0; i < themes.size(); i++) { + if (themes[i].extension == "xml") { syntaxThemeBox->addComboItem(themes[i].nameWithoutExtension); } } browseButton = new UIButton("Browse...", BUTTON_WIDTH); browseButton->addEventListener(this, UIEvent::CLICK_EVENT); - addChild(browseButton); - browseButton->setPosition(SETTINGS_WINDOW_WIDTH - (2*padding + BUTTON_WIDTH/2), EDITOR_BROWSE_POS); - - + rootGeneral->addChild(browseButton); + browseButton->setPosition(SETTINGS_WINDOW_WIDTH - (2 * padding + BUTTON_WIDTH / 2), EDITOR_BROWSE_POS); + + label = new UILabel("GENERAL", 22, "section", Label::ANTIALIAS_FULL); - addChild(label); + rootGeneral->addChild(label); label->color.a = 1.0; - label->setPosition(padding, 200); + label->setPosition(padding, 160); label = new UILabel("UI theme (requires restart)", 12); - addChild(label); + rootGeneral->addChild(label); label->color.a = 1.0; - label->setPosition(padding, 235); + label->setPosition(padding, 185); uiThemeBox = new UIComboBox(globalMenu, 300); - addChild(uiThemeBox); - uiThemeBox->setPosition(padding, 255); + rootGeneral->addChild(uiThemeBox); + uiThemeBox->setPosition(padding, 205); uiThemeBox->addEventListener(this, UIEvent::CHANGE_EVENT); - + std::vector uiThemes = OSBasics::parseFolder(CoreServices::getInstance()->getCore()->getDefaultWorkingDirectory() + "/UIThemes", false); - - for(int i=0; i < uiThemes.size(); i++) { - if(uiThemes[i].type == OSFileEntry::TYPE_FOLDER) { - - // do not list retina theme copies - if(uiThemes[i].name.find("_retina") == -1) { - uiThemeBox->addComboItem(uiThemes[i].name); - if(uiThemes[i].name == CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiTheme")) { - uiThemeBox->setSelectedIndex(i); - } - } + + for (int i = 0; i < uiThemes.size(); i++) { + if (uiThemes[i].type == OSFileEntry::TYPE_FOLDER) { + + // do not list retina theme copies + if (uiThemes[i].name.find("_retina") == -1) { + uiThemeBox->addComboItem(uiThemes[i].name); + if (uiThemes[i].name == CoreServices::getInstance()->getConfig()->getStringValue("Polycode", "uiTheme")) { + uiThemeBox->setSelectedIndex(i); + } + } } } label = new UILabel("Texture filtering (requires restart)", 12); - addChild(label); + rootGeneral->addChild(label); label->color.a = 1.0; - label->setPosition(padding, 285); + label->setPosition(padding, 235); textureFilteringBox = new UIComboBox(globalMenu, 300); - addChild(textureFilteringBox); - textureFilteringBox->setPosition(padding, 305); + rootGeneral->addChild(textureFilteringBox); + textureFilteringBox->setPosition(padding, 255); textureFilteringBox->addEventListener(this, UIEvent::CHANGE_EVENT); textureFilteringBox->addComboItem("Linear"); textureFilteringBox->addComboItem("Nearest"); - + + label = new UILabel("KEYS", 22, "section", Label::ANTIALIAS_FULL); + rootKeys->addChild(label); + label->color.a = 1.0; + label->setPosition(padding, 0); + + label = new UILabel("Pan Key (+ Mouse)", 12); + rootKeys->addChild(label); + label->color.a = 1.0; + label->setPosition(padding, 35); + + keyPan = new UIComboBox(globalMenu, 300); + rootKeys->addChild(keyPan); + keyPan->setPosition(padding, 55); + keyPan->addEventListener(this, UIEvent::CHANGE_EVENT); + keyPan->addComboItem("ALT"); + keyPan->addComboItem("SHIFT"); + keyPan->addComboItem("CTRL"); + keyPan->addComboItem("ALT GR"); + keyPan->addComboItem("WINDOWS KEY"); + keyPan->addComboItem("ALT + SHIFT"); + keyPan->addComboItem("ALT + CTRL"); + keyPan->addComboItem("SHIFT + CTRL"); + keyPan->addComboItem("ALT + SHIFT + CTRL"); + keyPan->addComboItem("ALT GR + SHIFT"); + keyPan->addComboItem("ALT GR + CTRL"); + keyPan->addComboItem("ALT GR + SHIFT + CTRL"); + keyPan->setSelectedIndex(config->getNumericValue("Polycode", "keyPan"), true); + + label = new UILabel("Rotation Key (+ Mouse)", 12); + rootKeys->addChild(label); + label->color.a = 1.0; + label->setPosition(padding, 80); + + keyRot = new UIComboBox(globalMenu, 300); + rootKeys->addChild(keyRot); + keyRot->setPosition(padding, 100); + keyRot->addEventListener(this, UIEvent::CHANGE_EVENT); + keyRot->addComboItem("ALT"); + keyRot->addComboItem("SHIFT"); + keyRot->addComboItem("CTRL"); + keyRot->addComboItem("ALT GR"); + keyRot->addComboItem("WINDOWS KEY"); + keyRot->addComboItem("ALT + SHIFT"); + keyRot->addComboItem("ALT + CTRL"); + keyRot->addComboItem("SHIFT + CTRL"); + keyRot->addComboItem("ALT + SHIFT + CTRL"); + keyRot->addComboItem("ALT GR + SHIFT"); + keyRot->addComboItem("ALT GR + CTRL"); + keyRot->addComboItem("ALT GR + SHIFT + CTRL"); + keyRot->setSelectedIndex(config->getNumericValue("Polycode", "keyRot"), true); + + label = new UILabel("Zoom Key (+ Mouse)", 12); + rootKeys->addChild(label); + label->color.a = 1.0; + label->setPosition(padding, 125); + + keyZoom = new UIComboBox(globalMenu, 300); + rootKeys->addChild(keyZoom); + keyZoom->setPosition(padding, 145); + keyZoom->addEventListener(this, UIEvent::CHANGE_EVENT); + keyZoom->addComboItem("ALT"); + keyZoom->addComboItem("SHIFT"); + keyZoom->addComboItem("CTRL"); + keyZoom->addComboItem("ALT GR"); + keyZoom->addComboItem("WINDOWS KEY"); + keyZoom->addComboItem("ALT + SHIFT"); + keyZoom->addComboItem("ALT + CTRL"); + keyZoom->addComboItem("SHIFT + CTRL"); + keyZoom->addComboItem("ALT + SHIFT + CTRL"); + keyZoom->addComboItem("ALT GR + SHIFT"); + keyZoom->addComboItem("ALT GR + CTRL"); + keyZoom->addComboItem("ALT GR + SHIFT + CTRL"); + keyZoom->setSelectedIndex(config->getNumericValue("Polycode", "keyZoom"), true); + cancelButton = new UIButton("Cancel", BUTTON_WIDTH); cancelButton->addEventListener(this, UIEvent::CLICK_EVENT); addChild(cancelButton); - cancelButton->setPosition(SETTINGS_WINDOW_WIDTH - (2*padding + BUTTON_WIDTH*1.5 + BUTTON_PADDING), SETTINGS_WINDOW_HEIGHT - padding); + cancelButton->setPosition(SETTINGS_WINDOW_WIDTH - (2 * padding + BUTTON_WIDTH*1.5 + BUTTON_PADDING), SETTINGS_WINDOW_HEIGHT - padding); okButton = new UIButton("OK", BUTTON_WIDTH); okButton->addEventListener(this, UIEvent::CLICK_EVENT); addChild(okButton); - okButton->setPosition(SETTINGS_WINDOW_WIDTH - (2*padding + BUTTON_WIDTH/2), SETTINGS_WINDOW_HEIGHT - padding); + okButton->setPosition(SETTINGS_WINDOW_WIDTH - (2 * padding + BUTTON_WIDTH / 2), SETTINGS_WINDOW_HEIGHT - padding); } void SettingsWindow::handleEvent(Event *event) { - if(event->getEventType() == "UIEvent") { - if(event->getEventCode() == UIEvent::CHANGE_EVENT) { - if(event->getDispatcher() == syntaxThemeBox) { - if(syntaxThemeBox->getSelectedItem()->label != globalSyntaxTheme->name) { + Config *config = CoreServices::getInstance()->getConfig(); + if (event->getEventType() == "UIEvent") { + if (event->getEventCode() == UIEvent::CHANGE_EVENT) { + if (event->getDispatcher() == syntaxThemeBox) { + if (syntaxThemeBox->getSelectedItem()->label != globalSyntaxTheme->name) { globalSyntaxTheme->loadFromFile(syntaxThemeBox->getSelectedItem()->label); } + } else if (event->getDispatcher() == keyPan){ + config->setNumericValue("Polycode", "keyPan", setKeyProp(keyPan->getSelectedItem()->label)); + } else if (event->getDispatcher() == keyRot){ + config->setNumericValue("Polycode", "keyRot", setKeyProp(keyRot->getSelectedItem()->label)); + } else if (event->getDispatcher() == keyZoom){ + config->setNumericValue("Polycode", "keyZoom", setKeyProp(keyZoom->getSelectedItem()->label)); } + } else if(event->getEventCode() == UIEvent::CLICK_EVENT) { if(event->getDispatcher() == okButton) { dispatchEvent(new UIEvent(), UIEvent::OK_EVENT); @@ -207,7 +303,41 @@ void SettingsWindow::updateUI() { textureFilteringBox->setSelectedIndex(0); } -} + keyPan->setSelectedIndex(config->getNumericValue("Polycode", "keyPan"), true); + keyRot->setSelectedIndex(config->getNumericValue("Polycode", "keyRot"), true); + keyZoom->setSelectedIndex(config->getNumericValue("Polycode", "keyZoom"), true); +} + +int SettingsWindow::setKeyProp(String keyString){ + if (keyString == "ALT"){ + return 0; + } else if (keyString == "SHIFT"){ + return 1; + } else if (keyString == "CTRL"){ + return 2; + } else if (keyString == "ALT GR"){ + return 3; + } else if (keyString == "WINDOWS KEY"){ + return 4; + } else if (keyString == "ALT + SHIFT"){ + return 5; + } else if (keyString == "ALT + CTRL"){ + return 6; + } else if (keyString == "SHIFT + CTRL"){ + return 7; + } else if (keyString == "ALT + SHIFT + CTRL"){ + return 8; + } else if (keyString == "ALT GR + SHIFT"){ + return 9; + } else if (keyString == "ALT GR + CTRL"){ + return 10; + } else if (keyString == "ALT GR + SHIFT + CTRL"){ + return 11; + } else { + return 0; + } +} + SettingsWindow::~SettingsWindow() { } diff --git a/IDE/Contents/Source/TrackballCamera.cpp b/IDE/Contents/Source/TrackballCamera.cpp index 0c865f8fe..ca5a2b42d 100644 --- a/IDE/Contents/Source/TrackballCamera.cpp +++ b/IDE/Contents/Source/TrackballCamera.cpp @@ -67,6 +67,37 @@ Camera *TrackballCamera::getTargetCamera() { return targetCamera; } +bool TrackballCamera::isActionKeyDown(String actionKey){ + Config *config = CoreServices::getInstance()->getConfig(); + Number key = config->getNumericValue("Polycode", actionKey); + if (key == 0){ + return (coreInput->getKeyState(KEY_LALT) || coreInput->getKeyState(KEY_RALT)); + } else if (key == 1){ + return (coreInput->getKeyState(KEY_LSHIFT) || coreInput->getKeyState(KEY_RSHIFT)); + } else if (key == 2){ + return (coreInput->getKeyState(KEY_LCTRL) || coreInput->getKeyState(KEY_RCTRL)); + } else if (key == 3){ + return (coreInput->getKeyState(KEY_MODE)); + } else if (key == 4){ + return (coreInput->getKeyState(KEY_LSUPER) || coreInput->getKeyState(KEY_RSUPER)); + } else if (key == 5){ + return ((coreInput->getKeyState(KEY_LALT) || coreInput->getKeyState(KEY_RALT)) && (coreInput->getKeyState(KEY_LSHIFT) || coreInput->getKeyState(KEY_RSHIFT))); + } else if (key == 6){ + return ((coreInput->getKeyState(KEY_LALT) || coreInput->getKeyState(KEY_RALT)) && (coreInput->getKeyState(KEY_LCTRL) || coreInput->getKeyState(KEY_RCTRL))); + } else if (key == 7){ + return ((coreInput->getKeyState(KEY_LSHIFT) || coreInput->getKeyState(KEY_RSHIFT)) && (coreInput->getKeyState(KEY_LCTRL) || coreInput->getKeyState(KEY_RCTRL))); + } else if (key == 8){ + return ((coreInput->getKeyState(KEY_LALT) || coreInput->getKeyState(KEY_RALT)) && (coreInput->getKeyState(KEY_LSHIFT) || coreInput->getKeyState(KEY_RSHIFT)) && (coreInput->getKeyState(KEY_LCTRL) || coreInput->getKeyState(KEY_RCTRL))); + } else if (key == 9){ + return ((coreInput->getKeyState(KEY_MODE)) && (coreInput->getKeyState(KEY_LSHIFT) || coreInput->getKeyState(KEY_RSHIFT))); + } else if (key == 10){ + return ((coreInput->getKeyState(KEY_MODE)) && (coreInput->getKeyState(KEY_LCTRL) || coreInput->getKeyState(KEY_RCTRL))); + } else if (key == 11){ + return ((coreInput->getKeyState(KEY_LALT) || coreInput->getKeyState(KEY_RALT)) && (coreInput->getKeyState(KEY_MODE))); + } else { + return false; + } +} bool TrackballCamera::isNavKeyDown() { return (coreInput->getKeyState(KEY_LALT) || coreInput->getKeyState(KEY_RALT)); @@ -77,30 +108,24 @@ void TrackballCamera::handleEvent(Event *event) { InputEvent *inputEvent = (InputEvent*) event; switch(event->getEventCode()) { case InputEvent::EVENT_MOUSEDOWN: - if(isNavKeyDown() || inputEvent->mouseButton == CoreInput::MOUSE_BUTTON3) { - if(coreInput->getKeyState(KEY_LSHIFT) || coreInput->getKeyState(KEY_RSHIFT)) { - mouseMode = MOUSE_MODE_PANNING; - trackBallMouseStart = Vector2( - inputEvent->getMousePosition().x / trackballShape->getWidth(), - inputEvent->getMousePosition().y / trackballShape->getHeight() + if (isActionKeyDown("keyPan")) { + mouseMode = MOUSE_MODE_PANNING; + trackBallMouseStart = Vector2( + inputEvent->getMousePosition().x / trackballShape->getWidth(), + inputEvent->getMousePosition().y / trackballShape->getHeight() ); - trackBallMouseEnd = trackBallMouseStart; - } else if(coreInput->getKeyState(KEY_LCTRL) || coreInput->getKeyState(KEY_RCTRL)) { - mouseMode = MOUSE_MODE_ZOOMING; - trackBallMouseStart = Vector2( - inputEvent->getMousePosition().x / trackballShape->getWidth(), - inputEvent->getMousePosition().y / trackballShape->getHeight() + trackBallMouseEnd = trackBallMouseStart; + } else if (isActionKeyDown("keyZoom")) { + mouseMode = MOUSE_MODE_ZOOMING; + trackBallMouseStart = Vector2( + inputEvent->getMousePosition().x / trackballShape->getWidth(), + inputEvent->getMousePosition().y / trackballShape->getHeight() ); - trackBallMouseEnd = trackBallMouseStart; - } else { - if(!rotationDisabled) { - mouseMode = MOUSE_MODE_ORBITING; - trackBallMouseStart = trackBallMouseEnd = Vector2( + trackBallMouseEnd = trackBallMouseStart; } else if (isActionKeyDown("keyRot") || inputEvent->mouseButton == CoreInput::MOUSE_BUTTON3){ if (!rotationDisabled) { + mouseMode = MOUSE_MODE_ORBITING; trackBallMouseStart = trackBallMouseEnd = Vector2( inputEvent->getMousePosition().x / trackballShape->getWidth(), - inputEvent->getMousePosition().y / trackballShape->getHeight() - ); - } - } + inputEvent->getMousePosition().y / trackballShape->getHeight() ); + } } } break; case InputEvent::EVENT_MOUSEUP: diff --git a/IDE/Contents/Source/TransformGizmo.cpp b/IDE/Contents/Source/TransformGizmo.cpp index 088521d24..a7d9ceb78 100644 --- a/IDE/Contents/Source/TransformGizmo.cpp +++ b/IDE/Contents/Source/TransformGizmo.cpp @@ -1054,7 +1054,7 @@ void TransformGizmo::handleEvent(Event *event) { return; } - if(!coreInput->getKeyState(KEY_LALT) && !coreInput->getKeyState(KEY_RALT)) { + if (!coreInput->getKeyState(KEY_LALT) && !coreInput->getKeyState(KEY_RALT) && !coreInput->getKeyState(KEY_LSHIFT) && !coreInput->getKeyState(KEY_RSHIFT) && !coreInput->getKeyState(KEY_LCTRL) && !coreInput->getKeyState(KEY_RCTRL) && !coreInput->getKeyState(KEY_MODE) && !coreInput->getKeyState(KEY_LSUPER) && !coreInput->getKeyState(KEY_RSUPER)) { if(event->getDispatcher() == pitchGrip) { if(event->getEventCode() == InputEvent::EVENT_MOUSEDOWN) { if(((InputEvent*)event)->getMouseButton() != CoreInput::MOUSE_BUTTON3) { diff --git a/Modules/Contents/UI/CMakeLists.txt b/Modules/Contents/UI/CMakeLists.txt index dd54cb715..c6fe85c70 100644 --- a/Modules/Contents/UI/CMakeLists.txt +++ b/Modules/Contents/UI/CMakeLists.txt @@ -24,6 +24,7 @@ SET(polycodeUI_SRCS Source/PolyUIFileDialog.cpp Source/PolyUIMenuBar.cpp Source/PolyUIIconSelector.cpp + Source/PolyUITab.cpp ) SET(polycodeUI_HDRS @@ -51,6 +52,7 @@ SET(polycodeUI_HDRS Include/PolyUIFileDialog.h Include/PolyUIMenuBar.h Include/PolyUIIconSelector.h + Include/PolyUITab.h ) INCLUDE_DIRECTORIES( diff --git a/Modules/Contents/UI/Include/PolyUITab.h b/Modules/Contents/UI/Include/PolyUITab.h new file mode 100644 index 000000000..5a6bab498 --- /dev/null +++ b/Modules/Contents/UI/Include/PolyUITab.h @@ -0,0 +1,227 @@ +/* +Copyright (C) 2014 by Joachim Meyer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#pragma once +#include "PolyGlobals.h" +#include "PolyUIElement.h" + +namespace Polycode { + + /** + * Is used to switch to a certain tab + */ + class _PolyExport UITabButton : public UIElement { + public: + /** + * Creates a new UITabButton by a caption + * @param caption String used for the label + */ + UITabButton(String caption); + ~UITabButton(); + + /** + * Sets the button's state + * @param val If true the button is selected, if false not + */ + void setActive(bool val); + void handleEvent(Event *event); + + /** + * Updates the label to the given String + * @param caption A String used as new name + */ + void updateLabel(String caption); + protected: + UIImage *bgRect; + UILabel *tabLabel; + }; + + /** + * A tab used in UITabFrame + */ + class _PolyExport UITab : public UIElement{ + public: + /** + * Creates a new tab of the given name and content + * @param caption String used as name + * @param tabContent A UIElement that has the children you want to have visible in this tab + */ + UITab(String caption, UIElement *tabContent); + ~UITab(); + + /** + * Resizes the tab to the given width and height + * @param width Width value of the tab + * @param height Height value of the tab + */ + void Resize(Number width, Number height); + + /** + * Set this tab active or inactive + * @param val True if tab should be visible, false if not + */ + void setActive(bool val); + + /** + * @return Whether the tab is active or not + */ + bool isActive(); + + /** + * Sets new content (old content will be overriden) + * @param newContent A UIElement that has the children you want to have visible in this tab + */ + void setContent(UIElement *newContent); + + /** + * @return The content of the tab + */ + UIElement *getContent(); + + /** + * @return The name of the tab + */ + String getTabName(); + + /** + * Sets new name + * @param newName String that should be the new name + */ + void setTabName(String newName); + + /** + * @return The UITabButton instance used by this tab + */ + UITabButton *getTabButton(); + + protected: + bool active; + String tabName; + + UITabButton *button; + UIElement *content; + }; + + /** + * An UI frame in which you can create tabs. + */ + class _PolyExport UITabFrame : public UIElement { + public: + /** + * Creates a new tab frame, needs a first tab. + * @param tab First UITab + * @param width Width value of the whole frame, if not provided defaulting to 320 + * @param height Height value of the whole frame, if not provided defaulting to 200 + */ + UITabFrame(UITab *tab, Number width = 320, Number height = 200); + ~UITabFrame(); + + /** + * Brings the given tab to the front + * @param tab UITab to show + */ + void showTab(UITab *tab); + + /** + * Brings the tab of the given index to the front + * @param tabIndex index of the tab in tabs + */ + void showTab(unsigned int tabIndex); + + /** + * Adds a new tab to the frame + * @param newTab UITab instance to add + */ + void addNewTab(UITab *newTab); + + /** + * @return std::vector of the tabs in the frame + */ + std::vector getTabs(); + + virtual void Update() {} + + /** + * @return Active tab + */ + UITab *getActiveTab(); + + /** + * @return Index of the active tab + */ + unsigned int getActiveTabIndex(); + + /** + * Returns the index of a given UITab + * @param tab A UITab instance of which you want to get the index + * @return Index of the given UITab + */ + unsigned int getTabIndex(UITab *tab); + + /** + * Returns the the tab of the given index + * @param index Index of the UITab to return + * @return UITab at index + */ + UITab *UITabFrame::getTabAtIndex(unsigned int index); + + /** + * @return How many tabs in the frame are - as unsigned int + */ + unsigned int getNumTabs(); + + void handleEvent(Event *event); + + /** + * Resizes the tab frame to the given width and height + * @param width Width value of the whole frame, + * @param height Height value of the whole frame + */ + void Resize(Number width, Number height); + + /** + * Sets the position of the tab button anchor (all the tab buttons positions are relative to this) + * @param _pos A Vector2 of the new position + */ + void setTabButtonAnchorPosition(Vector2 _pos); + + /** + * Sets the position of the tab button anchor (all the tab buttons positions are relative to this) + * @param x X-coordinate of the new position + * @param y Y-coordinate of the new position + */ + void setTabButtonAnchorPosition(Number x, Number y); + + /** + * Returns the position of the tab button anchor (all the tab buttons positions are relative to this) + * @return Position of the tab button anchor + */ + Vector2 getTabButtonAnchorPosition(); + + protected: + UIElement *tabButtonAnchor; + + UITab *activeTab; + std::vector tabButtons; + std::vector tabs; + }; +} \ No newline at end of file diff --git a/Modules/Contents/UI/Include/PolycodeUI.h b/Modules/Contents/UI/Include/PolycodeUI.h index 90c69bc70..acd44f7b9 100644 --- a/Modules/Contents/UI/Include/PolycodeUI.h +++ b/Modules/Contents/UI/Include/PolycodeUI.h @@ -43,3 +43,4 @@ #include "PolyUIFileDialog.h" #include "PolyUIMenuBar.h" #include "PolyUIIconSelector.h" +#include "PolyUITab.h" \ No newline at end of file diff --git a/Modules/Contents/UI/Source/PolyUITab.cpp b/Modules/Contents/UI/Source/PolyUITab.cpp new file mode 100644 index 000000000..4c0dc3f79 --- /dev/null +++ b/Modules/Contents/UI/Source/PolyUITab.cpp @@ -0,0 +1,252 @@ +/* +Copyright (C) 2014 by Joachim Meyer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "PolyUITab.h" +#include "PolyInputEvent.h" +#include "PolyCoreInput.h" +#include "PolyUIEvent.h" + +using namespace Polycode; + +UITab::UITab(String caption, UIElement *tabContent) : UIElement() { + + tabName = caption; + + + button = new UITabButton(caption); + + this->content = tabContent; + addChild(content); + + this->active = false; +} + +void UITab::setActive(bool val) { + this->active = val; + + content->visible = val; + content->enabled = val; + + button->setActive(val); +} + +bool UITab::isActive() { + return active; +} + +String UITab::getTabName() { + return tabName; +} + +UITabButton *UITab::getTabButton(){ + return button; +} + +void UITab::setTabName(String newName) { + tabName = newName; +} + +void UITab::Resize(Number width, Number height) { + content->Resize(width, height); + UIElement::Resize(width, height); +} + +UIElement *UITab::getContent() { + return content; +} + +void UITab::setContent(UIElement *newContent){ + this->content = newContent; +} + +UITab::~UITab() { + +} + +UITabButton::UITabButton(String caption){ + bgRect = new UIImage("main/tab_bg.png", 75, 20); + addChild(bgRect); + bgRect->processInputEvents = true; + processInputEvents = true; + bgRect->addEventListener(this, InputEvent::EVENT_MOUSEDOWN); + + setWidth(75); + setHeight(20); + + tabLabel = new UILabel(caption.toUpperCase(), 16, "section"); + tabLabel->setColor(0.0, 0.0, 0.0, 1.0); + tabLabel->setPosition(getWidth() - tabLabel->getWidth() - 10.0, ((getHeight() - tabLabel->getHeight()) / 2.0) - 3.0); + addChild(tabLabel); +} + +UITabButton::~UITabButton(){ + +} + +void UITabButton::setActive(bool val){ + if (val) { + bgRect->color.a = 0.4; + } else { + bgRect->color.a = 0.2; + } +} + +void UITabButton::handleEvent(Event *event){ + if (event->getDispatcher() == bgRect) { + if (event->getEventCode() == InputEvent::EVENT_MOUSEDOWN) { + dispatchEvent(new Event(), Event::SELECT_EVENT); + } + } + UIElement::handleEvent(event); +} + +void UITabButton::updateLabel(String caption){ + tabLabel->setText(caption.toUpperCase()); + tabLabel->setPosition(getWidth() - tabLabel->getWidth() - 10.0, ((getHeight() - tabLabel->getHeight()) / 2.0) - 3.0); +} + +UITabFrame::UITabFrame(UITab *tab, Number width, Number height) : UIElement(width, height) { + tabButtonAnchor = new UIElement(); + addChild(tabButtonAnchor); + tabButtonAnchor->setPosition(5, 5); + + tabs.push_back(tab); + tabButtonAnchor->addChild(tab->getTabButton()); + tabButtons.push_back(tab->getTabButton()); + tab->getTabButton()->addEventListener(this, Event::SELECT_EVENT); + tab->setPositionY(tab->getTabButton()->getHeight() + 5); + activeTab = tab; +} + +void UITabFrame::handleEvent(Event *event) { + for (int i = 0; i < tabButtons.size(); i++) { + if (event->getDispatcher() == tabButtons[i]) { + if (event->getEventCode() == Event::SELECT_EVENT) { + showTab(tabs[i]); + break; + } else if (event->getEventCode() == UIEvent::CHANGE_EVENT) { + dispatchEvent(new UIEvent(), UIEvent::CHANGE_EVENT); + break; + } + } + + } + + UIElement::handleEvent(event); +} + +void UITabFrame::showTab(UITab *tab) { + if (activeTab) { + activeTab->setActive(false); + activeTab->removeAllHandlersForListener(this); + removeChild(activeTab); + } + + addChild(tab); + tab->setActive(true); + tab->Resize(getWidth(), getHeight()); + activeTab = tab; + dispatchEvent(new UIEvent(), Event::CHANGE_EVENT); +} + +void UITabFrame::showTab(unsigned int tabIndex) { + if (tabIndex < tabs.size()) + { + if (activeTab) { + tabs.at(tabIndex)->setActive(false); + activeTab->removeAllHandlersForListener(this); + removeChild(activeTab); + } + + tabs.at(tabIndex)->setActive(true); + tabs.at(tabIndex)->Resize(getWidth(), getHeight()); + activeTab = tabs.at(tabIndex); + + addChild(tabs.at(tabIndex)); + dispatchEvent(new UIEvent(), Event::CHANGE_EVENT); + } +} + +UITab *UITabFrame::getTabAtIndex(unsigned int index) { + return tabs[index]; +} + +unsigned int UITabFrame::getActiveTabIndex() { + int i = 0; + while (activeTab != tabs.at(i)){ + i++; + } + return i; +} + +unsigned int UITabFrame::getTabIndex(UITab *tab) { + int i = 0; + while (tab != tabs.at(i)){ + i++; + } + return i; +} + +unsigned int UITabFrame::getNumTabs() { + return tabs.size(); +} + +UITab *UITabFrame::getActiveTab() { + return activeTab; +} + +std::vector UITabFrame::getTabs() { + return tabs; +} + +void UITabFrame::addNewTab(UITab *newTab){ + tabs.push_back(newTab); + + tabButtonAnchor->addChild(newTab->getTabButton()); + newTab->getTabButton()->setPositionX(tabButtons[tabButtons.size() - 1]->getPosition().x + tabButtons[tabButtons.size() - 1]->getWidth()); + tabButtons.push_back(newTab->getTabButton()); + newTab->getTabButton()->addEventListener(this, Event::SELECT_EVENT); + newTab->setPositionY(newTab->getTabButton()->getHeight() + 5); + showTab(newTab); +} + +void UITabFrame::setTabButtonAnchorPosition(Vector2 _pos){ + tabButtonAnchor->setPosition(_pos.x, _pos.y); + +} + +void UITabFrame::setTabButtonAnchorPosition(Number x, Number y){ + tabButtonAnchor->setPosition(x, y); +} + +Vector2 UITabFrame::getTabButtonAnchorPosition(){ + return tabButtonAnchor->getPosition2D(); +} + +void UITabFrame::Resize(Number width, Number height) { + activeTab->Resize(width, height); + UIElement::Resize(width, height); +} + +UITabFrame::~UITabFrame() { + +} \ No newline at end of file