diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..ebd76f5e4 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,31 @@ +name: Run Gradle build on push + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Cache Gradle packages + uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + - name: Build with Gradle + run: ./gradlew build + - name: Cleanup Gradle Cache + # Remove some files from the Gradle cache, so they aren't cached by GitHub Actions. + # Restoring these files from a GitHub Actions cache might cause problems for future builds. + run: | + rm -f ~/.gradle/caches/modules-2/modules-2.lock + rm -f ~/.gradle/caches/modules-2/gc.properties \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8a7d02425..c3b7aabab 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ *.ipr *.iml out/ +.idea/ # Eclipse .project @@ -17,6 +18,6 @@ bin/ build/ .gradle/ -gradle.properties - +*.log +.DS_Store diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index 7cfdc4d49..000000000 --- a/CHANGELOG +++ /dev/null @@ -1,31 +0,0 @@ -[0.6.0] -- COMPOSER: fix package naming when creating ios project - -[0.5.0] -- Updated to libgdx 1.4.1 -- ENGINE: Debug screen with speed control, record/play games and go to any scene in runtime -- ENGINE: Material style buttons in engine UI. Better look and feel for inventory and pie menu. - -[0.4.0] -- ENGINE: Custom game UI Screen support - -[0.3.2] -- COMPOSER: Fixed bug when running project without console - -[0.3.1] -- COMPOSER: Fixed accessing opengl context issue when creating project in the new thread. - -[0.3.0] -- ENGINE: Action refactoring. WARNING: Names have changed. All previous games are not compatible. -- ENGINE: New DebugScreen (Work in progress) -- ENGINE: Change speed support for fastforward. -- ENGINE: The blade-engine.jar are now in Maven Central. When creating a new game, the Maven dependency is added instead of adding the engine jar in libs folder. - -[0.2.0] -- COMPOSER: Fixed NullPointer error when creating project -- COMPOSER: Threads for long tasks to show UI message status -- COMPOSER: FIXED packaging with embedded JRE. -- ENGINE: CreditsScreen fonts now obtained from Skin - -[0.1.0] -- Initial release \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..7f542ff91 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,976 @@ +# Change Log + +All notable changes to this project will be documented in this file. +This project adheres to [Semantic Versioning](http://semver.org/). + +## [4.3.1] + +- Bugfix small font size. +- Update libgdx v1.12.1. + +## [4.3.0] + +- Fallback fonts/multiple fonts files to support dynamic font changing needed for Chinese and other logographic + languages. +- Upgrade gradle + robovm + android plugin to latest versions. +- Bugfix when adding a new item to a Ink list. + +## [4.2.0] + +- EDITOR: Latest Inklecate and build JDK can be downloaded from the editor. +- EDITOR: Disable Particle Editor button. It doesn't support LWJGL3. +- LWJGL3 backend for desktop. That means support for JDK 17 and ARM architectures. +- TextRenderer now supports maxWidth. +- Smooth animation to center camera after finishing walking. +- Show text in screen at least for 0.5secs before skipping it. +- Delete 3D support. +- Now we can use ':' in Ink to indicate the actor talking. '>' is still supported. +- Updated Blade Ink to v1.1.2. +- Minimum supported iOS version to 11.0. +- Bump spine runtimes to v4.1.0. +- Updated libgdx to v1.12.0. +- Updated packr version. +- A lot of bugs fixed (see git log). + +## [4.1.0] + +- EDITOR: Text filter for scene and actor lists. +- EDITOR: Button to show/hide actors in the scene. +- Ink: Support for multi flow. +- InkRunAction can pass params to Ink paths. +- New InkCancelAction action. +- Updated Blade Ink to v1.0.0. +- Updated libgdx to v1.10.0. +- Updated packr version. + +## [4.0.2] + +- Controller (gamepad) support. +- .aab package generation for Android. +- In panel showing choose options, up/down buttons now have animation. +- Update libgdx to latest version 1.9.13. +- Better Ink text extraction for I18N. +- Fix: Bug deleting animation if initial animation is not set. + +## [4.0.1] + +- Fix error serializing cb when Ink library is not used. +- Fix error creating resolution when there are atlases with subfolders. +- Fix Android launcher to make expansion files (.obb) works again. + +## [4.0.0] + +- Fix error when android keystore path had spaces. +- Added scene counter in the editor ui. +- Updated ios minosversion to 8. +- Better calc of speed when walking and fake depth is used. + +## [3.2.5] + +- Some validations adding/editing animations and verbs to avoid errors. +- Fixed dealing with OpenAL bug in credits screen. +- Fixed bug extracting ink texts. + +## [3.2.4] + +- Added more external functions for Ink. +- Added support to load/save game preferences. +- Scale and Rotate actions now work with ui actors. +- Many bugs fixed. + +## [3.2.3] + +- Added "initVerb" param to the "Leave" action. This verb will be executed if set instead of the "init" verb. +- Now, the "init" verb doesn't run if the "test" verb is executed. +- Load/Save preferences support. +- Allow to move BaseActors in MoveToSceneAction. +- FIX: Scale and Rotate actions didn't work with ui actors. +- Save also callbacks that are not in the current scene. + +## [3.2.2] + +- Inventory button style now in the InventoryUI style. This allows to customize the inventory button by player. +- Update Blade Ink to v0.7.3 which fixes an important bug. +- A lot of bugs fixed (see git log). + +## [3.2.1] + +- Added bubble positioning parameters on ui.json. +- Better multiple inventory support in actions. +- Better Spine skin handling. +- Update Blade Ink to v0.7.2. +- A lot of bugs fixed (see git log). + +## [3.2.0] + +- Say Action: Talk animation also for text types PLAIN and SUBTITLE. +- Only save modified actor properties on savegames. +- New SetDesc action to change the actor descriptions. +- Added 'show_hotspots' config key to enable/disable the show hotspots feature. +- Added INSIDE property to IfAttrProperty action to check if an actor is inside other actor. +- Improve size of chapter files and savegames. +- Updated libgdx to v1.9.10 +- Updated Spine to v3.8. +- Update gradle to v5.4.1 + +## [3.1.2] + +- Animated ui icons and cursors. +- Update RoboVM to v2.3.7. +- Don't extract string expresions from ink files for i18n. +- Allow empty values in Property action. +- Added public methods to the SpineRenderer to get access to the current skeleton and animation. + +## [3.1.1] + +- Dialog to create the android keystore inside the editor. +- Label and text to warn about legacy dialogs. +- Added RandomPosition action. +- Added reload assets icon to scene list. +- Added support for combining skins in Spine. +- Delete last_project key if loadproject fails so the editor doesn't fail forever. +- Delete SetModelProp action and supporting library. It was not useful and make porting dificult. +- Added IN_UI if property. +- Fix: Now search in all inventories. +- Fix: Set skin now updates properly. + +## [3.1.0] + +- Update Spine runtime to v3.7 +- Dialog to compile Ink stories. +- Show 'Saved game' text when saved game to give user feedback. + +## [3.0.0] aka Johnny Bonasera 3 + +- Ink button in editor to link Ink stories with chapters. +- Better handling of up/down buttons when showing options. +- Improved debug info and fix tester bot. +- Update vis-ui lib to latest stable. +- FIX: Show warning message when a game is playing also if not saved before. +- FIX: Bug in edit anim spine atlas. +- FIX: Several fixes in InkManager handling concurrency. +- FIX: uiactors camera refresh. +- FIX: Bug saving current dialog actor. +- FIX: 'desktop:dist' task in template. + +## [2.2.0] + +- Java 11 support (Gradle v4.10.2). +- Update to libgdx v1.9.9. +- iOS 12 bug fix (robovm v2.3.5). +- Added property to change the text position of bubbles for character actors. +- Add max width/height in the create atlas dialog. +- Android SDK is not mandatory to create or edit projects. +- A lot of bugs fixed (see git log). + +## [2.1.4] + +- Now the editor works without having the Android SDK installed. +- FIX: Bug when moving target actor. +- FIX: Bug in 'Transition' action. +- FIX:'actorTextPosition' property in 'SetActorAttr' action wasn't working. + +## [2.1.3] + +- Support for several walkzones in a scene. Now walkzones are also actors. +- Added icons to translate, scale and rotate actors in editor. +- Android: Added runtime permission query when necessary to make expansion files work in newer android apis. +- EDITOR: Added play in fullscreen option. +- Added talking text position to characters. +- Update Blade Ink to v0.5.1. +- FIX: Reset pointer always when updating UI to avoid showing last pointer when changing scene. +- FIX: Bad bubble alignment showing small texts. +- FIX: Bug creating/deleting chapters in editor. +- FIX: The current scene was setting twice when loading a saved game triggering an error. +- FIX: The dialog option was showing for 1 frame when autoselected enabled. + +## [2.1.2] + +- Sprite Actors can have different scales in X and Y axis allowing unproportional scaling. +- Check project version before loading + show loading message. +- Fix gradle deprecation warnings. +- Continue loading custom classes if some error found in one of them. + +## [2.1.1] + +- Fix several UI bugs: inventory button doesn't hide, dialog not working well when autoselect one option and text + doesn't show when returning to a scene without init. +- Add -s parameter to DestkopLauncher. + +## [2.1.0] + +- TextManager now sets the talk animation for characters. This ease characters to have conversations in the background. +- Code refactor to get rid of the 'World' singleton. This breaks custom action backwards compatibility. +- Leave action have the param 'init' to avoid call the init verb when false. This allows to change between scenes + without worrying about losing the state. +- Update blade-ink lib to v0.5.0. +- Upgrade to gradle 2.6. Maybe it needs some more tweaks. +- Added new text type 'UI' to show debug or ui messages. +- Added one click 'action' verb. +- Don't use ref point in position actions if the target actor is the same that the current actor. +- All intensive tasks (load music, voices and ink) are now executed in a background thread. +- FIX: filteredbox height bigger than screen and don't show the last element. + +## [2.0.6] + +- All intensive tasks (load music, voices and ink) are now executed in a background thread. + +- Added search box to combo boxes. +- Added desktop files to generate Flatpak package. +- Don't generate the key for desc if exists when editing actor. Better generation of not duplicated keys. +- Safety nullchecks. +- Error message if actor with same id exists when adding an actor to scene. +- RunVerb now uses the Verb IP. +- Added search box to combo boxes. +- Added desktop files to generate Flatpak package. + +## [2.0.2] + +- FIX: Stop voices when changing scene. +- FIX: Volume action musn't wait if duration=0 +- FIX: Changes to try to fix the OpenAL error in desktop + +## [2.0.1] + +- Added option to the create atlas dialog to allow generating .jpg atlases. +- Added build script custom parameter input box in the package dialog. +- FIX: Capture random music error on desktop in credit screen. + +## [2.0.0] + +- HelpScreen doesn't stretch in 4:3 aspect ratio. +- InkManager translation files support. +- Import ink texts in order. Better I18N checks. +- Add music volume fade support in MusicVolume action. +- VoiceManager doesn't hide texts, now waits to the calc time. +- FIX: bug when saving ink cb. + +## [1.3.5] + +- Added Spine's skins support. +- Choose the best matching 'use' verb when target and inventory actor have it. +- Added pitch parameter to sounds. +- Updated libgdx to v1.9.8. +- Special keys (testerbot, record, play, etc) only enabled in debug mode. +- Delete red tint in hotspots. +- Added sound input panel. +- FIX: Error in walking path calculation. +- FIX: running test scene in android. +- FIX: bad viewport configuration when pausing and restore the qqqgame when screen in 4:3. +- FIX: bug when setting ink property if it doesn't exists after load game. +- FIX: getCurrentTarget() in RunVerbAction. +- FIX: sound list reload when changing chapters. +- FIX: main class detection in desktop packaging. +- FIX: error reading Cb from InkManager. +- FIX: particles and bboxfromrenderer for resolutions other than 1. + +## [1.3.4] + +- Added currentTarget to verbs. +- Null checks in SoundManager before pause/resume sounds. +- Fix loading callbacks from saved inventories. +- Fix: Loop, volume and pan was not used when playing a sound. +- Missing fbo dispose. +- Fix: toString() instead of casting in getModelProp. + +## [1.3.3] + +- Added 'textStyle' attribute to character actors. +- Added basic QA rules/metrics of project. +- EDITOR: Understand SNAPSHOT versions when checking for updating versions. +- Actor 'tint' property are now used to draw inventory actors when dragged. +- Catch back key in android. +- Added load chapter option to the debug screen. +- Fix not showing saved games in tests folder. +- Fix error removing all items from inventory in 'DropItem' action. +- Fix error creating screenshots for savedgames in Mac. +- Fix crash when screenshot of a savegame doesn't exists. + +## [1.3.2] + +- Added Google Play expansion file support. +- Added 64 and 32 bit support when generating package for windows. Previously only 64 bits was supported. +- Bigger edit toolbar icons. +- Create initial scene in new projects. +- Fix: Recorder not recording dialog options. +- Add target scene to DropItemAction and mark RemoveInventoryItem action deprecated. +- Updated to libgdx v1.9.7. +- EDITOR: Fix testing not working with scenes with spaces in ID +- EDITOR: Fix nullpointer error when disabled imagen not exists. +- EDITOR: Fix bug when undo bbox points. + +## [1.3.1] + +- Asset folder is created now in the project root. +- Updated Gradle to v4.0.2 +- FIX sound error preventing to save the game. + +## [1.3.0] + +- New Sound System. Now adding sounds is more usable. Backwards compatibility preserved. +- World properties can also be set in BladeEngine.properties. +- Added PLATFORM property. +- Added OpenURL action. +- Added actions for accessing to Ink variables: InkVariable and IfInkVariable actions. +- Added DIRECTION attribute to IfActorAttr action. +- Initial support for assets in the root folder. +- Ink: Change the ':' character talk separator by '>'. +- Set actor fake depth as boolean. +- Custom icon support for the 'leave' verb. +- Updated blade-ink to v0.4.3. +- Updated InGameConsole to v0.7.1. +- 'world.json' is now called 'world'. Old files can still be loaded. +- EDITOR: Add refPoint to the EditActorDialog. +- EDITOR: Undo bbox points, depth markers, ref. points and walkzone points. +- EDITOR: Added zoom keys: '+' and '-'. +- EDITOR: Filter .zip files in File Input Dialog when selecting JRE in the package dialog. +- And many fixes Fixes. + +## [1.2.7] + +- Added secondary animation support for Spine actors. +- Added 'keepDirection' param to Animation action. +- Added 'target' actor to position in Camera action. +- Added 'LAYER' and 'IN_SCENE' params in IfAttr action. +- Updated Spine plugin to latest Spine version. +- Updated blade-ink dependency to v0.4.2 +- Added title image and aligment to the menu screen. +- EDITOR: Edit Animation dialog now sets the initial source based in previous sources. + +## [1.2.6] + +- Actors in inventory can be animated now. +- Added UI actors: Actors that stays in all scenes not affected by scrolling nor any other scene camera effect. Normally + used to create UI buttons. +- Multiline texts can have a voice file per line using a '#' mark in each line. +- Check for Ink engine errors after each line. +- FIX: SpineRenderer serialization error when loading. +- FIX: error loading objects in inventory when they have changed from layer. + +## [1.2.5] + +- Update Robovm to v2.3.1 fixing problems with the latest XCode update. +- FIX: VoiceManager show log and continues when the voice file is not found instead of crash. +- FIX: voice was mandatory in the edit option dialog. +- FIX: Show only the first line of comment actions in the action list. + +## [1.2.4] + +- NEW BIG FEATURE: Voice support. +- OSX Sandbox support to support releasing the game in the Mac App Store. +- Updated Spine engine to v3.5.51 +- When adding new assets throught the Asset List view, create the asset folder if it doesn't exist. +- FIX: Scene parameter in LoadChapterAction incorrect. +- FIX: Scale and Rotation actions. +- FIX: Loading integer atributes in actions. +- FIX: Serialization error in TextManager. + +## [1.2.3] + +- Added 'ignoreWalkZone' parameter to Goto. +- Get rid of SpriteActor restriction in PositionAnim target. +- Update to gradle v3.4.1 +- EDITOR: Dialogs can exit the editor borders. +- EDITOR: Scroll the actor list when actor is selected in ScnWidget. +- FIX: bad rotation in Spine actors. +- FIX: Error disposing source in getInternalAnimations. +- FIX: Add WHITE tint to Sprite actor in anim if the actor doesn't have + it. + +## [1.2.2] + +- Added I18N support to Text Actors. +- New AlphaAnimation action to animate the alpha channel of sprite actors. +- Added 'orgAlign' to Sprite Actors to set the origin for scale and rotation. +- Updated library libgdx to v1.9.6 +- AnimationRenderer refactor. +- Added text align to text actors. +- FIX: tint for text actors not working. +- FIX: Error saving/loading tweens state. +- EDITOR: Added icons for text and particle actors. +- EDITOR FIX: Problem when changing id to animations. + +## [1.2.1] + +- Added music support to the default Menu screen. +- Added rotation property to SetActorAttr action. +- FIX: Check if renderer is an AnimationRenderer when changing the selected animation in the editor. +- FIX: Error disposing Spine actors when creating new project. +- FIX: Error creating new project in Linux and MacOS due to CRLF in gradlew. + +## [1.2.0] + +- Added particle effect actors. +- Added text actors. +- Added rotation to actors. +- Several improvements to the ink integration. Updated 'blade-ink' package to v0.4.0. +- Updated 'packr' package to the latest version. +- Toggle debug mode tapping in the menu version label. +- Autodetect the Android SDK version installed. +- EDITOR: Show actor position when editing actor for precision positioning. +- EDITOR: Added color selector dialog for color input. +- EDITOR FIX: Init animation was not showing properly. + +## [1.1.1] + +- Added new action to add an integer value to a property to increment/decrement it. Useful to create counters. +- Add MacOS .icon when packaging. +- Add .app extension to the MacOS package. +- Added autoselect style property to the DialogUI. +- Ink support cleanup. +- FIX: music was stopped changing from scene when a change to the + loading screen was needed. + +## [1.1.0] + +- Ink support. (http://www.inklestudios.com/ink/) +- Update libgdx version to 1.9.5. +- Improve text styles in ui.json for TextManager. +- Added 'target' parameter to TextAction. +- Added tint/color animation support. +- Added interpolation to camera animation. + +## [1.0.3] + +- FIX: error loading recordings from 'tests' folder. + +## [1.0.2] + +- Added support to have several games packaged in the same application. +- Reset previous walk animation before new walk animation added. + +## [1.0.1] + +- Music not working for iOS in CreditScreen +- EDITOR: FIX bug when setting the init scene. The document wasn't marking as modified. + +## [1.0.0] + +- Images can be localized now. +- Added xxxhdpi icon folder to Android. +- Better scroll handling in text areas. +- Added "show console" checkbox in the view menu. + +## [0.9.19] + +- EDITOR: Use libgdx FileChooser and get rid of JavaFX to avoid freezing when loading projects. +- EDITOR: Added UI Atlas import/export buttons in Tools menu. +- EDITOR: Added scroll bars to Text Boxes. +- EDITOR: Add "clean" target in IOS because the app is not signing well if not cleaning first. + +- Added tags to Skin styles to increase the ui.json readability. +- Better scroll amount calculation in dialog ui scroll buttons. + +- FIX: error when loading project with custom actions. Not detecting no compiled project properly. +- FIX: DisableAction must not be visible in the action combo. +- FIX: The editor was losing the scroll focus when the log console was shown. + +## [0.9.18] + +- EDITOR: The Action list now supports multiple selection to copy, paste, show... use Shift and Ctrl keys to + multiselect. +- EDITOR: Added console log. Use F1 key to show/hide. +- EDITOR: Better scrollbars. Always showing now. +- Now the editor generates IOS packages ready to submit to the Apple Store. Fixed several config parameters related to + this problem. +- Added "Comment" action. +- Updated packr to v2.0. Better desktop packages are generated now. +- Dialog option UI now shows buttons to scroll add and down when necessary. New styles added to ui.json. +- Added parameter in TextManagerUI style inside ui.json to set the subtitle Y position. +- Improvement to the pathfinder. Now the clap algorithm always returns a point inside the polygon. +- In IOS platform, sounds and music in ACC (.m4a) format are used if exists. As .ogg is not supported in IOS. +- FIX: The name of the loaded chapter was not set correctly, causing saved games not loading the current chapter. +- FIX: Weird bug. Use toUpperCase with Locale.English to read enum values. +- FIX: Bad IOS splash screen orientation. + +## [0.9.17] + +- Updated libgdx library to v1.9.4. +- Added null sanity check for actor parameter in SayAction. + +## [0.9.16] + +- NEW FEAUTRE: The text manager can now show a character image/icon in texts. +- Added MusicVolumeAction +- Play recorded game directly if passed as parameter in command line. +- Added relative position to target in position and goto actions. +- Added animation param to SayAction. +- Added -aspect parameter to desktop launcher. +- Update spine plugin to latest spine runtime version. +- EDITOR: Save/Restore version in package dialog. +- EDITOR: Save/Restore selected scene. +- EDITOR: Show verb panel when no actor is selected to allow adding scene and + world verbs. + +- FIX: Reset UI when changing scene. +- FIX: CameraAction animation params not mandatory. +- FIX: Android Test: Uninstall android debug version before install. +- FIX: Count default value in AnimationAction. +- FIX: SceneActorInputPanel getText() when no actor is selected. +- FIX: bug pasting spine actors. + +## [0.9.15] + +- Ask for updating the engine version of the game if the editor detects that is old. +- Custom actions now are autodetected by the editor and handled as engine actions. +- Save view menu state. +- Show project path in window title. +- Select 'init' scene when loading a project. +- Ask for saving current project when loading or creating new project. +- Added preload parameter to sounds to avoid loading all scene sounds in init. +- FIX: Music was not restored from savedgames. +- FIX: Error in REVERSE_REPEAT animations. + +## [0.9.14] + +- Multiinventory support. +- EDITOR: Fix when adding custom actions. + +## [0.9.13] + +- Added new buttons in the Tools menu to test the scene in Iphone/Ipad emulator and device. +- Support for changing players in runtime: Added $PLAYER variable. +- Added actor Tint attribute to allow lighting effects. +- EDITOR: Disable not working HTML platform. +- Update RoboVM to Mobidevelop 2.1.0 release. +- Added 'initNewGame' and 'initSavedGame' verbs to allow calling actions when a game is started or loaded. +- Fix error in text position when drawing SUBTITLE texts. +- Fix action color serialize. +- DialogUI gets scrollbar style. +- Update fonts for better language support. +- Fix bug when loading project and scene scope is selected. +- Delete unused 'delay' field in AnimationDesc. +- Fix: bug in yoyo animatinons. + +## [0.9.12] + +- Added Refpoint to interactive actors. +- Support for fast leave scene when double click. +- Updated Spine Runtime library to latest Spine release. +- Updated to libgdx v1.9.3 + +## [0.9.11] + +- Unicode character support. Previously only ISO-8859-1 character set was supported. +- Shadow and outline font support. +- Editor fonts are now .ttf +- Added "Single Action" support to inventory. +- FIX: Hide inventory in cutmode +- EDITOR: Avoid dragging object by mistake when clicked to select it. +- FIX: Multiply position by scale for multiresolution support in TextAction. +- Better tolerance handling when dragging inventory objects. +- FIX: Use screen height instead of world height for size calculation in InventoryUI. + +## [0.9.10] + +- FIX: Bad width calculation in DialogUI. +- Change help screen language in runtime. +- Sets Ctrl+d to toggle debug mode. +- Catch 'BACK' key in android. + +## [0.9.9] + +- New music engine. +- I18N: language change support in runtime. +- EDITOR: Added I18N tools for importing and exporting texts in .tsv format for translation. +- EDITOR: Added button to play sounds in EditSoundDialog and SoundList. +- Added methods to MenuScreen to ease extension. +- FIX: Get desktop launcher properly when packaging. +- FIX: EndGameAction now returns true to stop the verb execution. +- FIX: bug playing music in credit screen. +- Doesn't play animation sounds when animation is in reverse mode. +- FIX: Pass debug flag when testing scene. +- FIX: In EditableSelectBox, check empty list before setting default value. + +## [0.9.8] + +- Show only ui state and time in screen debug text +- Add 'id' attribute to SoundFX. +- FIX: Pausing sounds when show menu. +- Support new properties in 'if' actions: in_inventory, interactive, current scene, previous scene and target actor in ' + use' verbs +- FIX: It was cleaning sound list when disposing sounds. +- FIX: bug when disposing Spine and sound assets. +- SoundAction: Delete stop parameter. Now the current sound stops if the play parameter is empty. +- EDITOR: Disable Spine event handling in editor. +- FIX: Flickering due to swapBuffer. +- More fault tolerant when loading actions: Action field not found. +- Change stopSound from actor for stopCurrentSound +- Doesn't play spine events in reverse mode. Spine doesn't works well in that case, maybe a spine bug? +- EDITOR: New View and Tools menu. 'Run on Android device' button. +- FIX: Inventory capacity error. Inventory now change its item size dynamically to increase his capacity. +- FIX: Bug obtaining the window title from properties in desktop launcher. +- FIX: bug saving interpolation +- Automatic generation of versions.properties +- Better version handling when packaging for android. +- Show game version in menu screen. +- Update UI ATLAS +- FIX: EDITOR bug in zindex not setting for interactive actor when editing. +- FIX: EDITOR bug setting interaction property in editor. Better interaction property handling. +- Prevent event trigger when retrieving assets +- FIX: added hotspot image +- 'Remove Savegame' button size depends on dpi + +## [0.9.7] + +- Better Load/Save game screen. +- Confirmation dialog when overwrite current game in new game or load game. +- Updated spine plugin to Spine v3 +- Show time in debug. Time is now long to avoid float overflow. +- Updated to libgdx 1.9.1 +- Android SDK not mandatory when creating a project. +- More fault tolerant when loading saved games. Good for patches. +- Saved games can be stored in 'tests' folder inside game. These games are distributed with the game and in debug mode + these saved games can be loaded. Good for testing. +- When creating a verb an icon can be specified. This icon will be showed in the UI. +- Add movement to the inventory button when picking an object. +- Doesn't hide inventory when running a verb. +- And tons of bug fixing. + +## [0.9.6] + +- Layer parallax feature +- Several fixes in atlasrenderer related with drawing atlases with striped whitespaces +- Drop lightmap support +- Fix inventory loading bug +- Fix inventory auto width calc +- Change default character actor speed +- Editor: add combo values in world props +- EDITOR: Fix losing player attr when editing actor. +- EDITOR: HTML not supported message +- Fix checking if a path is absolute in windows. +- Avoid nullpointer when lookat if animation doesn't exists in 3d sprite +- EDITOR: fixed NullPointer error when creating 3d sprite actor. +- Drop XML Loader + +## [0.9.5] + +- ENGINE: Added infinity text duration when duration < 0. +- ENGINE: fix: ImageRenderer check if currentAnimation==null in toString() +- EDITOR: align left actor panel to left. To always show the '+' button. +- ENGINE: fix sceneextendviewport world size calc. +- ENGINE: NEW ScreenPositionAction +- EDITOR: fixed bug when editing assets +- EDITOR: Fixed bug in TextInputPanel when text=null +- EDITOR: Fixed Issue #25. Error deleting elements from lists. +- EDITOR: fix: change world.json SayAction changed for LookatAction +- EDITOR: fix bug when paste IfAttr actions. +- EDITOR: Fix generated build.gradle BladeEngine.properties path reference when updating versions. + +## [0.9.4] + +- Compile custom classes when not found in loading project. +- Fix issue #23: Edit an existing actor +- Sets editor window size to 0.9 * screen size +- Better version control: + - Extract version strings from build.gradle to gradle.properties in games. + - Put versions in BladeEngine.properties when compiling games. + - Show versions in DebugScreen + - Added version to game model and saved games for further checks. + - Put version variables in game gradle.properties +- Bug fix adding assets because of bad filter strings. +- Get appName from gradle.properties +- fix little bug when loading project and the custom actions are not compiled +- Editor: Better msg handling: Message Dialog +- Change RECTANGLE to SUBTITLE type of Text +- Editor: adjust colors in skin for a more pleasant feel. +- update pathfinder classes for no warnings. +- Use Gdx library instead JavaFX to set the window size. +- Use enum toString() as key to retrieve custom screens implementation. + +## [0.9.3] + +- Fix error when interpolation=null + +## [0.9.2] + +- Issue #22 fixed. Something went wrong while creating project. +- Set document modified when changing player +- Walking speed depends on scale +- Better direction calculation +- fixes: Null checks in animation dialogs/widget +- Fix calculating position when speed!=1 in reversing animation. +- Some ajustements in Action annotations: Better description and required field + +## [0.9.1] + +- Fixes several bugs in the editor related to the big refactor. +- Created EndGameAction +- Action refactor. VerbRunner parameter instead of ActionCallback. + +## [0.9.0] + +- Game model and saved games are now in JSON format. + * XML is deprecated. Backward compatibility broken. + * Saved games are patch friendly. +- EDITOR: Big refactor. Editor uses engine model objects now. +- Change I18N file encoding from ISO-889-1 to UTF-8 + +## [0.8.10] + +### Added + +- Change to TEXT_INPUT for Lookat and Say actions text fields. + +### Fixed + +- fix: set last frame in atlasrenderer when reverse mode + +## [0.8.9] + +### Added + +- EDITOR: Added input panels for text input. +- Better aspect ratio support. Correct support for 4:3, 16:9 and 16:10. +- Pause the game when an exception/error is thrown and debug mode is + activated. +- Updated to libgdx v0.6.4 +- Text from dialog ui wrap to screen size. + +### Fixed + +- fix: stop processing ActionCallbackQueue when changing scene + +## [0.8.8] + +### Added + +- Interpolation support for position and scale actions +- Update to libgdx v1.6.2. WARNING: Projects have to be modified in order to work the IOS version. + More info: http://www.badlogicgames.com/wordpress/?p=3694 + +### Fixed + +- Compute BBox in renderer Refactor to allow recompute bbox when animation complete. +- Fix animationTime when reverse animation in SpineRenderer +- Fix save/game screen slot size +- EDITOR: fix when generating world keys for i18n + doesn't remove ui.* keys. + +## [0.8.7] + +### Fixed + +- Fix: use scale factor for speed in PositionAction +- Added ui missing translations for menu screen +- Spine RT updated to latest version + +## [0.8.6] + +### Fixed + +- Fix fakeDepthScale() calc: added world scale factor +- Change 'assets/test' folder name for 'assets/tests' when creating a project +- Some debugscreen changes +- Load/Save Game Screen improvements + +## [0.8.5] + +### Fixed + +- SetActorAttrAction: multiply position by scale +- Check because the ActionCallbackQueue can call to setCurrentScene() + +## [0.8.4] + +### Fixed + +- fix camera loading state +- fix bad casting when read saved game +- fix walking speed double scale multiply + +## [0.8.3] + +### Added + +- UI Fixes + - Inventory ui over inventory icon + - Edit verbs dialog improvement + - Custom autosize button + +## [0.8.2] + +### Added + +- Inventory improved + - Added configurable align (top, down, left, right, center) + - Added configurable autosize behaviour +- Added arrow icon for exits when showing hotspots +- EDITOR: Added several config properties in the Game Properties tab + +### Fixed + +-EDITOR: fix world width and height was not recalculated when loading + +## [0.8.1] + +### Fixed + +- Tester Bot fixes +- Dialog render fixes when character position is not inside the screen +- Dialog nullpointer fix when playing recorded files + +## [0.8.0] + +### Added + +- Added a Tester Bot that plays the game randomly +- Spine atlas in animations + +### Fixed + +- EDITOR: Dialog editing fix + +## [0.7.2] + +### Added + +- libgdx v1.5.6 update +- update to the latest spine libgdx runtime +- EDITOR: Enable/disable actions +- Backround images must be inside atlas now +- Added control actions +- Added ActorAttrAction +- GotoAction: Change margin. +- Added log when verb finished +- GotoAction: add anchor parameter +- PositionAction now works with BaseActors (no animation) + +### Fixed + +- EDITOR: fixes to inputpanels +- fix OptionInputPanel when mandatory +- Reset testScene when changing current scene +- ActorProps: Show pos for BaseActors +- EDITOR: change some edit defaults +- walkzone fix when dinamic obstacles +- fill animation/actor list when setText() + +## [0.7.1] + +- Action refactor +- EDITOR: Undo support +- EDITOR: Fake depth vector can be setting dragging ui markers +- Actor ZIndex +- RunVerb now allows iterating over a list of verbs +- Scene cache +- SpriteActor: scale support +- SpineRenderer: Reverse animation support +- Scene layer support + +## [0.6.9] + +- libgdx updated to v1.5.4 +- Sprite Actor Scale support +- Added scene state handling + +### Fixed + +- javadoc fixes for jdk 1.8 + +## [0.6.8] + +### Fixed + +- Editor only release: Fix bug when saving project + +## [0.6.7] + +### Added + +- Load/Save game screens +- libgdx updated to v1.5.3. + +### Fixed + +- fixed fillanimations combo bug. set selection to the first element +- Fix for windows gradle exec + +## [0.6.6] + +- creditscreen: set scroll speed resolution independent +- creditscreen: added background style. Style now obtained from skin + +### Fixed + +- fixed textureunpacker bug when image was rotated in atlas + +## [0.6.5] + +- better text size management for small screens +- text bubble smaller and better management + +### Fixed + +- fix ActionCallbackQueue serialization + +## [0.6.4] + +- ActionCallbackQueue serialization +- world defaultverbs serialization +- i18n UI support + +## [0.6.3] + +- Updated libgdx to 1.5.2 version +- Menu Screen Refactor +- Transition moved to World + +## [0.6.2] + +- i18n workflow in Editor working +- Added event handling in Spine plugin +- Editor dialog tree: edit and delete fixes +- fix CameraAction when no selecting any target +- fix enter/leave verb conflicts name. Rename to enter/exit +- fix xml action loading +- Call cb before cleaning text fifo +- fix RunVerb action in repeat + +## [0.6.1] + +- fix show assets folder +- fix when packaging android release (build.gradle bug) + +## [0.6.0] + +- Created Spine plugin and set as optional when creating a project. +- Refactor: FrameAnimation -> AnimationDesc, SpriteRenderer -> ActorRenderer +- EDITOR: fix several IOS related bugs. IOS Ipad/Iphone testing and working fine. +- EDITOR: fix create resolution. Now atlas upacking/packing is supported + +## [0.5.0] + +- Updated to libgdx 1.4.1 +- ENGINE: Debug screen with speed control, record/play games and go to any scene in runtime +- ENGINE: Material style buttons in engine UI. Better look and feel for inventory and pie menu. + +## [0.4.0] + +- ENGINE: Custom game UI Screen support + +## [0.3.2] + +- EDITOR: Fixed bug when running project without console + +## [0.3.1] + +- EDITOR: Fixed accessing opengl context issue when creating project in the new thread. + +## [0.3.0] + +- ENGINE: Action refactoring. WARNING: Names have changed. All previous games are not compatible. +- ENGINE: New DebugScreen (Work in progress) +- ENGINE: Change speed support for fastforward. +- ENGINE: The blade-engine.jar are now in Maven Central. When creating a new game, the Maven dependency is added instead + of adding the engine jar in libs folder. + +## [0.2.0] + +- EDITOR: Fixed NullPointer error when creating project +- EDITOR: Threads for long tasks to show UI message status +- EDITOR: FIXED packaging with embedded JRE. +- ENGINE: CreditsScreen fonts now obtained from Skin + +## [0.1.0] + +- Initial release diff --git a/README.md b/README.md index c562b4f7a..833b09cce 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,90 @@ Bladecoder Adventure Engine =========================== -The **Bladecoder Adventure Engine** is a set of tools to create interactive graphic adventures (classical point ant click games). +The **Bladecoder Adventure Engine** is a set of tools to create interactive graphic adventures (classical point and +click games). -I think that this type of games is a great medium to tell stories and the new mobile devices provides a big opportunity to rebird and evolve them. +I think that this type of games are a great medium to tell stories and mobile devices provide a big opportunity to +rebirth and evolve them. -By creating Bladecoder Adventure Engine, I want to create a platform to tell stories. Interactive stories with modern graphics, animations and music. +By creating the **Bladecoder Adventure Engine**, I want to create a platform to tell stories. Interactive stories with +modern graphics, animations and music. -The Bladecoder Adventure Engine is composed by the following subprojects: +The **Bladecoder Adventure Engine** is composed of the following subprojects: -* **adventure-composer**: It ss the graphical editor for creating point and click games. -* **blade-engine**: It is the engine to run the games creates with the adventure-composer. - -The **Bladecoder Adventure Engine** is developped using the [LibGDX](http://libgdx.badlogicgames.com/) framework and the projects generates a layout similar to any LibGDX project, this lowers the learning curve and ease the development and deploy in several platforms. +* **adventure-editor**: the graphical editor for creating point and click games. +* **blade-engine**: the engine to run the games created with `adventure-editor`. -### Adventure Composer -The Adventure Composer is a graphical editor to create full point and click games with minimal programming. +The **Bladecoder Adventure Engine** has been developed using the [LibGDX](http://libgdx.badlogicgames.com/) framework +and the project generates a layout similar to any LibGDX project. This lowers the learning curve and eases development +and deploy on several platforms. -![adventure composer 2014-09-26](https://cloud.githubusercontent.com/assets/6229260/4420346/1d3a1b8a-4578-11e4-8eec-415f5e27c005.png) +### Adventure Editor + +The **Adventure Editor** is a graphical editor to create full point and click games with minimal programming. + +![adventure editor 2014-09-26](https://cloud.githubusercontent.com/assets/6229260/4420346/1d3a1b8a-4578-11e4-8eec-415f5e27c005.png) ### Blade Engine + The Engine has the following features: -* Multi platform support: Android, IOS, Desktop (windows, OSX, Linux) and HTML -* Several animation techniques: sprite/atlas animation, Spine (cutout) animation and 3d model animation -* 3d character support -* Multiresolution to deal with differents densities and screen sizes -* Multilanguaje support + +* Multi platform support: Android, IOS and Desktop (Windows, OSX and Linux) +* Several animation techniques: sprite/atlas animation and Spine (cutout) animation +* Multiresolution to deal with different densities and screen sizes +* Multilanguage support +* Use of the [Ink](https://www.inklestudios.com/ink/) language to create dialogs and puzzles easily. ### The Goddess Robbery -The **Bladecoder Adventure Engine** is currently under continous development and it is almost ready for production. The Goddess Robbery is a test game created to show the features of the Engine. +The **Bladecoder Adventure Engine** is currently under continuous development and it's ready for production. **The +Goddess Robbery** is a test game created to show the features of the Engine. + +The source of **The Goddess Robbery** can be +downloaded [here](https://github.com/bladecoder/bladecoder-adventure-tests/tree/master/venus) and it's useful to learn +how to use the **Adventure Editor**. + +**The Goddess Robbery** is also available for Android devices at the Google Play Store. + +[![The Goddess Robbery on Google Play](http://i.imgur.com/yn6RYuX.png)](https://play.google.com/store/apps/details?id=org.bladecoder.engine) -The source of **The Goddess Robbery** can be downloaded [here](https://github.com/bladecoder/bladecoder-adventure-tests/tree/master/venus) and it is useful to learn how to use the **Adventure Composer**. +### Documentation -The Goddess Robbery is also available for Android devices at the Google Play Store. +All available documentation is in the [wiki page](https://github.com/bladecoder/bladecoder-adventure-engine/wiki). The +documentation is not good enough and needs to improve, we are working on it. Meanwhile you can download and look into +the [test projects](https://github.com/bladecoder/bladecoder-adventure-tests/). -[![The Goddess Robbery on Google Play](http://developer.android.com/images/brand/en_app_rgb_wo_60.png)](http://play.google.com/store/apps/details?id=com.bladecoder.engine) +### Download latest release + +Check the [release page](https://github.com/bladecoder/bladecoder-adventure-engine/releases/latest) to download the +latest version. + +For Linux users, there is a Flatpack package with all the dependencies included. + +Download on Flathub ### Building and running -In order to compile, build and run the engine, the Java platform is necessary. The project uses Gradle to build and package. + +In order to compile, build and run the engine, the Java platform is necessary. The project uses Gradle to build and +package. Build: $ ./gradlew build -Run the Adventure Composer: +Run the Adventure Editor: $ ./gradlew run -Create a distribution package for the Adventure Composer: +Create a distribution package for the Adventure Editor: $ ./gradlew distZip -A zip package ready for distribution is created in the folder 'bladecoder-adventure-engine/adventure-composer/build/distributions' +A zip package ready for distribution is created in the folder ' +bladecoder-adventure-engine/adventure-editor/build/distributions' ### License -Bladecoder Adventure Engine is licensed under the [Apache 2 License](http://www.apache.org/licenses/LICENSE-2.0.html), meaning you -can use it free of charge, without strings attached in commercial and non-commercial projects. - +The **Bladecoder Adventure Engine** is licensed under +the [Apache 2 License](http://www.apache.org/licenses/LICENSE-2.0.html), meaning you +can use it free of charge, without strings attached in commercial and non-commercial projects. diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/paytone-one-18_00.png b/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/paytone-one-18_00.png deleted file mode 100644 index 5ec445b67..000000000 Binary files a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/paytone-one-18_00.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/ubuntu-light-12_00.png b/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/ubuntu-light-12_00.png deleted file mode 100644 index fb9d49564..000000000 Binary files a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/ubuntu-light-12_00.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/ubuntu-medium-14_00.png b/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/ubuntu-medium-14_00.png deleted file mode 100644 index 921f82c70..000000000 Binary files a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/ubuntu-medium-14_00.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/icons-atlas.svg b/adventure-composer/assets-raw/editor/icons-atlas/icons-atlas.svg deleted file mode 100644 index 9f494da92..000000000 --- a/adventure-composer/assets-raw/editor/icons-atlas/icons-atlas.svg +++ /dev/null @@ -1,3569 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - Character Actor - Base Actor - Sprite Actor - FG Actor - - - - - - - - - - - - x,y - - - - - - - - - - - - - - animation - repeat - pickup - lookup - talk - use - init - test - leave - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - yoyo - - - - - custom - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Player - - - - - - P - - - - - - ON - - - - - OFF - - new - edit - delete - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - create - load - save - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Assets - - - - - - - - - - - - Assets - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Atlas - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_add.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_add.png deleted file mode 100644 index a43285a92..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_add.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_add_disabled.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_add_disabled.png deleted file mode 100644 index 1f36f1bc7..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_add_disabled.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_check.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_check.png deleted file mode 100644 index 7a87b4781..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_check.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_check_disabled.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_check_disabled.png deleted file mode 100644 index 9abe3fce3..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_check_disabled.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_closed.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_closed.png deleted file mode 100644 index a293e6152..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_closed.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_copy.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_copy.png deleted file mode 100644 index 3ef428b55..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_copy.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_copy_disabled.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_copy_disabled.png deleted file mode 100644 index 86c0bf16d..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_copy_disabled.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_create_all.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_create_all.png deleted file mode 100644 index 35427870a..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_create_all.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_delete.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_delete.png deleted file mode 100644 index ed60c8cd5..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_delete.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_delete_disabled.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_delete_disabled.png deleted file mode 100644 index 17175c09f..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_delete_disabled.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_down.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_down.png deleted file mode 100644 index 6a32c6ffa..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_down.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_down_disabled.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_down_disabled.png deleted file mode 100644 index 0a8b2fe64..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_down_disabled.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_edit.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_edit.png deleted file mode 100644 index 175d38e88..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_edit.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_edit_disabled.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_edit_disabled.png deleted file mode 100644 index 80fd164b7..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_edit_disabled.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_left.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_left.png deleted file mode 100644 index 95695e571..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_left.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_left_disabled.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_left_disabled.png deleted file mode 100644 index 8711b527c..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_left_disabled.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_open.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_open.png deleted file mode 100644 index 53bf6e0ec..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_open.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_paste.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_paste.png deleted file mode 100644 index 1339276c7..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_paste.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_paste_disabled.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_paste_disabled.png deleted file mode 100644 index 62cc1ecb9..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_paste_disabled.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_right.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_right.png deleted file mode 100644 index d5498582f..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_right.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_right_disabled.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_right_disabled.png deleted file mode 100644 index c5be53067..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_right_disabled.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_up.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_up.png deleted file mode 100644 index 993e32e7c..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_up.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_up_disabled.png b/adventure-composer/assets-raw/editor/icons-atlas/images/ic_up_disabled.png deleted file mode 100644 index 7cc69133e..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_up_disabled.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/title.png b/adventure-composer/assets-raw/editor/icons-atlas/images/title.png deleted file mode 100644 index d19ed80c4..000000000 Binary files a/adventure-composer/assets-raw/editor/icons-atlas/images/title.png and /dev/null differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/title.svg b/adventure-composer/assets-raw/editor/icons-atlas/title.svg deleted file mode 100644 index dce115f8c..000000000 --- a/adventure-composer/assets-raw/editor/icons-atlas/title.svg +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - AdventureCOMPOSER - - - - - diff --git a/adventure-composer/assets-raw/engine/gen-default-icons.sh b/adventure-composer/assets-raw/engine/gen-default-icons.sh deleted file mode 100755 index 937a9eb71..000000000 --- a/adventure-composer/assets-raw/engine/gen-default-icons.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -#ANDROID ICONS -inkscape -w 144 -h 144 --export-area-page --export-png=../../src/main/resources/projectTmpl/android/res/drawable-xxhdpi/ic_launcher.png engine-default-icon.svg; -inkscape -w 96 -h 96 --export-area-page --export-png=../../src/main/resources/projectTmpl/android/res/drawable-xhdpi/ic_launcher.png engine-default-icon.svg; -inkscape -w 72 -h 72 --export-area-page --export-png=../../src/main/resources/projectTmpl/android/res/drawable-hdpi/ic_launcher.png engine-default-icon.svg; -inkscape -w 48 -h 48 --export-area-page --export-png=../../src/main/resources/projectTmpl/android/res/drawable-mdpi/ic_launcher.png engine-default-icon.svg; -#inkscape -w 36 -h 36 --export-area-page --export-png=../../src/main/resources/projectTmpl/android/res/drawable-ldpi/ic_launcher.png engine-default-icon.svg; - -inkscape -w 512 -h 512 --export-area-page --export-png=../../src/main/resources/projectTmpl/android/ic_launcher-web.png engine-default-icon.svg; - - -#DESKTOP -inkscape -w 16 -h 16 --export-area-page --export-png=../../src/main/resources/projectTmpl/desktop/src/icons/icon16.png engine-default-icon.svg; -inkscape -w 32 -h 32 --export-area-page --export-png=../../src/main/resources/projectTmpl/desktop/src/icons/icon32.png engine-default-icon.svg; -inkscape -w 128 -h 128 --export-area-page --export-png=../../src/main/resources/projectTmpl/desktop/src/icons/icon128.png engine-default-icon.svg; - -#IOS -inkscape -w 57 -h 57 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Icon.png engine-default-icon.svg; -inkscape -w 114 -h 114 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Icon@2x.png engine-default-icon.svg; -inkscape -w 72 -h 72 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Icon-72.png engine-default-icon.svg; -inkscape -w 144 -h 144 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Icon-72@2x.png engine-default-icon.svg; - diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/back.png b/adventure-composer/assets-raw/engine/ui-atlas/images/back.png deleted file mode 100644 index 8da79590c..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/back.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/border_rect2.9.png b/adventure-composer/assets-raw/engine/ui-atlas/images/border_rect2.9.png deleted file mode 100644 index c9814d1db..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/border_rect2.9.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/border_rect4.9.png b/adventure-composer/assets-raw/engine/ui-atlas/images/border_rect4.9.png deleted file mode 100644 index 4f9ba7708..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/border_rect4.9.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/bubblepointer.png b/adventure-composer/assets-raw/engine/ui-atlas/images/bubblepointer.png deleted file mode 100644 index c3c3e0bfe..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/bubblepointer.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/circle.png b/adventure-composer/assets-raw/engine/ui-atlas/images/circle.png deleted file mode 100644 index c8529e378..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/circle.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/circle_border.png b/adventure-composer/assets-raw/engine/ui-atlas/images/circle_border.png deleted file mode 100644 index 498c373a7..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/circle_border.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/circle_button.png b/adventure-composer/assets-raw/engine/ui-atlas/images/circle_button.png deleted file mode 100644 index 0e58041c9..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/circle_button.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/config.png b/adventure-composer/assets-raw/engine/ui-atlas/images/config.png deleted file mode 100644 index b7df82a44..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/config.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/credits.png b/adventure-composer/assets-raw/engine/ui-atlas/images/credits.png deleted file mode 100644 index 277777e95..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/credits.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/help.png b/adventure-composer/assets-raw/engine/ui-atlas/images/help.png deleted file mode 100644 index b736d8a22..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/help.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/hotspotpointer.png b/adventure-composer/assets-raw/engine/ui-atlas/images/hotspotpointer.png deleted file mode 100644 index 3ad0841d7..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/hotspotpointer.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/inventory.png b/adventure-composer/assets-raw/engine/ui-atlas/images/inventory.png deleted file mode 100644 index b22bf4313..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/inventory.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/inventory_plain.png b/adventure-composer/assets-raw/engine/ui-atlas/images/inventory_plain.png deleted file mode 100644 index 3dec40438..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/inventory_plain.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/leave.png b/adventure-composer/assets-raw/engine/ui-atlas/images/leave.png deleted file mode 100644 index 8e9b0e853..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/leave.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/left.png b/adventure-composer/assets-raw/engine/ui-atlas/images/left.png deleted file mode 100644 index ff7332f5e..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/left.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/lookat.png b/adventure-composer/assets-raw/engine/ui-atlas/images/lookat.png deleted file mode 100644 index 36bebe2f6..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/lookat.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/menu.png b/adventure-composer/assets-raw/engine/ui-atlas/images/menu.png deleted file mode 100644 index 9dc526233..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/menu.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/pack.json b/adventure-composer/assets-raw/engine/ui-atlas/images/pack.json deleted file mode 100644 index 8f1f6afb6..000000000 --- a/adventure-composer/assets-raw/engine/ui-atlas/images/pack.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - pot: false, - paddingX: 4, - paddingY: 4, - bleed: true, - edgePadding: true, - duplicatePadding: false, - rotation: false, - minWidth: 16, - minHeight: 16, - maxWidth: 1024, - maxHeight: 1024, - square: false, - stripWhitespaceX: false, - stripWhitespaceY: false, - alphaThreshold: 0, - filterMin: MipMapLinearNearest, - filterMag: Nearest, - wrapX: ClampToEdge, - wrapY: ClampToEdge, - format: RGBA8888, - alias: true, - outputFormat: png, - jpegQuality: 0.9, - ignoreBlankImages: true, - fast: false, - debug: false, - combineSubdirectories: false, - flattenPaths: false, - premultiplyAlpha: false, - useIndexes: true, - limitMemory: true, - grid: false, - scale: [1], - scaleSuffix: [""], -} diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/pickup.png b/adventure-composer/assets-raw/engine/ui-atlas/images/pickup.png deleted file mode 100644 index 834394ce2..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/pickup.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/pie.png b/adventure-composer/assets-raw/engine/ui-atlas/images/pie.png deleted file mode 100644 index a68658504..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/pie.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/pointer.png b/adventure-composer/assets-raw/engine/ui-atlas/images/pointer.png deleted file mode 100644 index 56c185d0b..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/pointer.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/quit.png b/adventure-composer/assets-raw/engine/ui-atlas/images/quit.png deleted file mode 100644 index eed4ec27b..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/quit.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/reload.png b/adventure-composer/assets-raw/engine/ui-atlas/images/reload.png deleted file mode 100644 index 149bdfa8a..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/reload.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/right.png b/adventure-composer/assets-raw/engine/ui-atlas/images/right.png deleted file mode 100644 index cd952186c..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/right.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/talkto.png b/adventure-composer/assets-raw/engine/ui-atlas/images/talkto.png deleted file mode 100644 index 45dbe85e6..000000000 Binary files a/adventure-composer/assets-raw/engine/ui-atlas/images/talkto.png and /dev/null differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/ui.svg b/adventure-composer/assets-raw/engine/ui-atlas/ui.svg deleted file mode 100644 index 984c76ff0..000000000 --- a/adventure-composer/assets-raw/engine/ui-atlas/ui.svg +++ /dev/null @@ -1,2591 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - POINTERS - - - - - - - - - - - - - - ICONS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/adventure-composer/build.gradle b/adventure-composer/build.gradle deleted file mode 100644 index 1fd5fcf4e..000000000 --- a/adventure-composer/build.gradle +++ /dev/null @@ -1,47 +0,0 @@ -apply plugin: "java" -apply plugin: 'application' - - group = 'com.bladecoder.engineeditor' - -mainClassName = 'com.bladecoder.engineeditor.Main' - -// java - sourceCompatibility = 1.7 - [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' - -jar { - manifest.attributes += [ - 'github': 'https://github.com/bladecoder/bladecoder-adventure-engine/', - 'license': 'Apache-2.0', - 'group': project.group, - 'version': project.version, - 'libgdx': gdxVersion, - 'java': targetCompatibility, - 'timestamp': System.currentTimeMillis() - ] -} - - javadoc { - title = "Adventure Composer" - options { - memberLevel = JavadocMemberLevel.PUBLIC - author true - setUse true - encoding "UTF-8" - } - } - -dependencies { - compile "com.badlogicgames.gdx:gdx:$gdxVersion" - compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" - compile "com.badlogicgames.gdx:gdx-tools:$gdxVersion" - compile fileTree(dir: 'libs', include: '*.jar') - compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion" - compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" - compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop" - compile "commons-io:commons-io:2.1" - compile "com.badlogicgames.packr:packr:1.2" - - //compile "com.bladecoder.engine:blade-engine:$bladeEngineVersion" - compile project(":blade-engine") -} diff --git a/adventure-composer/dist.ant.properties b/adventure-composer/dist.ant.properties deleted file mode 100644 index be43df3ec..000000000 --- a/adventure-composer/dist.ant.properties +++ /dev/null @@ -1,4 +0,0 @@ -name=AdventureComposer -main.class=com.bladecoder.engineeditor.ui.Main -version=0.1.0 -icon=./package-files/icon.ico \ No newline at end of file diff --git a/adventure-composer/dist.ant.xml b/adventure-composer/dist.ant.xml deleted file mode 100644 index 1987e359a..000000000 --- a/adventure-composer/dist.ant.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #!/bin/sh -cd "`dirname \"$0\"`" -./jre-linux64/bin/java -server -Xmx1024M -jar ${name}.jar "${@}" - - - #!/bin/sh -cd "`dirname \"$0\"`" -./jre-linux32/bin/java -server -Xmx1024M -jar ${name}.jar "${@}" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/Editor.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/Editor.java deleted file mode 100644 index c759eff90..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/Editor.java +++ /dev/null @@ -1,205 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor; - -import java.io.File; -import java.io.IOException; - -import javax.xml.transform.TransformerException; - -import com.badlogic.gdx.ApplicationListener; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.scenes.scene2d.ui.Dialog; -import com.badlogic.gdx.scenes.scene2d.ui.Image; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.SplitPane; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.utils.Align; -import com.badlogic.gdx.utils.Scaling; -import com.badlogic.gdx.utils.viewport.ScreenViewport; -import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.scneditor.ScnEditor; -import com.bladecoder.engineeditor.ui.ActorPanel; -import com.bladecoder.engineeditor.ui.AssetPanel; -import com.bladecoder.engineeditor.ui.ProjectPanel; -import com.bladecoder.engineeditor.ui.ProjectToolbar; -import com.bladecoder.engineeditor.ui.ScenePanel; -import com.bladecoder.engineeditor.utils.EditorLogger; -import com.bladecoder.engineeditor.utils.Message; - -//TODO: Show COPYRIGHT_STR + VERSION_STR -//TODO: Set TITLE in window bar. Set '*' in the title when modified -//TODO: Query if save project when exit - -public class Editor implements ApplicationListener { - public static final String VERSION_STR = "0.1.0 (Beta)"; - public static final String COPYRIGHT_STR = "2013 - Rafael García\nhttp://bladecoder.blogspot.com"; - public static final String TITLE = "Adventure Composer"; - -// public static final String SKIN = "skin/HoloSkin/Holo-dark-ldpi.json"; - // public static final String SKIN = "skin/uiskin.json"; - public static final String SKIN = "skin/BladeSkin/BladeSkin-ldpi.json"; - - Stage stage; - ScnEditor scnEditor; - Skin skin; - - @Override - public void create() { - skin = new Skin(Gdx.files.internal(SKIN)); - - EditorLogger.setDebug(); - EditorLogger.debug("CREATE"); - Ctx.project = new Project(); - Ctx.msg = new Message(skin); - Ctx.assetManager = new EditorAssetManager(); - - scnEditor = new ScnEditor(skin); - - /*** STAGE SETUP ***/ - stage = new Stage(new ScreenViewport()); - Gdx.input.setInputProcessor(stage); - - // RIGHT PANEL - ScenePanel scenePanel = new ScenePanel(skin); - ActorPanel actorPanel = new ActorPanel(skin); - - Table rightPanel = new Table(); - rightPanel.top().left(); - rightPanel.add(scenePanel).expand().fill(); - rightPanel.row(); - rightPanel.add(actorPanel).expand().fill(); - - SplitPane splitPaneRight = new SplitPane(scnEditor, rightPanel, - false, skin); - - // LEFT PANEL - ProjectPanel projectPanel = new ProjectPanel(skin); - AssetPanel assetPanel = new AssetPanel(skin); - Image img = new Image(Ctx.assetManager.getIcon("title")); - img.setScaling(Scaling.none); - img.setAlign(Align.left); - - Table leftPanel = new Table(); - leftPanel.top().left().padLeft(10); - leftPanel.add(img).expandX().fill().padBottom(20).padTop(20).padLeft(20); - leftPanel.row(); - leftPanel.add(new ProjectToolbar(skin)).expandX().fill(); - leftPanel.row(); - leftPanel.add(projectPanel).expand().fill(); - leftPanel.row(); - leftPanel.add(assetPanel).expand().fill(); - - SplitPane splitPaneLeft = new SplitPane(leftPanel, splitPaneRight, - false, skin); - splitPaneLeft.setFillParent(true); - splitPaneLeft.setSplitAmount(0.3f); - stage.addActor(splitPaneLeft); - - // LOAD LAST OPEN PROJECT - String lastProject = Ctx.project.getConfig().getProperty( - Project.LAST_PROJECT_PROP, ""); - - if (!lastProject.isEmpty() && new File(lastProject).exists()) { - try { - EditorLogger.debug("Loading last project: " + lastProject); - Ctx.project.loadProject(new File(lastProject)); - } catch (Exception e) { - EditorLogger.debug("Error loading last project: " - + e.getMessage()); - Ctx.project.closeProject(); - e.printStackTrace(); - } - } - - stage.setScrollFocus(scnEditor.getScnWidget()); - } - - @Override - public void render() { - Gdx.gl.glClearColor(0, 0, 0, 1); - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); - - stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); - stage.draw(); -// Table.drawDebug(stage); - } - - @Override - public void resize(int width, int height) { - EditorLogger.debug("RESIZE - w:" + width + " h:" + height); - - stage.getViewport().update(width, height, true); - } - - @Override - public void pause() { - - } - - @Override - public void resume() { - - } - - @Override - public void dispose() { - scnEditor.dispose(); - stage.dispose(); - - Ctx.project.saveConfig(); - -// try { -// Ctx.project.saveProject(); -// } catch (Exception ex) { -// System.out.println("Something went wrong while saving the project.\n"); -// ex.printStackTrace(); -// } - } - - public void exit() { - if (Ctx.project.getWorld().isModified() - || Ctx.project.getSelectedChapter().isModified()) { - new Dialog("Save Project", skin) { - protected void result(Object object) { - if (((Boolean) object).booleanValue()) { - try { - Ctx.project.saveProject(); - } catch (TransformerException | IOException e1) { - String msg = "Something went wrong while saving the actor.\n\n" - + e1.getClass().getSimpleName() - + " - " - + e1.getMessage(); - Ctx.msg.show(getStage(), msg, 2); - - e1.printStackTrace(); - } - } - - ((Main)Gdx.app).exitSaved(); - } - }.text("Save changes to project?").button("Yes", true) - .button("No", false).key(Keys.ENTER, true) - .key(Keys.ESCAPE, false).show(stage); - } else { - ((Main)Gdx.app).exitSaved(); - } - - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/Main.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/Main.java deleted file mode 100644 index f12e4136d..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/Main.java +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor; - -import java.io.File; - -import com.badlogic.gdx.Files.FileType; -import com.badlogic.gdx.backends.lwjgl.LwjglApplication; -import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; - -public class Main extends LwjglApplication { - - public static void main(final String[] args) { - LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration(); - - cfg.title = "Adventure Composer"; - cfg.width = 1920 / 2; - cfg.height = 1080 / 2; - - cfg.resizable = true; - // cfg.samples = 2; - // cfg.useGL30 = true; - - if (Main.class.getResource("/res/images/ic_app64.png") != null) - cfg.addIcon("images/ic_app64.png", FileType.Internal); - - if (Main.class.getResource("/res/images/ic_app32.png") != null) - cfg.addIcon("images/ic_app32.png", FileType.Internal); - - if (Main.class.getResource("/res/images/ic_app16.png") != null) - cfg.addIcon("images/ic_app16.png", FileType.Internal); - - parseArgs(args); - - new Main(new Editor(), cfg); - } - - private static void parseArgs(String[] args) { - for (int i = 1; i < args.length; i++) { - if (args[i - 1].equals("-f")) { - try { - File file = new File(args[i]).getCanonicalFile(); - Ctx.project.loadProject(file); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - } - } - - public Main(Editor editor, LwjglApplicationConfiguration cfg) { - super(editor,cfg); - } - - @Override - public void exit() { - ((Editor) listener).exit(); - } - - public void exitSaved() { - super.exit(); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/BaseDocument.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/BaseDocument.java deleted file mode 100644 index 260b9c841..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/BaseDocument.java +++ /dev/null @@ -1,400 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.model; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.HashMap; -import java.util.Properties; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -import com.bladecoder.engine.util.EngineLogger; - -public abstract class BaseDocument extends PropertyChange { - public static final String NOTIFY_ELEMENT_DELETED = "ELEMENT_DELETED"; - public static final String NOTIFY_ELEMENT_CREATED = "ELEMENT_CREATED"; - - public static final String NOTIFY_DOCUMENT_SAVED = "DOCUMENT_SAVED"; - - Document doc; - private String filename; - protected String modelPath; - - protected Properties i18n; - - protected boolean modified = false; - - public abstract String getRootTag(); - - public void create() throws ParserConfigurationException { - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - - doc = dBuilder.newDocument(); - - Element rootElement = doc.createElement(getRootTag()); - - doc.appendChild(rootElement); - - i18n = new Properties(); - - modified = true; - firePropertyChange(); - } - - protected String getI18NFilename() { - String name = getAbsoluteName(); - - return name.substring(0, name.lastIndexOf('.')) + ".properties"; - } - - private void loadI18N() { - String i18nFilename = getI18NFilename(); - - i18n = new Properties(); - try { - i18n.load(new FileInputStream(i18nFilename)); - ; - } catch (IOException e) { - EngineLogger.error("ERROR LOADING BUNDLE: " + i18nFilename); - } - } - - public String getTranslation(String key) { - if (key.isEmpty() || key.charAt(0) != '@' || i18n == null) - return key; - - return i18n.getProperty(key.substring(1), key); - } - - public void setTranslation(String key, String value) { - i18n.setProperty(key, value); - } - - private void saveI18N() { - String i18nFilename = getI18NFilename(); - - try { - i18n.store(new FileOutputStream(i18nFilename), filename); - } catch (IOException e) { - EngineLogger.error("ERROR WRITING BUNDLE: " + i18nFilename); - } - } - - public void load() throws ParserConfigurationException, SAXException, IOException { - File fXmlFile = new File(getAbsoluteName()); - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - doc = dBuilder.parse(fXmlFile); - - loadI18N(); - - modified = false; - } - - public void save() throws TransformerException, FileNotFoundException { - - if (!modified) - return; - - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - Transformer transformer = transformerFactory.newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - DOMSource source = new DOMSource(doc); - StreamResult result = new StreamResult(new FileOutputStream(getAbsoluteName())); - transformer.transform(source, result); - - saveI18N(); - - modified = false; - firePropertyChange(NOTIFY_DOCUMENT_SAVED); - } - - public boolean isModified() { - return modified; - } - - public String getFilename() { - return filename; - } - - public void setFilename(String filename) { - this.filename = filename; - } - - public String getAbsoluteName() { - return modelPath + "/" + filename; - } - - public void setModelPath(String p) { - modelPath = p; - } - - public String getRootAttr(String attr) { - return doc.getDocumentElement().getAttribute(attr); - } - - public String getElementAttr(String tag, String attr) { - NodeList nl = doc.getDocumentElement().getElementsByTagName(tag); - - if (nl.getLength() == 0) - return ""; - else - return ((Element) nl.item(0)).getAttribute(attr); - } - - public void setElementAttr(String tag, String attr, String value) { - NodeList nl = doc.getDocumentElement().getElementsByTagName(tag); - - Element e = null; - - if (nl.getLength() == 0) { - e = doc.createElement(tag); - - doc.getDocumentElement().appendChild(e); - } else { - e = (Element) nl.item(0); - } - - e.setAttribute(attr, value); - modified = true; - } - - public void setModified(boolean b) { - modified = b; - firePropertyChange(DOCUMENT_CHANGED, null, doc.getDocumentElement()); - } - - public Element getRootElement() { - return doc.getDocumentElement(); - } - - public Document getDocument() { - return doc; - } - - public Element cloneNode(Element parent, Element e) { - Element cloned; - - if (e.getOwnerDocument() != doc) { - cloned = (Element) doc.importNode(e, true); - } else { - cloned = (Element) e.cloneNode(true); - } - - parent.appendChild(cloned); - - if (cloned.getAttribute("id") != null && !cloned.getAttribute("id").isEmpty()) { - cloned.setAttribute("id", getCheckedId(cloned, cloned.getAttribute("id"))); - } - - setModified(cloned); - - return cloned; - } - - public void setModified(Element e) { - setModified(e.getTagName(), e); - } - - public void setModified(String property, Element e) { - modified = true; - firePropertyChange(property, null, e); - } - - public String getRootAttr(Element e, String a) { - return e.getAttribute(a); - } - - public void setRootAttr(Element e, String attr, String value) { - String old = e.getAttribute(attr); - - if (value != null && !value.isEmpty()) - e.setAttribute(attr, value); - else - e.removeAttribute(attr); - - modified = true; - firePropertyChange(attr, old, e); - } - - public void setRootAttr(String attr, String value) { - String old = getRootAttr(getRootElement(), attr); - - if (value != null && !value.isEmpty()) - getRootElement().setAttribute(attr, value); - else - getRootElement().removeAttribute(attr); - - modified = true; - firePropertyChange(attr, old, getRootElement()); - } - - public void deleteElement(Element e) { - e.getParentNode().removeChild(e); - - modified = true; - firePropertyChange(NOTIFY_ELEMENT_DELETED, e); - } - - public Element createVerb(Element e, String id, String state, String target) { - Element ev = doc.createElement("verb"); - ev.setAttribute("id", id); - if (state != null && !state.isEmpty()) - ev.setAttribute("state", state); - if (target != null && !target.isEmpty()) - ev.setAttribute("target", target); - - e.appendChild(ev); - - modified = true; - firePropertyChange("verb", null, e); - - return ev; - } - - public Element createAction(Element verb, String action, String actor, - HashMap params) { - Element e = doc.createElement(action); - if (actor != null && !actor.isEmpty()) - e.setAttribute("actor", actor); - - if (params != null) { - for (String k : params.keySet()) { - String v = params.get(k); - e.setAttribute(k, v); - } - } - - verb.appendChild(e); - - modified = true; - firePropertyChange("action", null, e); - - return e; - } - - public String getType(Element e) { - return e.getAttribute("type"); - } - - public NodeList getVerbs(Element e) { - // return e.getElementsByTagName("verb"); - - XPathFactory xpathFactory = XPathFactory.newInstance(); - XPath xpath = xpathFactory.newXPath(); - - try { - return (NodeList) xpath.evaluate("./verb", e, XPathConstants.NODESET); - } catch (XPathExpressionException ex) { - // TODO Auto-generated catch block - ex.printStackTrace(); - } - - return null; - } - - public NodeList getChildrenByTag(Element e, String tag) { - - XPathFactory xpathFactory = XPathFactory.newInstance(); - XPath xpath = xpathFactory.newXPath(); - - try { - return (NodeList) xpath.evaluate("./" + tag, e, XPathConstants.NODESET); - } catch (XPathExpressionException ex) { - // TODO Auto-generated catch block - ex.printStackTrace(); - } - - return null; - } - - public Element getElement() { - return doc.getDocumentElement(); - } - - /** - * Sets the element id avoiding duplicated ids - * - * @param e - * @param id - */ - public void setId(Element e, String id) { - String idChecked = getCheckedId(e, id); - - setRootAttr(e, "id", idChecked); - } - - public String getCheckedId(Element e, String id) { - String idChecked = id; - - if (e.getParentNode() instanceof Element) { - - NodeList nl = ((Element) e.getParentNode()).getElementsByTagName(e.getTagName()); - boolean checked = false; - - int i = 1; - - while (!checked) { - checked = true; - - for (int j = 0; j < nl.getLength(); j++) { - Element e2 = (Element) nl.item(j); - if (e2.getAttribute("id").equals(idChecked) && e != e2) { - i++; - idChecked = id + i; - checked = false; - break; - } - } - } - } - - return idChecked; - } - - public String getId(Element e) { - return e.getAttribute("id"); - } - - public Element createElement(Element parent, String type) { - Element es = doc.createElement(type); - parent.appendChild(es); - - return es; - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/ChapterDocument.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/ChapterDocument.java deleted file mode 100644 index 8d211db61..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/ChapterDocument.java +++ /dev/null @@ -1,648 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.model; - -import java.io.File; -import java.io.FileNotFoundException; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; - -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -import com.badlogic.gdx.math.Polygon; -import com.badlogic.gdx.math.Vector2; -import com.bladecoder.engine.actions.Param; -import com.bladecoder.engine.anim.AtlasFrameAnimation; -import com.bladecoder.engine.anim.FrameAnimation; -import com.bladecoder.engine.anim.Tween; -import com.bladecoder.engine.model.BaseActor; -import com.bladecoder.engine.model.AtlasRenderer; -import com.bladecoder.engine.model.ImageRenderer; -import com.bladecoder.engine.model.Scene; -import com.bladecoder.engine.model.SpineRenderer; -import com.bladecoder.engine.model.Sprite3DRenderer; -import com.bladecoder.engine.model.SpriteActor; -import com.bladecoder.engine.model.SpriteRenderer; -import com.bladecoder.engine.model.BaseActor.ActorLayer; -import com.bladecoder.engine.model.SpriteActor.DepthType; -import com.bladecoder.engine.polygonalpathfinder.PolygonalNavGraph; -import com.bladecoder.engine.util.EngineLogger; - -public class ChapterDocument extends BaseDocument { - - public static final String NO_RENDERER_ACTOR_TYPE = "no_renderer"; - public static final String ATLAS_ACTOR_TYPE = "atlas"; - public static final String SPRITE3D_ACTOR_TYPE = "3d"; - public static final String SPINE_ACTOR_TYPE = "spine"; - public static final String IMAGE_ACTOR_TYPE = "image"; - - public static final String BACKGROUND_LAYER = "background"; - public static final String FOREGROUND_LAYER = "foreground"; - public static final String DYNAMIC_LAYER = "dynamic"; - - public static final String ACTOR_TYPES[] = { NO_RENDERER_ACTOR_TYPE, - ATLAS_ACTOR_TYPE, SPINE_ACTOR_TYPE, SPRITE3D_ACTOR_TYPE, IMAGE_ACTOR_TYPE}; - - public static final String ACTOR_LAYERS[] = { BACKGROUND_LAYER, - FOREGROUND_LAYER, DYNAMIC_LAYER}; - - public static final String ANIMATION_TYPES[] = { "no_repeat", "repeat", - "yoyo", "reverse" }; - - public ChapterDocument(String modelPath) { - super(); - setModelPath(modelPath); - } - - @Override - public String getRootTag() { - return "chapter"; - } - - public void setFilenameFromId() { - setFilename(getId() + ".chapter"); - } - - public Element getActor(Element scn, String id) { - NodeList actorsNL = getActors(scn); - for (int j = 0; j < actorsNL.getLength(); j++) { - Element e = (Element) actorsNL.item(j); - if (id.equals(e.getAttribute("id"))) { - return e; - } - } - - return null; - } - - public NodeList getActors(Element scn) { - NodeList actors = scn - .getElementsByTagName("actor"); - - return actors; - } - - public NodeList getActions(Element verb) { - NodeList actions = verb - .getElementsByTagName("action"); - - return actions; - } - - public NodeList getScenes() { - NodeList s = getElement() - .getElementsByTagName("scene"); - - return s; - } - - public void addActor(Element scn, Element e) { - - scn.appendChild(e); - - modified = true; - firePropertyChange(ChapterDocument.NOTIFY_ELEMENT_CREATED, e); - } - - public void removeActor(Element scn, String id) { - Element e = getActor(scn, id); - - deleteElement(e); - } - - public Element getPlayer(Element scn) { - NodeList nl = scn.getElementsByTagName("player"); - - if (nl.getLength() == 0) - return null; - else - return (Element) nl.item(0); - } - - public void setRootAttr(Element e, String attr, String value) { - - String old = e.getAttribute(attr); - - if (value != null && !value.isEmpty()) - e.setAttribute(attr, value); - else - e.removeAttribute(attr); - - modified = true; - firePropertyChange(attr, old, value); - } - - public String getMusic(Element scn) { - return scn.getAttribute("music"); - } - - public void setMusic(Element scn, String filename, String loopMusic, - String initialMusicDelay, String repeatMusicDelay) { - if (filename != null && !filename.isEmpty()) - scn.setAttribute("music", filename); - else - scn.removeAttribute("music"); - - if (loopMusic != null && !loopMusic.isEmpty()) - scn.setAttribute("loop_music", loopMusic); - else - scn.removeAttribute("loop_music"); - - if (initialMusicDelay != null && !initialMusicDelay.isEmpty()) - scn.setAttribute("initial_music_delay", - initialMusicDelay); - else - scn.removeAttribute("initial_music_delay"); - - if (repeatMusicDelay != null && !repeatMusicDelay.isEmpty()) - scn.setAttribute("repeat_music_delay", - repeatMusicDelay); - else - scn.removeAttribute("repeat_music_delay"); - - modified = true; - firePropertyChange("music", scn); - } - - public String getBackground(Element scn) { - return scn.getAttribute("background"); - } - - public String getLightmap(Element scn) { - return doc.getDocumentElement().getAttribute("lightmap"); - } - - public void setBackground(Element scn, String value) { - setRootAttr(scn, "background", value); - } - - public void setLightmap(Element scn, String value) { - setRootAttr(scn, "lightmap", value); - } - - public Scene getEngineScene(Element s, int wWidth, int wHeight) { - Scene scn = new Scene(); - - scn.setId(getId()); - - scn.getCamera().create(wWidth, wHeight); - - String background = getBackground(s); - if (background != null && !background.isEmpty()) { - scn.setBackground(background, getLightmap(s)); - } - - String depthVector = s.getAttribute("depth_vector"); - if (!depthVector.isEmpty()) - scn.setDepthVector(Param.parseVector2(depthVector)); - - // GET ACTORS - NodeList actors = getActors(s); - for (int i = 0; i < actors.getLength(); i++) { - Element a = (Element) actors.item(i); - BaseActor actor = getEngineActor(a); - scn.addActor(actor); - - if (getId(a).equals(getRootAttr("player"))) { - scn.setPlayer((SpriteActor) actor); - } - } - - // WALK ZONE - Element wz = getWalkZone(s); - - if(wz != null) { - PolygonalNavGraph polygonalPathFinder = new PolygonalNavGraph(); - polygonalPathFinder.setWalkZone(Param.parsePolygon(wz.getAttribute("polygon"), wz.getAttribute("pos"))); - - scn.setPolygonalNavGraph(polygonalPathFinder); - - NodeList obstacles = wz.getElementsByTagName("obstacle"); - for (int i = 0; i < obstacles.getLength(); i++) { - Element o = (Element) obstacles.item(i); - - polygonalPathFinder.addObstacle(Param.parsePolygon(o.getAttribute("polygon"), o.getAttribute("pos"))); - } - } - - return scn; - } - - public void create(String id) throws ParserConfigurationException, - FileNotFoundException, TransformerException { - create(); - setId(id); - setFilenameFromId(); - save(); - } - - public void rename(String newId) throws FileNotFoundException, - TransformerException { - - deleteFiles(); - - setId(newId); - setFilenameFromId(); - - save(); - } - - public void deleteFiles() { - File f = new File(getAbsoluteName()); - - f.delete(); - - // TODO delete all .properties - f = new File(getI18NFilename()); - f.delete(); - } - - public String getId() { - return doc.getDocumentElement().getAttribute("id"); - } - - public void setId(String id) { - setRootAttr(doc.getDocumentElement(), "id", id); - } - - public String toString() { - return getId(); - } - - /*********************** ELEMENT METHODS *************************/ - - /** - * Sets the actor id avoiding duplicated ids - * - * @param e - * @param id - */ - public void setActorId(Element scn, Element e, String id) { - NodeList actors = getActors(scn); - - boolean checked = false; - - int i = 1; - - String idChecked = id; - - while (!checked) { - checked = true; - - for (int j = 0; j < actors.getLength(); j++) { - Element ae = (Element) actors.item(j); - String id2 = ae.getAttribute("id"); - - if (id2.equals(idChecked) && e != ae) { - i++; - idChecked = id + i; - checked = false; - break; - } - } - } - - setRootAttr(e, "id", idChecked); - } - - public String getDesc(Element e) { - return getTranslation(e.getAttribute("desc")); - } - - public NodeList getFrameAnimations(Element e) { - return e.getElementsByTagName("frame_animation"); - } - - public Polygon getBBox(Element e) { - if (e.getAttribute("bbox").isEmpty()) - return null; - - return Param.parsePolygon(e.getAttribute("bbox")); - } - - public BaseActor getEngineActor(Element e) { - BaseActor a = null; - - String type = getType(e); - - if (type.equals(ATLAS_ACTOR_TYPE)) { - a = new SpriteActor(); - ((SpriteActor) a).setRenderer(new AtlasRenderer()); - } else if (type.equals(SPRITE3D_ACTOR_TYPE)) { - a = new SpriteActor(); - Sprite3DRenderer r = new Sprite3DRenderer(); - ((SpriteActor) a).setRenderer(r); - r.setSpriteSize(Param.parseVector2(e - .getAttribute("sprite_size"))); - - } else if (type.equals(SPINE_ACTOR_TYPE)) { - a = new SpriteActor(); - ((SpriteActor) a).setRenderer(new SpineRenderer()); - } else if (type.equals(IMAGE_ACTOR_TYPE)) { - a = new SpriteActor(); - ((SpriteActor) a).setRenderer(new ImageRenderer()); - } else if (type.equals(NO_RENDERER_ACTOR_TYPE)) { - a = new BaseActor(); - } else { - EngineLogger.error(" Wrong actor Type defined in XML"); - return null; - } - - - String layer = e.getAttribute("layer"); - if (layer.equals(BACKGROUND_LAYER)) { - a.setLayer(ActorLayer.BACKGROUND); - } else if (layer.equals(FOREGROUND_LAYER)) { - a.setLayer(ActorLayer.FOREGROUND); - } else { - a.setLayer(ActorLayer.DYNAMIC); - } - - - a.setId(getId(e)); - Polygon bbox = getBBox(e); - a.setBbox(bbox); - - if(bbox == null) { - bbox = new Polygon(); - a.setBbox(bbox); - - if(a instanceof SpriteActor) - ((SpriteActor) a).setBboxFromRenderer(true); - } - - Vector2 pos = getPos(e); - if(pos != null) - a.setPosition(pos.x, pos.y); - - a.setDesc(e.getAttribute("desc")); - - if (a instanceof SpriteActor) { - SpriteRenderer r = ((SpriteActor) a).getRenderer(); - - NodeList faList = getFrameAnimations(e); - - for (int i = 0; i < faList.getLength(); i++) { - Element faElement = (Element) faList.item(i); - - FrameAnimation fa = getEngineFA(type, faElement); - - r.addFrameAnimation(fa); - } - - if (!e.getAttribute("init_frame_animation").isEmpty()) { - ((SpriteActor) a).getRenderer().setInitFrameAnimation( - e.getAttribute("init_frame_animation")); - - } - - if(e.getAttribute("obstacle").equals("true")) - a.setWalkObstacle(true); - - // PARSE DEPTH TYPE - String depthType = e.getAttribute("depth_type"); - ((SpriteActor) a).setDepthType(DepthType.NONE); - - if (!depthType.isEmpty()) { - if (depthType.equals("vector")) - ((SpriteActor) a).setDepthType(DepthType.VECTOR); - } - } - - return a; - } - - public FrameAnimation getEngineFA(String type, Element faElement) { - FrameAnimation fa; - - if(type.equals(ATLAS_ACTOR_TYPE)) { - fa = new AtlasFrameAnimation(); - } else { - fa = new FrameAnimation(); - } - - fa.id = faElement.getAttribute("id"); - fa.source = faElement.getAttribute("source"); - - if (faElement.getAttribute("animation_type").isEmpty() - || faElement.getAttribute("animation_type").equalsIgnoreCase( - "repeat")) { - fa.animationType = Tween.REPEAT; - } else if (faElement.getAttribute("animation_type").equalsIgnoreCase( - "yoyo")) { - fa.animationType = Tween.PINGPONG; - } else { - fa.animationType = Tween.NO_REPEAT; - } - - if (!faElement.getAttribute("speed").isEmpty()) - fa.duration = Float.parseFloat(faElement.getAttribute("speed")); - - if (!faElement.getAttribute("delay").isEmpty()) - fa.delay = Float.parseFloat(faElement.getAttribute("delay")); - - if (!faElement.getAttribute("count").isEmpty()) - fa.count = Integer.parseInt(faElement.getAttribute("count")); - else - fa.count = Tween.INFINITY; - - if (!faElement.getAttribute("sound").isEmpty()) - fa.sound = faElement.getAttribute("sound"); - - if (!faElement.getAttribute("inD").isEmpty()) { - fa.inD = Param.parseVector2(faElement.getAttribute("inD")); - } - - if (!faElement.getAttribute("outD").isEmpty()) { - fa.outD = Param.parseVector2(faElement.getAttribute("outD")); - } - - if (!faElement.getAttribute("preload").isEmpty()) { - fa.outD = Param.parseVector2(faElement.getAttribute("preload")); - } - - if (!faElement.getAttribute("dispose_when_played").isEmpty()) { - fa.outD = Param.parseVector2(faElement.getAttribute("dispose_when_played")); - } - - return fa; - } - - public Vector2 getPos(Element e) { - return Param.parseVector2(e.getAttribute("pos")); - } - - public void setPos(Element e, Vector2 pos) { - if (pos == null) { - e.removeAttribute("pos"); - } else { - e.setAttribute("pos", Param.toStringParam(pos)); - } - - modified = true; - firePropertyChange("pos", e); - } - - public NodeList getDialogs(Element e) { - return e.getElementsByTagName("dialog"); - } - - public void setBbox(Element e, Polygon p) { - if (p == null) { - p = new Polygon(); - - float[] verts = new float[8]; - - verts[0] = 0f; - verts[1] = 0f; - verts[2] = 0f; - verts[3] = 200; - verts[4] = 200; - verts[5] = 200; - verts[6] = 200; - verts[7] = 0f; - - p.setVertices(verts); - } - - e.setAttribute("bbox", Param.toStringParam(p)); - - modified = true; - firePropertyChange("bbox", e); - } - - public Element createDialogOption(Element parent, String text, - String responseText, String verb, String next, String visible) { - Element e = doc.createElement("option"); - e.setAttribute("text", text); - if (responseText != null && !responseText.isEmpty()) - e.setAttribute("responseText", responseText); - if (verb != null && !verb.isEmpty()) - e.setAttribute("verb", verb); - if (next != null && !next.isEmpty()) - e.setAttribute("next", next); - if (visible != null && !visible.isEmpty()) - e.setAttribute("visible", visible); - - parent.appendChild(e); - - modified = true; - firePropertyChange("option", e); - - return e; - } - - public Element createWalkZone(Element scn, Polygon poly) { - Element e = doc.createElement("walk_zone"); - e.setAttribute("polygon", Param.toStringParam(poly)); - e.setAttribute("pos", Param.toStringParam(new Vector2(poly.getX(), poly.getY()))); - - scn.appendChild(e); - - modified = true; - firePropertyChange("walk_zone", e); - - return e; - } - - public void setWalkZonePolygon(Element scn, Polygon poly) { - Element e = getWalkZone(scn); - - if(e == null) - e = createWalkZone(scn, poly); - else { - e.setAttribute("polygon", Param.toStringParam(poly)); - e.setAttribute("pos", Param.toStringParam(new Vector2(poly.getX(), poly.getY()))); - } - - modified = true; - firePropertyChange("walk_zone", e); - - } - - public Element getWalkZone(Element scn) { - NodeList nl = scn.getElementsByTagName("walk_zone"); - Element e = null; - - if(nl.getLength() > 0) { - e = (Element) nl.item(0); - } - - return e; - } - - public void deleteWalkZone(Element scn) { - Element e = getWalkZone(scn); - - if(e != null) { - deleteElement(e); - } - - modified = true; - firePropertyChange("walk_zone", e); - } - - public Element createObstacle(Element scn, Polygon poly) { - Element e = doc.createElement("obstacle"); - e.setAttribute("polygon", Param.toStringParam(poly)); - e.setAttribute("pos", Param.toStringParam(new Vector2(poly.getX(), poly.getY()))); - - getWalkZone(scn).appendChild(e); - - modified = true; - firePropertyChange("obstacle", e); - - return e; - } - - public Element getObstacle(Element scn, int i) { - Element wz = getWalkZone(scn); - Element e = null; - - NodeList nl = wz.getElementsByTagName("obstacle"); - - e = (Element) nl.item(i); - - return e; - } - - public void setObstaclePolygon(Element scn, int i, Polygon poly) { - Element e = getObstacle(scn, i); - - if(e == null) - return; - - - e.setAttribute("polygon", Param.toStringParam(poly)); - e.setAttribute("pos", Param.toStringParam(new Vector2(poly.getX(), poly.getY()))); - - modified = true; - firePropertyChange("obstacle", e); - } - - public void deleteObstacle(Element scn, int i) { - Element e = getObstacle(scn, i); - - if(e != null) { - deleteElement(e); - } - - modified = true; - firePropertyChange("obstacle", e); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/Project.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/Project.java deleted file mode 100644 index b944d3746..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/Project.java +++ /dev/null @@ -1,369 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.model; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Properties; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; - -import org.w3c.dom.Element; -import org.xml.sax.SAXException; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.bladecoder.engine.util.Config; -import com.bladecoder.engineeditor.setup.BladeEngineSetup; -import com.bladecoder.engineeditor.setup.Dependency; -import com.bladecoder.engineeditor.setup.DependencyBank; -import com.bladecoder.engineeditor.setup.ProjectBuilder; -import com.bladecoder.engineeditor.setup.DependencyBank.ProjectDependency; -import com.bladecoder.engineeditor.setup.DependencyBank.ProjectType; -import com.bladecoder.engineeditor.utils.DinamicClassPath; -import com.bladecoder.engineeditor.utils.EditorLogger; - -public class Project extends PropertyChange { - public static final String PROP_PROJECTFILE = "projectFile"; - public static final String NOTIFY_SCENE_SELECTED = "SCENE_SELECTED"; - public static final String NOTIFY_ACTOR_SELECTED = "ACTOR_SELECTED"; - public static final String NOTIFY_FA_SELECTED = "FA_SELECTED"; - public static final String NOTIFY_VERB_SELECTED = "VERB_SELECTED"; - public static final String NOTIFY_PROJECT_LOADED = "PROJECT_LOADED"; - - public static final String ASSETS_PATH = "/android/assets"; - public static final String MODEL_PATH = ASSETS_PATH + "/model"; - public static final String ATLASES_PATH = ASSETS_PATH + "/atlases"; - public static final String BACKGROUNDS_PATH = ASSETS_PATH + "/backgrounds"; - public static final String FONTS_PATH = ASSETS_PATH + "/fonts"; - public static final String MUSIC_PATH = ASSETS_PATH + "/music"; - public static final String SOUND_PATH = ASSETS_PATH + "/sounds"; - public static final String IMAGE_PATH = ASSETS_PATH + "/images"; - public static final String SPRITE3D_PATH = ASSETS_PATH + "/3d"; - public static final String SPINE_PATH = ASSETS_PATH + "/spine"; - public static final String UI_PATH = ASSETS_PATH + "/ui"; - - private static final String CONFIG_DIR = System.getProperty("user.home") + "/.AdventureComposer"; - private static final String CONFIG_FILENAME = "config.properties"; - - public static final String LAST_PROJECT_PROP = "last_project"; - - private final Properties editorConfig = new Properties(); - - private File projectFile; - - private final WorldDocument world = new WorldDocument(); - private Properties projectConfig; - - private ChapterDocument selectedChapter; - private Element selectedScene; - private Element selectedActor; - private String selectedFA; - - private HashMap bgIconCache = new HashMap(); - - final PropertyChangeListener modelChangeListener = new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); - } - - }; - - public Project() { - world.addPropertyChangeListener(modelChangeListener); - loadConfig(); - } - - public TextureRegion getBgIcon(String s) { - TextureRegion icon = bgIconCache.get(s); - - if(icon == null) { - try { - bgIconCache.put(s, createBgIcon(s)); - } catch (Exception e) { - return null; - } - - icon = bgIconCache.get(s); - } - - return icon; - } - - private TextureRegion createBgIcon(String bg) { - return new TextureRegion(new Texture(Gdx.files.absolute(getProjectPath() + "/" + BACKGROUNDS_PATH + - "/1/" + bg))); - } - - private void loadConfig() { - File dir = new File(CONFIG_DIR); - File f = new File(CONFIG_DIR + "/" + CONFIG_FILENAME); - - if (!dir.exists()) - dir.mkdirs(); - - try { - if (!f.exists()) { - f.createNewFile(); - } else { - editorConfig.load(new FileInputStream(f)); - } - } catch (IOException e) { - EditorLogger.error(e.getMessage()); - } - } - - public void saveConfig() { - File f = new File(CONFIG_DIR + "/" + CONFIG_FILENAME); - - try { - editorConfig.store(new FileOutputStream(f), null); - } catch (IOException e) { - EditorLogger.error(e.getMessage()); - } - } - - public Properties getConfig() { - return editorConfig; - } - - public void setSelectedScene(Element scn) { - Element old = null; - - old = selectedScene; - - selectedScene = scn; - selectedActor = null; - selectedFA = null; - - firePropertyChange(NOTIFY_SCENE_SELECTED, old, selectedScene); - } - - public void setSelectedActor(Element a) { - Element old = null; - - old = selectedActor; - - selectedActor = a; - - selectedFA = null; - - firePropertyChange(NOTIFY_ACTOR_SELECTED, old, selectedActor); - } - - public ChapterDocument getSelectedChapter() { - return selectedChapter; - } - - public Element getSelectedScene() { - return selectedScene; - } - - public Element getSelectedActor() { - return selectedActor; - } - - public String getSelectedFA() { - return selectedFA; - } - - public void setSelectedFA(String id) { - String old = selectedFA; - - selectedFA = id; - - firePropertyChange(NOTIFY_FA_SELECTED, old, selectedFA); - } - - public String getModelPath() { - return projectFile.getAbsolutePath() + MODEL_PATH; - } - - public String getProjectPath() { - return projectFile.getAbsolutePath(); - } - - public File getProjectDir() { - return projectFile; - } - - public String getTitle() { - if(projectConfig == null) return null; - - return projectConfig.getProperty(Config.TITLE_PROP, getProjectDir().getName()); - } - - public String getPackageTitle() { - return getTitle().replace(" ", "").replace("'", ""); - } - - public void createProject(String projectDir, String name, String sdkLocation) throws ParserConfigurationException, - TransformerException, IOException, SAXException { - createLibGdxProject(projectDir, name, "com.bladecoder.engine", "BladeEngine", sdkLocation); - - projectFile = new File(projectDir + "/" + name); - -// loadProject(projectFile); - } - - private void createLibGdxProject(String projectDir, String name, String pkg, String mainClass, String sdkLocation) throws IOException { - String sdk = ""; - if (System.getenv("ANDROID_HOME") != null && sdkLocation == null) { - sdk = System.getenv("ANDROID_HOME"); - } else { - sdk = sdkLocation; - } - - DependencyBank bank = new DependencyBank(); - ProjectBuilder builder = new ProjectBuilder(bank); - List projects = new ArrayList(); - projects.add(ProjectType.CORE); - projects.add(ProjectType.DESKTOP); - projects.add(ProjectType.ANDROID); - projects.add(ProjectType.IOS); - projects.add(ProjectType.HTML); - - List dependencies = new ArrayList(); - dependencies.add(bank.getDependency(ProjectDependency.GDX)); - dependencies.add(bank.getDependency(ProjectDependency.FREETYPE)); - - builder.buildProject(projects, dependencies); - builder.build(); - new BladeEngineSetup().build(builder, projectDir + "/" + name, name, pkg,mainClass, - sdk, null); - } - - public void saveProject() throws IOException, TransformerException { - if (projectFile != null) { - world.save(); - selectedChapter.save(); - - projectConfig.store(new FileOutputStream(projectFile.getAbsolutePath()+ "/" + ASSETS_PATH + "/" + Config.PROPERTIES_FILENAME), null); - } - } - - public void closeProject() { - this.projectFile = null; - } - - public void loadProject(File projectFile) throws IOException, ParserConfigurationException, - SAXException { - this.projectFile = projectFile; - - if (checkProjectStructure()) { - - - // Add 'bin' dir from project directory to classpath so we can get custom actions desc and params - // WARNING: Previous 'bin' folders are not deleted from the classpath - // That can not be a problem if the package of the custom actions is different - // in the loaded project. - try { - DinamicClassPath.addFile(projectFile.getAbsolutePath() + "/bin"); - DinamicClassPath.addFile(projectFile.getAbsolutePath() + "/out"); - DinamicClassPath.addFile(projectFile.getAbsolutePath() + "/desktop/build/classes/main"); - } catch (IOException e) { - e.printStackTrace(); - System.exit(0); - } - - world.setModelPath(projectFile.getAbsolutePath() + "/" + MODEL_PATH); - world.load(); - selectedChapter = world.loadChapter(world.getInitChapter()); - editorConfig.setProperty(LAST_PROJECT_PROP, projectFile.getAbsolutePath()); - - projectConfig = new Properties(); - projectConfig.load(new FileInputStream(projectFile.getAbsolutePath()+ ASSETS_PATH + "/" + Config.PROPERTIES_FILENAME)); - firePropertyChange(NOTIFY_PROJECT_LOADED); - } else { - this.projectFile = null; - throw new IOException("Project not found."); - } - } - - public boolean checkProjectStructure() { - if (!new File(getModelPath()).exists()) { - projectFile = projectFile.getParentFile(); - if (new File(getModelPath()).exists()) - return true; - else - return false; - } - - return true; - } - - public WorldDocument getWorld() { - return world; - } - - public Element getActor(String id) { - return selectedChapter.getActor(selectedScene, id); - } - - public List getResolutions() { - File atlasesPath = new File(projectFile.getAbsolutePath() + ATLASES_PATH); - ArrayList l = new ArrayList(); - - File[] list = atlasesPath.listFiles(); - - for (int i = 0; i < list.length; i++) { - String name = list[i].getName(); - - if (list[i].isDirectory()) { - try { - Float.parseFloat(name); - - l.add(name); - } catch (Exception e) { - - } - } - } - - return l; - } - - public String getResDir() { - return "1"; - } - - public void loadChapter(String selChapter) throws ParserConfigurationException, SAXException, IOException { - selectedChapter = world.loadChapter(selChapter); - -// if(selectedChapter != null) { -// NodeList scenes = selectedChapter.getScenes(); -// if(scenes.getLength()>0) -// setSelectedScene((Element)scenes.item(0)); -// else -// setSelectedScene(null); -// } - } - - public void dispose() { - for(TextureRegion r:bgIconCache.values()) - r.getTexture().dispose(); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/WorldDocument.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/WorldDocument.java deleted file mode 100644 index 319a32889..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/WorldDocument.java +++ /dev/null @@ -1,189 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.model; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FilenameFilter; -import java.io.IOException; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; - -import org.xml.sax.SAXException; - -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.utils.EditorLogger; - -public class WorldDocument extends BaseDocument { - public static final int DEFAULT_WIDTH = 1920; - public static final int DEFAULT_HEIGHT = 1080; - - public static final String NOTIFY_DOCUMENT_MODIFIED = "DOCUMENT_MODIFIED"; - - private PropertyChangeListener documentModifiedListener = new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { -// if(!evt.getPropertyName().equals(NOTIFY_DOCUMENT_MODIFIED)) - firePropertyChange(evt); - EditorLogger.debug("WorldDocument Listener: " + evt.getPropertyName()); - } - }; - - public WorldDocument() { - setFilename("world.xml"); - } - - @Override - public String getRootTag() { - return "world"; - } - - @Override - public void create() throws ParserConfigurationException { - super.create(); - - setDimensions(DEFAULT_WIDTH, DEFAULT_HEIGHT); - } - - public void setDimensions(int width, int height) { - doc.getDocumentElement().setAttribute("width", Integer.toString(width)); - doc.getDocumentElement().setAttribute("height", Integer.toString(height)); - modified = true; - firePropertyChange(); - } - - public String[] getChapters() { - String dir = Ctx.project.getProjectPath() + Project.MODEL_PATH; - - String[] chapters = new File(dir).list(new FilenameFilter() { - @Override - public boolean accept(File arg0, String arg1) { - if (!arg1.endsWith(".chapter")) - return false; - - return true; - } - }); - - for(int i = 0; i < chapters.length; i++) - chapters[i] = chapters[i].substring(0, chapters[i].lastIndexOf('.')); - - return chapters; - } - - public int getWidth() { - return Integer.parseInt(doc.getDocumentElement().getAttribute("width")); - } - - public int getHeight() { - return Integer.parseInt(doc.getDocumentElement().getAttribute("height")); - } - - public void setWidth(String value) { - doc.getDocumentElement().setAttribute("width", value); - modified = true; - firePropertyChange(); - } - - public void setHeight(String value) { - doc.getDocumentElement().setAttribute("height", value); - modified = true; - firePropertyChange(); - } - - public ChapterDocument loadChapter(String id) throws ParserConfigurationException, SAXException, IOException { - ChapterDocument chapter = new ChapterDocument(modelPath); - chapter.setFilename(id + ".chapter"); - chapter.load(); - chapter.addPropertyChangeListener(documentModifiedListener); - - return chapter; - } - - public String getInitChapter() { - String init = getRootAttr("init_chapter"); - - if(init == null || init.isEmpty()) { - init = getChapters()[0]; - - setRootAttr("init_chapter", init); - } - - return init; - } - - public void setInitChapter(String value) { - doc.getDocumentElement().setAttribute("init_chapter", value); - modified = true; - firePropertyChange(); - } - - public ChapterDocument createChapter(String id) throws FileNotFoundException, TransformerException, ParserConfigurationException { - ChapterDocument chapter = new ChapterDocument(modelPath); - String checkedId = getChapterCheckedId(id); - - chapter.create(checkedId); - firePropertyChange("chapter"); - - return chapter; - } - - public String getChapterCheckedId(String id) { - boolean checked = false; - int i = 1; - - String idChecked = id; - - String [] nl = getChapters(); - - while (!checked) { - checked = true; - - for (int j = 0; j < nl.length; j++) { - String id2 = nl[j]; - - if (id2.equals(idChecked)) { - i++; - idChecked = id + i; - checked = false; - break; - } - } - } - - return idChecked; - } - - public void renameChapter(String oldId, String newId) throws TransformerException, ParserConfigurationException, SAXException, IOException { - - ChapterDocument chapter = new ChapterDocument(modelPath); - chapter.setFilename(oldId + ".chapter"); - chapter.load(); - chapter.rename(newId); - firePropertyChange("chapter"); - } - - public void removeChapter(String id) throws FileNotFoundException, TransformerException { - - ChapterDocument chapter = new ChapterDocument(modelPath); - chapter.setFilename(id + ".chapter"); - chapter.deleteFiles(); - firePropertyChange("chapter"); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/ScnEditor.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/ScnEditor.java deleted file mode 100644 index cd03feab6..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/ScnEditor.java +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.scneditor; - -import java.io.IOException; - -import com.badlogic.gdx.scenes.scene2d.ui.CheckBox; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.ui.TextButton; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.utils.RunProccess; - -public class ScnEditor extends Table { - ScnWidget scnWidget; - CheckBox inSceneCb; - CheckBox animCb; - TextButton testButton; - TextButton walkZoneButton; - - public ScnEditor(Skin skin) { - super(skin); - - scnWidget = new ScnWidget(skin); - - inSceneCb = new CheckBox("In Scene Sprites", skin); - inSceneCb.setChecked(false); - animCb = new CheckBox("Animation", skin); - animCb.setChecked(true); - testButton = new TextButton("Test", skin); - walkZoneButton = new TextButton("Walk Zone", skin); - - add(scnWidget).expand().fill(); - row(); - - Table bottomTable = new Table(skin); - bottomTable.left(); - // bottomTable.setBackground("background"); - add(bottomTable).fill(); - - bottomTable.add(walkZoneButton); - bottomTable.add(inSceneCb); - bottomTable.add(animCb); - bottomTable.add(testButton); - - walkZoneButton.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, - com.badlogic.gdx.scenes.scene2d.Actor actor) { - if(walkZoneButton.isChecked()) - getScnWidget().showEditWalkZoneWindow(); - else - getScnWidget().hideEditWalkZoneWindow(); - } - }); - - - inSceneCb.addListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, - com.badlogic.gdx.scenes.scene2d.Actor actor) { - scnWidget.setInSceneSprites(inSceneCb.isChecked()); - } - }); - - animCb.addListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, - com.badlogic.gdx.scenes.scene2d.Actor actor) { - scnWidget.setAnimation(animCb.isChecked()); - } - }); - - testButton.addListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, - com.badlogic.gdx.scenes.scene2d.Actor actor) { - test(); - event.cancel(); - } - }); - } - - public ScnWidget getScnWidget() { - return scnWidget; - } - - private void test() { - - if(Ctx.project.getSelectedScene() == null) { - String msg = "There are no scenes in this chapter."; - Ctx.msg.show(getStage(),msg, 3); - return; - } - - try { - try { - Ctx.project.saveProject(); - } catch (Exception ex) { - String msg = "Something went wrong while saving the project.\n\n" - + ex.getClass().getSimpleName() + " - " + ex.getMessage(); - Ctx.msg.show(getStage(),msg, 2); - } - - if(!RunProccess.runBladeEngine( - Ctx.project.getProjectDir(), - Ctx.project.getSelectedChapter().getId(), - Ctx.project.getSelectedChapter().getId(Ctx.project.getSelectedScene()))) - Ctx.msg.show(getStage(),"There was a problem running the project", 3); - } catch (IOException e) { - String msg = "Something went wrong while testing the scene.\n\n" - + e.getClass().getSimpleName() + " - " + e.getMessage(); - Ctx.msg.show(getStage(),msg, 3); - } - } - - public void dispose() { - scnWidget.dispose(); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/ScnWidget.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/ScnWidget.java deleted file mode 100644 index a0df5db94..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/ScnWidget.java +++ /dev/null @@ -1,616 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.scneditor; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.text.MessageFormat; -import java.util.ArrayList; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.math.Polygon; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.Widget; -import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack; -import com.badlogic.gdx.scenes.scene2d.utils.TiledDrawable; -import com.bladecoder.engine.anim.FrameAnimation; -import com.bladecoder.engine.anim.Tween; -import com.bladecoder.engine.assets.EngineAssetManager; -import com.bladecoder.engine.model.BaseActor; -import com.bladecoder.engine.model.Scene; -import com.bladecoder.engine.model.SpriteActor; -import com.bladecoder.engine.model.SpriteRenderer; -import com.bladecoder.engine.util.RectangleRenderer; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.BaseDocument; -import com.bladecoder.engineeditor.model.ChapterDocument; -import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.utils.EditorLogger; - -public class ScnWidget extends Widget { - private static final Color BLACK_TRANSPARENT = new Color(0f, 0f, 0f, 0.5f); - - // TMPs to avoid GC calls - private final Vector3 tmpV3 = new Vector3(); - private final Vector2 tmpV2 = new Vector2(); - - private final SpriteBatch sceneBatch = new SpriteBatch(); - private final CanvasDrawer drawer = new CanvasDrawer(); - private final SpriteDrawer faRenderer = new SpriteDrawer(); - private final ScnWidgetInputListener inputListner = new ScnWidgetInputListener( - this); - - private final Rectangle bounds = new Rectangle(); - private final Rectangle scissors = new Rectangle(); - - private Scene scn; - private BaseActor selectedActor = null; - private boolean inScene = false; - private boolean animation = true; - - private static final int[] zoomLevels = { 5, 10, 16, 25, 33, 50, 66, 100, - 150, 200, 300, 400, 600, 800, 1000 }; - private int zoomLevel = 100; - - private BitmapFont bigFont; - private BitmapFont defaultFont; - private TiledDrawable tile; - - private boolean loading = false; - private boolean loadingError = false; - - private WalkZoneWindow walkZoneWindow; - - private boolean showWalkZone; - - /** - * The NOTIFY_PROJECT_LOADED listener is called from other thread. - * This flag is to recreate the scene in the OpenGL thread. - */ - private boolean projectLoadedFlag = false; - - public ScnWidget(Skin skin) { - bigFont = skin.get("big-font", BitmapFont.class); - defaultFont = skin.get("default-font", BitmapFont.class); - - setSize(150, 150); - - tile = new TiledDrawable(Ctx.assetManager.getIcon("transparent-light")); - - faRenderer.setViewport(getWidth(), getHeight()); - - setLayoutEnabled(true); - - addListener(inputListner); - - Ctx.project.addPropertyChangeListener(new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent e) { - EditorLogger.debug("ScnWidget (Project Listener): " - + e.getPropertyName()); - - if (e.getPropertyName().equals(Project.NOTIFY_SCENE_SELECTED)) { - if(!projectLoadedFlag) - setSelectedScene(Ctx.project.getSelectedScene()); - } else if (e.getPropertyName().equals( - Project.NOTIFY_ACTOR_SELECTED)) { - if(!projectLoadedFlag) - setSelectedActor(Ctx.project.getSelectedActor()); - } else if (e.getPropertyName().equals( - Project.NOTIFY_FA_SELECTED)) { - if(!projectLoadedFlag) - setSelectedFA(Ctx.project.getSelectedFA()); - } else if (e.getPropertyName().equals( - Project.NOTIFY_PROJECT_LOADED)) { - projectLoadedFlag = true; - } - } - }); - - Ctx.project.getWorld().addPropertyChangeListener( - new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent e) { - EditorLogger.debug("ScnWidget (World Listener): " - + e.getPropertyName()); - ChapterDocument doc = Ctx.project.getSelectedChapter(); - - if (e.getPropertyName().equals("scene")) { - setSelectedScene(Ctx.project.getSelectedScene()); - setSelectedActor(Ctx.project.getSelectedActor()); - } else if (e.getPropertyName().equals("bbox")) { - Element selActor = (Element) e.getNewValue(); - String id = doc.getId(selActor); - BaseActor a = scn.getActor(id, false); - if (a == null) - return; - - a.setBbox(doc.getBBox(selActor)); - Vector2 p = doc.getPos(selActor); - a.setPosition(p.x, p.y); - } else if (e.getPropertyName().equals("pos")) { - Element selActor = (Element) e.getNewValue(); - String id = doc.getId(selActor); - BaseActor a = scn.getActor(id, false); - if (a == null) - return; - Vector2 p = doc.getPos(selActor); - a.setPosition(p.x, p.y); - } else if (e.getPropertyName().equals("id")) { - String id = (String) e.getOldValue(); - - if (selectedActor == null - || !selectedActor.getId().equals(id)) - return; - - scn.removeActor(scn.getActor(id, false)); - setSelectedActor(null); - } else if (e.getPropertyName() - .equals("frame_animation")) { - createAndSelectActor(Ctx.project.getSelectedActor()); - setSelectedFA(null); - } else if (e.getPropertyName().equals( - "init_frame_animation")) { - String initFA = (String) e.getNewValue(); - ((SpriteActor) selectedActor).getRenderer() - .setInitFrameAnimation(initFA); - setSelectedFA(null); - } else if (e.getPropertyName().equals("actor")) { - createAndSelectActor((Element) e.getNewValue()); - } else if (e.getPropertyName().equals( - BaseDocument.NOTIFY_ELEMENT_DELETED)) { - if (((Element) e.getNewValue()).getTagName() - .equals("actor")) - removeActor(doc, (Element) e.getNewValue()); - else if (((Element) e.getNewValue()).getTagName() - .equals("frame_animation")) - setSelectedFA(null); - } - } - }); - - walkZoneWindow = new WalkZoneWindow(skin, inputListner); - } - - @Override - public void act(float delta) { - if(projectLoadedFlag) { - projectLoadedFlag = false; - - if (scn != null) { - scn.dispose(); - EngineAssetManager.getInstance().dispose(); - scn = null; - } - - EngineAssetManager.createEditInstance(Ctx.project - .getProjectDir().getAbsolutePath() + Project.ASSETS_PATH, Ctx.project.getWorld().getWidth(), Ctx.project.getWorld().getHeight()); - - setSelectedScene(Ctx.project.getSelectedScene()); - setSelectedActor(Ctx.project.getSelectedActor()); - setSelectedFA(Ctx.project.getSelectedFA()); - } - - if (scn != null && animation && !loading && !loadingError) { - faRenderer.update(delta); - scn.update(delta); - } - } - - @Override - public void draw(Batch batch, float parentAlpha) { - validate(); - - Color tmp = batch.getColor(); - batch.setColor(Color.WHITE); - - // BACKGROUND - batch.disableBlending(); - tile.draw(batch, getX(), getY(), getWidth(), getHeight()); - batch.enableBlending(); - - if (scn != null && !loading && !loadingError) { - Vector3 v = new Vector3(getX(), getY(), 0); - v = v.prj(batch.getTransformMatrix()); - - batch.end(); - - // System.out.println("X: " + v.x+ " Y:" + v.y); - Gdx.gl.glViewport((int) v.x, (int) v.y, (int) getWidth(), - (int) (getHeight())); - - getStage().calculateScissors(bounds, scissors); - - if (ScissorStack.pushScissors(scissors)) { - // WORLD CAMERA - sceneBatch.setProjectionMatrix(scn.getCamera().combined); - sceneBatch.begin(); - scn.draw(sceneBatch); - sceneBatch.end(); - ScissorStack.popScissors(); - } - - drawer.drawBGBounds(); - - if (showWalkZone && scn.getPolygonalNavGraph() != null) { - drawer.drawBBoxWalkZone(scn, false); - - drawer.drawPolygonVertices(scn.getPolygonalNavGraph().getWalkZone(), - Color.GREEN); - - ArrayList obstacles = scn.getPolygonalNavGraph() - .getObstacles(); - - for (Polygon p : obstacles) { - drawer.drawPolygonVertices(p, Color.RED); - } - } - - drawer.drawBBoxActors(scn); - - if (selectedActor != null) { - drawer.drawSelectedActor(selectedActor); - } - - getStage().getViewport().apply(); - - // SCREEN CAMERA - batch.begin(); - - if (!inScene) { - faRenderer.draw((SpriteBatch) batch); - } - - // DRAW COORDS - Vector2 coords = new Vector2(Gdx.input.getX(), Gdx.input.getY()); - screenToWorldCoords(coords); - String str = MessageFormat.format("({0}, {1})", (int) coords.x, - (int) coords.y); - - TextBounds bounds2 = defaultFont.getBounds(str); - RectangleRenderer.draw((SpriteBatch) batch, 0f, getY() - + getHeight() - bounds2.height - 15, bounds2.width + 10, - bounds2.height + 10, BLACK_TRANSPARENT); - defaultFont.draw(batch, str, 5, getHeight() + getY() - 10); - - batch.setColor(tmp); - - } else { - RectangleRenderer.draw((SpriteBatch) batch, getX(), getY(), - getWidth(), getHeight(), Color.BLACK); - - String s; - - if (loading) { - s = "LOADING..."; - - try { - if (!EngineAssetManager.getInstance().isLoading()) { - loading = false; - - scn.retrieveAssets(); - - drawer.setCamera(scn.getCamera()); - - invalidate(); - } - } catch (Exception e) { - Ctx.msg.show(getStage(), "Could not load assets for scene", - 4); - e.printStackTrace(); - loadingError = true; - loading = false; - } - - } else if (loadingError) { - s = "ERROR IN SCENE DATA. CANNOT DISPLAY SCENE"; - } else if (Ctx.project.getProjectDir() == null) { - s = "CREATE OR LOAD A PROJECT"; - } else { - s = "THERE ARE NO SCENES IN THIS CHAPTER YET"; - } - - bigFont.draw(batch, s, - (getWidth() - bigFont.getBounds(s).width) / 2, getHeight() - / 2 + bigFont.getLineHeight() * 3); - - } - - } - - public void setInSceneSprites(boolean v) { - inScene = v; - } - - public void setAnimation(boolean v) { - animation = v; - } - - public void setFrameAnimation(FrameAnimation fa) { - try { - faRenderer.setFrameAnimation(fa); - } catch (Exception e) { - Ctx.msg.show(getStage(), "Could not retrieve assets for sprite: " - + fa.id, 4); - e.printStackTrace(); - - faRenderer.setFrameAnimation(null); - } - } - - public void showEditWalkZoneWindow() { - getParent().addActor(walkZoneWindow); - showWalkZone = true; - } - - public void hideEditWalkZoneWindow() { - getParent().removeActor(walkZoneWindow); - showWalkZone = false; - } - - public boolean getShowWalkZone() { - return showWalkZone; - } - - @Override - public void layout() { - EditorLogger.debug("LAYOUT SIZE CHANGED - X: " + getX() + " Y: " - + getY() + " Width: " + getWidth() + " Height: " + getHeight()); - EditorLogger.debug("Last Point coords - X: " + (getX() + getWidth()) - + " Y: " + (getY() + getHeight())); - localToScreenCoords(tmpV2 - .set(getX() + getWidth(), getY() + getHeight())); - EditorLogger.debug("Screen Last Point coords: " + tmpV2); - - faRenderer.setViewport(getWidth(), getHeight()); - bounds.set(getX(), getY(), getWidth(), getHeight()); - - walkZoneWindow.setPosition(getX() + 5, getY() + 5); - walkZoneWindow.invalidate(); - - // SETS WORLD CAMERA - if (scn != null) { - - float aspect = getWidth() / getHeight(); - - float wWidth = Ctx.project.getWorld().getWidth(); - float wHeight = Ctx.project.getWorld().getHeight(); - float aspectWorld = wWidth / wHeight; - - if (aspectWorld > aspect) { - wHeight = wWidth / aspect; - } else { - wWidth = wHeight * aspect; - } - - zoomLevel = 100; - - scn.getCamera().setToOrtho(false, wWidth, wHeight); - scn.getCamera().zoom = 1f; - scn.getCamera().position.set(Ctx.project.getWorld().getWidth() / 2, Ctx.project.getWorld().getHeight() / 2, 0); - scn.getCamera().update(); - zoom(+1); - } - } - - public void zoom(int amount) { - if (zoomLevel == zoomLevels[0] && amount < 0) { - zoomLevel = zoomLevels[1]; - } else if (zoomLevel == zoomLevels[zoomLevels.length - 1] && amount > 0) { - zoomLevel = zoomLevels[zoomLevels.length - 2]; - } else { - for (int i = 1; i < zoomLevels.length - 1; i++) { - if (zoomLevels[i] == zoomLevel) { - zoomLevel = amount > 0 ? zoomLevels[i - 1] - : zoomLevels[i + 1]; - break; - } - } - } - - if (scn != null) { - scn.getCamera().zoom = 100f / zoomLevel; - scn.getCamera().update(); - } - } - - public void translate(Vector2 delta) { - // EditorLogger.debug("TRANSLATING - X: " + delta.x + " Y: " + delta.y); - if (scn != null) { - scn.getCamera().translate(-delta.x, -delta.y, 0); - scn.getCamera().update(); - } - } - - public void localToScreenCoords(Vector2 coords) { - localToStageCoordinates(coords); - getStage().stageToScreenCoordinates(coords); - } - - public void localToWorldCoords(Vector2 coords) { - localToStageCoordinates(coords); - getStage().stageToScreenCoordinates(coords); - - tmpV3.set(coords.x, coords.y, 0); - getScene().getCamera().unproject(tmpV3, getX(), getY(), getWidth(), - getHeight()); - coords.set(tmpV3.x, tmpV3.y); - } - - public void screenToWorldCoords(Vector2 coords) { - tmpV2.set(0, 0); - localToStageCoordinates(tmpV2); - // getStage().stageToScreenCoordinates(tmpV2); - tmpV3.set(coords.x, coords.y, 0); - getScene().getCamera().unproject(tmpV3, tmpV2.x, tmpV2.y, getWidth(), - getHeight()); - coords.set(tmpV3.x, tmpV3.y); - } - - public Scene getScene() { - return scn; - } - - public BaseActor getSelectedActor() { - return selectedActor; - } - - public void setSelectedScene(Element e) { - if (scn != null) { - scn.dispose(); - scn = null; - } - - loadingError = false; - - setSelectedActor(null); - - if (e != null) { - scn = Ctx.project.getSelectedChapter().getEngineScene(e, - Ctx.project.getWorld().getWidth(), - Ctx.project.getWorld().getHeight()); - - scn.loadAssets(); - loading = true; - } - - walkZoneWindow.setScene(scn); - - // SETS WORLD CAMERA - if (scn != null) { - - float aspect = getWidth() / getHeight(); - - float wWidth = Ctx.project.getWorld().getWidth(); - float wHeight = Ctx.project.getWorld().getHeight(); - float aspectWorld = wWidth / wHeight; - - if (aspectWorld > aspect) { - wHeight = wWidth / aspect; - } else { - wWidth = wHeight * aspect; - } - - zoomLevel = 100; - - scn.getCamera().setToOrtho(false, wWidth, wHeight); - scn.getCamera().zoom = 1f; - scn.getCamera().update(); - -// translate(new Vector2((-getWidth() + wWidth ) / 2 * scn.getCamera().zoom, -// (-getHeight() + wHeight) / 2 * scn.getCamera().zoom)); - - translate(new Vector2(0, - (-getHeight() + wHeight) / 2)); - } - } - - public void setSelectedActor(Element actor) { - BaseActor a = null; - - if (scn != null && actor != null) { - a = scn.getActor(Ctx.project.getSelectedChapter().getId(actor), - false); - } - - selectedActor = a; - faRenderer.setActor(a); - setFrameAnimation(null); - walkZoneWindow.setActor(a); - } - - public void setSelectedFA(String selFA) { - if (selectedActor instanceof SpriteActor) { - SpriteRenderer s = ((SpriteActor) selectedActor).getRenderer(); - - if (selFA == null || s.getFrameAnimations().get(selFA) == null) { - selFA = ((SpriteActor) selectedActor).getRenderer() - .getInitFrameAnimation(); - } - - if (selFA != null && s.getFrameAnimations().get(selFA) != null) { - - setFrameAnimation(s.getFrameAnimations().get(selFA)); - - if (inScene - || s.getCurrentFrameAnimation() == null - || ((SpriteActor) selectedActor).getRenderer() - .getInitFrameAnimation().equals(selFA)) { - try { - - ((SpriteActor) selectedActor).startFrameAnimation( - selFA, Tween.REPEAT, Tween.INFINITY, null); - } catch (Exception e) { - setFrameAnimation(null); - ((SpriteActor) selectedActor).getRenderer() - .getFrameAnimations().remove(selFA); - } - } - } else { - setFrameAnimation(null); - } - } else { - setFrameAnimation(null); - } - } - - private void createAndSelectActor(Element actor) { - removeActor(Ctx.project.getSelectedChapter(), actor); - selectedActor = createActor(Ctx.project.getSelectedChapter(), actor); - setSelectedActor(actor); - } - - private BaseActor createActor(ChapterDocument doc, Element e) { - BaseActor a = doc.getEngineActor(e); - scn.addActor(a); - - a.loadAssets(); - EngineAssetManager.getInstance().finishLoading(); - a.retrieveAssets(); - - return a; - } - - private void removeActor(ChapterDocument doc, Element e) { - BaseActor a = scn.getActor(doc.getId(e), false); - if (a != null) { - scn.removeActor(a); - - a.dispose(); - setSelectedActor(null); - } - } - - public void dispose() { - if (scn != null) { - scn.dispose(); - scn = null; - } - - faRenderer.dispose(); - } - -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/ScnWidgetInputListener.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/ScnWidgetInputListener.java deleted file mode 100644 index 902414d24..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/ScnWidgetInputListener.java +++ /dev/null @@ -1,414 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.scneditor; - -import java.util.ArrayList; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Input.Buttons; -import com.badlogic.gdx.Input.Keys; -import com.badlogic.gdx.math.Polygon; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.scenes.scene2d.InputEvent; -import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; -import com.bladecoder.engine.model.BaseActor; -import com.bladecoder.engine.model.Scene; -import com.bladecoder.engine.model.SpriteActor; -import com.bladecoder.engine.polygonalpathfinder.PolygonalNavGraph; -import com.bladecoder.engine.util.PolygonUtils; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.utils.EditorLogger; - -public class ScnWidgetInputListener extends ClickListener { - private final ScnWidget scnWidget; - - private static enum DraggingModes { - NONE, DRAGING_ACTOR, DRAGING_BBOX_POINT, DRAGING_WALKZONE, DRAGING_WALKZONE_POINT, DRAGING_OBSTACLE, DRAGING_OBSTACLE_POINT - }; - - private DraggingModes draggingMode = DraggingModes.NONE; - private BaseActor selActor = null; - private Vector2 org = new Vector2(); - private int vertIndex; - private Polygon selPolygon = null; - private int selObstacleIndex = 0; - - private boolean deleteObstacle = false; - - public ScnWidgetInputListener(ScnWidget w) { - this.scnWidget = w; - } - - public void setDeleteObstacle(boolean v) { - Ctx.msg.show(scnWidget.getStage(), "Select Obstacle to Delete"); - deleteObstacle = v; - } - - @Override - public void clicked(InputEvent event, float x, float y) { - Scene scn = scnWidget.getScene(); - if (scn == null) - return; - - Vector2 p = new Vector2(Gdx.input.getX(), Gdx.input.getY()); - scnWidget.screenToWorldCoords(p); - - if (deleteObstacle) { - deleteObstacle = false; - - Ctx.msg.hide(); - PolygonalNavGraph pf = scn.getPolygonalNavGraph(); - ArrayList obstacles = scn.getPolygonalNavGraph() - .getObstacles(); - - // SEARCH FOR OBSTACLE - for (int j = 0; j < obstacles.size(); j++) { - Polygon o = obstacles.get(j); - if (o.contains(p.x, p.y)) { - Ctx.project.getSelectedChapter().deleteObstacle( - Ctx.project.getSelectedScene(), j); - pf.getObstacles().remove(j); - return; - } - } - } - - // DOUBLE CLICK TO CREATE OR DELETE POINTS - if (getTapCount() == 2) { - // Check WALKZONE - if (scn.getPolygonalNavGraph() != null - && scnWidget.getShowWalkZone()) { - Polygon poly = scn.getPolygonalNavGraph().getWalkZone(); - ArrayList obstacles = scn.getPolygonalNavGraph() - .getObstacles(); - - if (Gdx.input.isKeyPressed(Keys.CONTROL_LEFT)) { - // Delete the point if selected - boolean deleted = PolygonUtils.deletePoint(poly, p.x, p.y, - CanvasDrawer.CORNER_DIST); - - if (deleted) { - Ctx.project.getSelectedChapter().setWalkZonePolygon( - Ctx.project.getSelectedScene(), poly); - return; - } else { // check obstacles - for (int i = 0; i < obstacles.size(); i++) { - Polygon o = obstacles.get(i); - deleted = PolygonUtils.deletePoint(o, p.x, p.y, - CanvasDrawer.CORNER_DIST); - if (deleted) { - Ctx.project.getSelectedChapter() - .setObstaclePolygon( - Ctx.project.getSelectedScene(), - i, o); - return; - } - } - } - - } else { - - boolean created = PolygonUtils.addClampPointIfTolerance( - poly, p.x, p.y, CanvasDrawer.CORNER_DIST); - - if (created) { - Ctx.project.getSelectedChapter().setWalkZonePolygon( - Ctx.project.getSelectedScene(), poly); - return; - } else { - for (int i = 0; i < obstacles.size(); i++) { - Polygon o = obstacles.get(i); - created = PolygonUtils.addClampPointIfTolerance(o, - p.x, p.y, CanvasDrawer.CORNER_DIST); - if (created) { - Ctx.project.getSelectedChapter() - .setObstaclePolygon( - Ctx.project.getSelectedScene(), - i, o); - return; - } - } - } - } - } - - if (scnWidget.getSelectedActor() != null) { - - Polygon poly = scnWidget.getSelectedActor().getBBox(); - - if (!(scnWidget.getSelectedActor() instanceof SpriteActor) - || !((SpriteActor) scnWidget.getSelectedActor()) - .isBboxFromRenderer()) { - if (Gdx.input.isKeyPressed(Keys.CONTROL_LEFT)) { - - // Delete the point if selected - boolean deleted = PolygonUtils.deletePoint(poly, p.x, - p.y, CanvasDrawer.CORNER_DIST); - - if (deleted) { - Ctx.project.getSelectedChapter().setBbox( - Ctx.project.getSelectedActor(), poly); - return; - } - } else { - boolean created = PolygonUtils - .addClampPointIfTolerance(poly, p.x, p.y, - CanvasDrawer.CORNER_DIST); - - if (created) { - Ctx.project.getSelectedChapter().setBbox( - Ctx.project.getSelectedActor(), poly); - return; - } - } - } - } - } - } - - @Override - public boolean touchDown(InputEvent event, float x, float y, int pointer, - int button) { - - super.touchDown(event, x, y, pointer, button); - EditorLogger.debug("Touch Down - X: " + x + " Y: " + y); - - Scene scn = scnWidget.getScene(); - if (scn == null) - return false; - - Vector2 p = new Vector2(Gdx.input.getX(), Gdx.input.getY()); - scnWidget.screenToWorldCoords(p); - org.set(p); - - if (button == Buttons.LEFT) { - selActor = scnWidget.getSelectedActor(); - - if (scn.getPolygonalNavGraph() != null - && scnWidget.getShowWalkZone()) { // Check WALKZONE - - // CHECK WALKZONE VERTEXS - Polygon wzPoly = scn.getPolygonalNavGraph().getWalkZone(); - float verts[] = wzPoly.getTransformedVertices(); - - for (int i = 0; i < verts.length; i += 2) { - if (p.dst(verts[i], verts[i + 1]) < CanvasDrawer.CORNER_DIST) { - draggingMode = DraggingModes.DRAGING_WALKZONE_POINT; - vertIndex = i; - return true; - } - } - - // CHECK OBSTACLE VERTEXS - ArrayList obstacles = scn.getPolygonalNavGraph() - .getObstacles(); - - for (int j = 0; j < obstacles.size(); j++) { - Polygon o = obstacles.get(j); - verts = o.getTransformedVertices(); - - for (int i = 0; i < verts.length; i += 2) { - if (p.dst(verts[i], verts[i + 1]) < CanvasDrawer.CORNER_DIST) { - draggingMode = DraggingModes.DRAGING_OBSTACLE_POINT; - selPolygon = o; - vertIndex = i; - selObstacleIndex = j; - return true; - } - } - } - - // CHECK FOR OBSTACLE DRAGGING - for (int j = 0; j < obstacles.size(); j++) { - Polygon o = obstacles.get(j); - if (o.contains(p.x, p.y)) { - draggingMode = DraggingModes.DRAGING_OBSTACLE; - selPolygon = o; - selObstacleIndex = j; - return true; - } - } - - // CHECK FOR WALKZONE DRAGGING - if (wzPoly.contains(p.x, p.y)) { - draggingMode = DraggingModes.DRAGING_WALKZONE; - return true; - } - - } - - // SELACTOR VERTEXs DRAGGING - if (selActor != null - && (!(selActor instanceof SpriteActor) || !((SpriteActor) selActor) - .isBboxFromRenderer())) { - - Polygon bbox = selActor.getBBox(); - float verts[] = bbox.getTransformedVertices(); - for (int i = 0; i < verts.length; i += 2) { - if (p.dst(verts[i], verts[i + 1]) < CanvasDrawer.CORNER_DIST) { - draggingMode = DraggingModes.DRAGING_BBOX_POINT; - vertIndex = i; - return true; - } - } - } - - BaseActor a = scn.getActorAt(p.x, p.y); // CHECK FOR ACTORS - - if (a != null && a != selActor) { - - selActor = a; - Element da = Ctx.project.getActor(selActor.getId()); - Ctx.project.setSelectedActor(da); - - draggingMode = DraggingModes.DRAGING_ACTOR; - return true; - } - - if (a != null) { - draggingMode = DraggingModes.DRAGING_ACTOR; - return true; - } - - } - - return true; - } - - @Override - public void touchDragged(InputEvent event, float x, float y, int pointer) { - // EditorLogger.debug("Touch Dragged - X: " + Gdx.input.getX() + " Y: " - // + Gdx.input.getY()); - - super.touchDragged(event, x, y, pointer); - - if (Gdx.input.isButtonPressed(Buttons.LEFT)) { - Scene scn = scnWidget.getScene(); - - if (scn == null) - return; - - Vector2 d = new Vector2(Gdx.input.getX(), Gdx.input.getY()); - scnWidget.screenToWorldCoords(d); - - d.sub(org); - org.add(d); - - if (draggingMode == DraggingModes.DRAGING_ACTOR) { - Polygon p = selActor.getBBox(); - p.translate(d.x, d.y); - Ctx.project.getSelectedChapter().setPos( - Ctx.project.getSelectedActor(), - new Vector2(selActor.getX(), selActor.getY())); - - } else if (draggingMode == DraggingModes.DRAGING_BBOX_POINT) { - Polygon poly = selActor.getBBox(); - - float verts[] = poly.getVertices(); - verts[vertIndex] += d.x; - verts[vertIndex + 1] += d.y; - poly.dirty(); - - Ctx.project.getSelectedChapter().setBbox( - Ctx.project.getSelectedActor(), poly); - } else if (draggingMode == DraggingModes.DRAGING_WALKZONE_POINT) { - Polygon poly = scn.getPolygonalNavGraph().getWalkZone(); - - float verts[] = poly.getVertices(); - verts[vertIndex] += d.x; - verts[vertIndex + 1] += d.y; - poly.dirty(); - - Ctx.project.getSelectedChapter().setWalkZonePolygon( - Ctx.project.getSelectedScene(), poly); - } else if (draggingMode == DraggingModes.DRAGING_OBSTACLE_POINT) { - float verts[] = selPolygon.getVertices(); - verts[vertIndex] += d.x; - verts[vertIndex + 1] += d.y; - selPolygon.dirty(); - - Ctx.project.getSelectedChapter().setObstaclePolygon( - Ctx.project.getSelectedScene(), selObstacleIndex, - selPolygon); - } else if (draggingMode == DraggingModes.DRAGING_OBSTACLE) { - selPolygon.translate(d.x, d.y); - Ctx.project.getSelectedChapter().setObstaclePolygon( - Ctx.project.getSelectedScene(), selObstacleIndex, - selPolygon); - } else if (draggingMode == DraggingModes.DRAGING_WALKZONE) { - Polygon poly = scn.getPolygonalNavGraph().getWalkZone(); - poly.translate(d.x, d.y); - Ctx.project.getSelectedChapter().setWalkZonePolygon( - Ctx.project.getSelectedScene(), poly); - } - - } else if (Gdx.input.isButtonPressed(Buttons.RIGHT) - || Gdx.input.isButtonPressed(Buttons.MIDDLE)) { - - Vector2 p = new Vector2(Gdx.input.getX(), Gdx.input.getY()); - scnWidget.screenToWorldCoords(p); - p.sub(org); - - scnWidget.translate(p); - } - } - - @Override - public boolean scrolled(InputEvent event, float x, float y, int amount) { - super.scrolled(event, x, y, amount); -// EditorLogger.debug("SCROLLED - X: " + x + " Y: " + y); - - scnWidget.zoom(amount); - return true; - } - - @Override - public void touchUp(InputEvent event, float x, float y, int pointer, - int button) { - - super.touchUp(event, x, y, pointer, button); - EditorLogger.debug("Touch Up - X: " + x + " Y: " + y); - - draggingMode = DraggingModes.NONE; - - return; - } - - @Override - public boolean keyDown(InputEvent event, int keycode) { - super.keyDown(event, keycode); - - switch (keycode) { - case Keys.ENTER: - break; - case Keys.BACKSPACE: - break; - } - - return false; - } - - @Override - public void enter(InputEvent event, float x, float y, int pointer, - com.badlogic.gdx.scenes.scene2d.Actor fromActor) { - super.enter(event, x, y, pointer, fromActor); - // EditorLogger.debug("ENTER - X: " + x + " Y: " + y); - scnWidget.getStage().setScrollFocus(scnWidget); - } - -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/SpriteDrawer.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/SpriteDrawer.java deleted file mode 100644 index 01446809e..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/SpriteDrawer.java +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.scneditor; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.math.Vector2; -import com.bladecoder.engine.anim.FrameAnimation; -import com.bladecoder.engine.anim.Tween; -import com.bladecoder.engine.model.BaseActor; -import com.bladecoder.engine.model.AtlasRenderer; -import com.bladecoder.engine.model.ImageRenderer; -import com.bladecoder.engine.model.SpineRenderer; -import com.bladecoder.engine.model.Sprite3DRenderer; -import com.bladecoder.engine.model.SpriteActor; -import com.bladecoder.engine.model.SpriteRenderer; -import com.bladecoder.engine.util.RectangleRenderer; - -/** - * Frame Animation renderer. - * - * @author rgarcia - */ -public class SpriteDrawer { - - public static final Color BG_COLOR = Color.MAGENTA; - private static final float HEIGHT = 200; - - FrameAnimation currentFrameAnimation; - private SpriteRenderer renderer; - private float viewportW, viewportH; - - public void setViewport(float w, float h) { - viewportW = w; - viewportH = h; - } - - public void setActor(BaseActor a) { - if (renderer != null) { - renderer.dispose(); - renderer = null; - } - - if (a instanceof SpriteActor) { - SpriteRenderer r = ((SpriteActor) a).getRenderer(); - - if (r instanceof Sprite3DRenderer) { - renderer = new Sprite3DRenderer(); - ((Sprite3DRenderer) renderer).setSpriteSize(new Vector2(r - .getWidth(), r.getHeight())); - } else if (r instanceof SpineRenderer) { - renderer = new SpineRenderer(); - } else if (r instanceof ImageRenderer) { - renderer = new ImageRenderer(); - } else { - renderer = new AtlasRenderer(); - } - } - } - - public void setFrameAnimation(FrameAnimation fa) { - currentFrameAnimation = fa; - - if (renderer != null) { - - renderer.getFrameAnimations().clear(); - - if (fa != null) { - - renderer.addFrameAnimation(fa); - - renderer.retrieveAssets(); - - renderer.startFrameAnimation(fa.id, Tween.REPEAT, Tween.INFINITY, null); - } - } - } - - public void draw(SpriteBatch batch) { - if (renderer != null && currentFrameAnimation != null) { - - float width = HEIGHT / renderer.getHeight() * renderer.getWidth(); - - RectangleRenderer.draw(batch, viewportW - width - 5, viewportH - - HEIGHT - 55, width + 10, HEIGHT + 10, Color.BLACK); - RectangleRenderer.draw(batch, viewportW - width, viewportH - HEIGHT - - 50, width, HEIGHT, BG_COLOR); - - float scaleh = width / renderer.getWidth(); - renderer.draw(batch, viewportW - width / 2, - viewportH - HEIGHT - 50, scaleh); - - } - } - - public void update(float delta) { - if (renderer != null && currentFrameAnimation != null) { - renderer.update(delta); - } - } - - public void dispose() { - if (renderer != null) - renderer.dispose(); - } - -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/SpriteWidget.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/SpriteWidget.java deleted file mode 100644 index c70b987c3..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/SpriteWidget.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.scneditor; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.Batch; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.scenes.scene2d.ui.Widget; -import com.bladecoder.engine.anim.AtlasFrameAnimation; -import com.bladecoder.engine.anim.FrameAnimation; -import com.bladecoder.engine.anim.Tween; -import com.bladecoder.engine.assets.EngineAssetManager; -import com.bladecoder.engine.model.AtlasRenderer; -import com.bladecoder.engine.model.ImageRenderer; -import com.bladecoder.engine.model.SpineRenderer; -import com.bladecoder.engine.model.Sprite3DRenderer; -import com.bladecoder.engine.model.SpriteRenderer; -import com.bladecoder.engine.util.RectangleRenderer; -import com.bladecoder.engineeditor.model.ChapterDocument; -import com.bladecoder.engineeditor.ui.EditSpriteDialog; - -public class SpriteWidget extends Widget { - private String source; - private FrameAnimation fa; - private SpriteRenderer renderer; - EditSpriteDialog editFADialog; - - - public SpriteWidget(EditSpriteDialog createEditFADialog) { - this.editFADialog = createEditFADialog; - } - - - public void setSource(String type, String source) { - this.source = source; - - if(renderer != null) { - renderer.dispose(); - renderer = null; - } - - - if(type.equals(ChapterDocument.SPRITE3D_ACTOR_TYPE)) { - renderer = new Sprite3DRenderer(); - ((Sprite3DRenderer)renderer).setSpriteSize(new Vector2( Gdx.graphics.getWidth(), Gdx.graphics.getHeight())); - } else if(type.equals(ChapterDocument.SPINE_ACTOR_TYPE)) { - renderer = new SpineRenderer(); - } else if(type.equals(ChapterDocument.IMAGE_ACTOR_TYPE)) { - renderer = new ImageRenderer(); - } else { - renderer = new AtlasRenderer(); - } - - renderer.loadAssets(); - EngineAssetManager.getInstance().finishLoading(); - renderer.retrieveAssets(); - } - - public String[] getAnimations() { - return renderer.getInternalAnimations(source); - } - - public void setFrameAnimation(String id, String speedStr, String typeStr) { - if (source!=null && id != null && !source.isEmpty() && !id.isEmpty()) { - - int type = Tween.REPEAT; - float speed = 2.0f; - - if(!speedStr.isEmpty()) - speed = Float.parseFloat(speedStr); - - if(typeStr.equals("yoyo")) - type = Tween.PINGPONG; - - if(renderer instanceof AtlasRenderer) - fa = new AtlasFrameAnimation(); - else - fa = new FrameAnimation(); - - fa.set(id, source, speed, 0.0f, Tween.INFINITY, type, - null, null, null, false, true); - - renderer.addFrameAnimation(fa); - - renderer.startFrameAnimation(fa.id, Tween.FROM_FA, 1, null); - } - } - - public void draw (Batch batch, float parentAlpha) { - super.draw(batch, parentAlpha); - - if(renderer == null || renderer.getCurrentFrameAnimation() == null) - return; - - Color tmp = batch.getColor(); - batch.setColor(Color.WHITE); - - renderer.update(Gdx.graphics.getDeltaTime()); - - RectangleRenderer.draw((SpriteBatch)batch, getX(), getY(), getWidth(), getHeight(), Color.MAGENTA); - - float scalew = getWidth() / renderer.getWidth(); - float scaleh = getHeight() / renderer.getHeight(); - float scale = scalew>scaleh?scaleh:scalew; - renderer.draw((SpriteBatch)batch, getX() + renderer.getWidth() * scale /2, getY(), scale); - batch.setColor(tmp); - } - - public void dispose() { - renderer.dispose(); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/WalkZoneWindow.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/WalkZoneWindow.java deleted file mode 100644 index c323e7f53..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/WalkZoneWindow.java +++ /dev/null @@ -1,219 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.scneditor; - -import com.badlogic.gdx.math.Polygon; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Container; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.ui.TextButton; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.scenes.scene2d.utils.Drawable; -import com.bladecoder.engine.model.Scene; -import com.bladecoder.engine.polygonalpathfinder.PolygonalNavGraph; -import com.bladecoder.engineeditor.Ctx; - -public class WalkZoneWindow extends Container { - private static final String DELETE_WALK_ZONE_TEXT = "Delete Walk Zone"; - private static final String CREATE_WALK_ZONE_TEXT = "Create Walk Zone"; - private static final String SET_ACTOR_AS_OBSTACLE_TEXT = "Set BaseActor as Obstacle"; - private static final String REMOVE_ACTOR_AS_OBSTACLE_TEXT = "Remove BaseActor as Obstacle"; - private static final float OBSTACLE_WIDTH = 200; - - TextButton createZoneBtn; - TextButton createObstacleBtn; - TextButton deleteObstacleBtn; - TextButton addObstacleActorBtn; - Scene scn; - com.bladecoder.engine.model.BaseActor actor; - - private final ScnWidgetInputListener scnIL; - - public WalkZoneWindow(Skin skin, ScnWidgetInputListener sIL) { - this.scnIL = sIL; - - Table table = new Table(skin); - createZoneBtn = new TextButton(CREATE_WALK_ZONE_TEXT, skin); - createObstacleBtn = new TextButton("Create Obstacle", skin); - deleteObstacleBtn = new TextButton("Delete Obstacle", skin); - addObstacleActorBtn = new TextButton(SET_ACTOR_AS_OBSTACLE_TEXT, skin); - - createZoneBtn.setDisabled(true); - createObstacleBtn.setDisabled(true); - deleteObstacleBtn.setDisabled(true); - addObstacleActorBtn.setDisabled(true); - - table.top(); - table.add(new Label("Walk Zone", skin, "big")).center(); - - Drawable drawable = skin.getDrawable("trans"); - setBackground(drawable); - table.row(); - table.add(createZoneBtn).expandX().fill(); - table.row(); - table.add(createObstacleBtn).expandX().fill(); - table.row(); - table.add(deleteObstacleBtn).expandX().fill(); - table.row(); - table.add(addObstacleActorBtn).expandX().fill(); - setActor(table); - - createZoneBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - - if (scn.getPolygonalNavGraph() == null) { - float[] verts = new float[8]; - - float width = scn.getCamera().getScrollingWidth(); - float height = scn.getCamera().getScrollingHeight(); - - verts[3] = height; - verts[4] = width; - verts[5] = height; - verts[6] = width; - - Polygon poly = new Polygon(verts); - PolygonalNavGraph pf = new PolygonalNavGraph(); - pf.setWalkZone(poly); - scn.setPolygonalNavGraph(pf); - createZoneBtn.setText(DELETE_WALK_ZONE_TEXT); - createObstacleBtn.setDisabled(false); - addObstacleActorBtn.setDisabled(false); - Ctx.project.getSelectedChapter().createWalkZone( - Ctx.project.getSelectedScene(), poly); - } else { - createZoneBtn.setText(CREATE_WALK_ZONE_TEXT); - createObstacleBtn.setDisabled(true); - deleteObstacleBtn.setDisabled(true); - addObstacleActorBtn.setDisabled(true); - scn.setPolygonalNavGraph(null); - Ctx.project.getSelectedChapter().deleteWalkZone( - Ctx.project.getSelectedScene()); - } - - event.cancel(); - } - - }); - - createObstacleBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - float[] verts = new float[8]; - - verts[3] = OBSTACLE_WIDTH; - verts[4] = OBSTACLE_WIDTH; - verts[5] = OBSTACLE_WIDTH; - verts[6] = OBSTACLE_WIDTH; - - Polygon poly = new Polygon(verts); - PolygonalNavGraph pf = scn.getPolygonalNavGraph(); - pf.addObstacle(poly); - Ctx.project.getSelectedChapter().createObstacle( - Ctx.project.getSelectedScene(), poly); - deleteObstacleBtn.setDisabled(false); - - event.cancel(); - } - }); - - deleteObstacleBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - PolygonalNavGraph pf = scn.getPolygonalNavGraph(); - - if (pf.getObstacles().size() > 0) - scnIL.setDeleteObstacle(true); - else - Ctx.msg.show(getStage(), - "There are no obstacles to delete", 3); - - // if(pf.getObstacles().size() == 0) - // deleteObstacleBtn.setDisabled(true); - - event.cancel(); - } - }); - - addObstacleActorBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor a) { - if (actor.isWalkObstacle()) { - actor.setWalkObstacle(false); - Ctx.project.getSelectedChapter().setRootAttr(Ctx.project.getSelectedActor(), "obstacle", "false"); - addObstacleActorBtn.setText(SET_ACTOR_AS_OBSTACLE_TEXT); - } else { - actor.setWalkObstacle(true); - Ctx.project.getSelectedChapter().setRootAttr(Ctx.project.getSelectedActor(), "obstacle", "true"); - addObstacleActorBtn.setText(REMOVE_ACTOR_AS_OBSTACLE_TEXT); - } - - event.cancel(); - } - }); - - prefSize(200, 200); - setSize(200, 200); - } - - public void setScene(Scene scn) { - this.scn = scn; - this.actor = null; - - if (scn == null) { - createZoneBtn.setDisabled(true); - createObstacleBtn.setDisabled(true); - deleteObstacleBtn.setDisabled(true); - return; - } - - createZoneBtn.setDisabled(false); - - if (scn.getPolygonalNavGraph() == null) { - createZoneBtn.setText(CREATE_WALK_ZONE_TEXT); - createObstacleBtn.setDisabled(true); - } else { - createZoneBtn.setText(DELETE_WALK_ZONE_TEXT); - createObstacleBtn.setDisabled(false); - } - - if (scn.getPolygonalNavGraph() != null - && scn.getPolygonalNavGraph().getObstacles().size() > 0) { - deleteObstacleBtn.setDisabled(false); - } else { - deleteObstacleBtn.setDisabled(true); - } - } - - public void setActor(com.bladecoder.engine.model.BaseActor a) { - this.actor = a; - - if(a == null) { - addObstacleActorBtn.setDisabled(true); - } else { - addObstacleActorBtn.setDisabled(false); - - if(!a.isWalkObstacle()) { - addObstacleActorBtn.setText(SET_ACTOR_AS_OBSTACLE_TEXT); - } else { - addObstacleActorBtn.setText(SET_ACTOR_AS_OBSTACLE_TEXT); - } - } - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/BladeEngineSetup.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/BladeEngineSetup.java deleted file mode 100644 index 96a8148c4..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/BladeEngineSetup.java +++ /dev/null @@ -1,645 +0,0 @@ -/******************************************************************************* - * Copyright 2011 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 com.bladecoder.engineeditor.setup; - -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.io.FileUtils; - -import com.bladecoder.engineeditor.setup.DependencyBank.ProjectDependency; -import com.bladecoder.engineeditor.setup.DependencyBank.ProjectType; -import com.bladecoder.engineeditor.utils.EditorLogger; -import com.bladecoder.engineeditor.utils.RunProccess; -import com.bladecoder.engineeditor.utils.Versions; -import com.esotericsoftware.spine.Skeleton; - -/** Command line tool to generate libgdx projects - * @author badlogic - * @author Tomski - * @author rgarcia*/ -public class BladeEngineSetup { - public static boolean isSdkLocationValid (String sdkLocation) { - return new File(sdkLocation, "tools").exists() && new File(sdkLocation, "platforms").exists(); - } - - public static boolean isEmptyDirectory (String destination) { - if (new File(destination).exists()) { - return new File(destination).list().length == 0; - } else { - return true; - } - } - - public static boolean isSdkUpToDate (String sdkLocation) { - File buildTools = new File(sdkLocation, "build-tools"); - if (!buildTools.exists()) { - EditorLogger.error("You have no build tools!\nUpdate your Android SDK with build tools version: " - + Versions.getBuildToolsVersion()); - return false; - } - - File apis = new File(sdkLocation, "platforms"); - if (!apis.exists()) { - EditorLogger.error("You have no Android APIs!\nUpdate your Android SDK with API level: " - + Versions.getAndroidAPILevel()); - return false; - } - String newestLocalTool = getLatestTools(buildTools); - int[] localToolVersion = convertTools(newestLocalTool); - int[] targetToolVersion = convertTools(Versions.getBuildToolsVersion()); - if (compareVersions(targetToolVersion, localToolVersion)) { -// int value = JOptionPane.showConfirmDialog(null, -// "You have a more recent version of android build tools than the recommended.\nDo you want to use this version?", -// "Warning!", JOptionPane.YES_NO_OPTION); - - int value = 0; // ALWAYS USE THE CURRENT BUILD TOOLS - if(value == 0) { - Versions.setBuildToolsVersion(newestLocalTool); - } - - EditorLogger.error("Using build tools: " + Versions.getBuildToolsVersion()); - } else { - if (!hasFileInDirectory(buildTools, Versions.getBuildToolsVersion())) { - EditorLogger.error("Please update your Android SDK, you need build tools: " - + Versions.getBuildToolsVersion()); - return false; - } - } - - int newestLocalApi = getLatestApi(apis); - if (newestLocalApi > Integer.valueOf(Versions.getAndroidAPILevel())) { -// int value = JOptionPane.showConfirmDialog(null, -// "You have a more recent version of android build tools than the recommended.\nDo you want to use this version?", -// "Warning!", JOptionPane.YES_NO_OPTION); - - int value = 0; // ALWAYS USE THE CURRENT API - - if(value == 0) { - Versions.setAndroidAPILevel(Integer.toString(newestLocalApi)); - } - - EditorLogger.error("Using API level: " + Versions.getAndroidAPILevel()); - } else { - if (!hasFileInDirectory(apis, "android-" + Versions.getAndroidAPILevel())) { - EditorLogger.error("Please update your Android SDK, you need the Android API: " - + Versions.getAndroidAPILevel()); - return false; - } - } - return true; - } - - private static boolean hasFileInDirectory (File file, String fileName) { - for (String name : file.list()) { - if (name.equals(fileName)) return true; - } - return false; - } - - private static int getLatestApi (File apis) { - int apiLevel = 0; - for (File api : apis.listFiles()) { - int level = readAPIVersion(api); - if (level > apiLevel) apiLevel = level; - } - return apiLevel; - } - - private static String getLatestTools (File buildTools) { - String version = null; - int[] versionSplit = new int[3]; - int[] testSplit = new int[3]; - for (File toolsVersion : buildTools.listFiles()) { - if (version == null) { - version = readBuildToolsVersion(toolsVersion); - versionSplit = convertTools(version); - continue; - } - testSplit = convertTools(readBuildToolsVersion(toolsVersion)); - if (compareVersions(versionSplit, testSplit)) { - version = readBuildToolsVersion(toolsVersion); - } - } - if (version != null) { - return version; - } else { - return "0.0.0"; - } - } - - private static int readAPIVersion (File parentFile) { - File properties = new File(parentFile, "source.properties"); - FileReader reader; - BufferedReader buffer; - try { - reader = new FileReader(properties); - buffer = new BufferedReader(reader); - - String line = null; - - while ((line = buffer.readLine()) != null) { - if (line.contains("AndroidVersion.ApiLevel")) { - - String versionString = line.split("\\=")[1]; - int apiLevel = Integer.parseInt(versionString); - - buffer.close(); - reader.close(); - - return apiLevel; - } - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (NumberFormatException e) { - e.printStackTrace(); - } - return 0; - } - - private static String readBuildToolsVersion (File parentFile) { - File properties = new File(parentFile, "source.properties"); - FileReader reader; - BufferedReader buffer; - try { - reader = new FileReader(properties); - buffer = new BufferedReader(reader); - - String line = null; - - while ((line = buffer.readLine()) != null) { - if (line.contains("Pkg.Revision")) { - - String versionString = line.split("\\=")[1]; - int count = versionString.split("\\.").length; - for (int i = 0; i < 3 - count; i++) { - versionString += ".0"; - } - - buffer.close(); - reader.close(); - - return versionString; - } - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return "0.0.0"; - } - - private static boolean compareVersions(int[] version, int[] testVersion) { - if (testVersion[0] > version[0]) { - return true; - } else if (testVersion[0] == version[0]) { - if (testVersion[1] > version[1]) { - return true; - } else if (testVersion[1] == version[1]) { - return testVersion[2] > version[2]; - } - } - return false; - } - - private static int[] convertTools (String toolsVersion) { - String[] stringSplit = toolsVersion.split("\\."); - int[] versionSplit = new int[3]; - if (stringSplit.length == 3) { - try { - versionSplit[0] = Integer.parseInt(stringSplit[0]); - versionSplit[1] = Integer.parseInt(stringSplit[1]); - versionSplit[2] = Integer.parseInt(stringSplit[2]); - return versionSplit; - } catch (NumberFormatException nfe) { - return new int[] {0, 0, 0}; - } - } else { - return new int[] {0, 0, 0}; - } - } - - public void build (ProjectBuilder builder, String outputDir, String appName, String packageName, String mainClass, - String sdkLocation, List gradleArgs) throws IOException { - Project project = new Project(); - - String packageDir = packageName.replace('.', '/'); - String sdkPath = sdkLocation.replace('\\', '/'); - - if (!isSdkLocationValid(sdkLocation)) { - System.out.println("Android SDK location '" + sdkLocation + "' doesn't contain an SDK"); - } - - // root dir/gradle files - project.files.add(new ProjectFile("gitignore", ".gitignore", false)); - project.files.add(new TemporaryProjectFile(builder.settingsFile, "settings.gradle", false)); - project.files.add(new TemporaryProjectFile(builder.buildFile, "build.gradle", true)); - project.files.add(new ProjectFile("gradlew", false)); - project.files.add(new ProjectFile("gradlew.bat", false)); - project.files.add(new ProjectFile("gradle/wrapper/gradle-wrapper.jar", false)); - project.files.add(new ProjectFile("gradle/wrapper/gradle-wrapper.properties", false)); - project.files.add(new ProjectFile("gradle.properties")); - - // core project - project.files.add(new ProjectFile("core/build.gradle")); -// project.files.add(new ProjectFile("core/src/MainClass", "core/src/" + packageDir + "/" + mainClass + ".java", true)); - if (builder.modules.contains(ProjectType.HTML)) { - project.files.add(new ProjectFile("core/CoreGdxDefinition", "core/src/" + mainClass + ".gwt.xml", true)); - } - - // desktop project - if (builder.modules.contains(ProjectType.DESKTOP)) { - project.files.add(new ProjectFile("desktop/build.gradle")); - project.files.add(new ProjectFile("desktop/src/DesktopLauncher", "desktop/src/" + packageDir + "/desktop/DesktopLauncher.java", true)); - - project.files.add(new ProjectFile("desktop/src/icons/icon16.png", false)); - project.files.add(new ProjectFile("desktop/src/icons/icon32.png", false)); - project.files.add(new ProjectFile("desktop/src/icons/icon128.png", false)); - } - - // Assets - String assetPath = builder.modules.contains(ProjectType.ANDROID) ? "android/assets" : "core/assets"; - - // CREATE ASSETS EMPTY FOLDERS - new File(outputDir + "/" + assetPath + "/3d").mkdirs(); - new File(outputDir + "/" + assetPath + "/atlases/1").mkdirs(); - new File(outputDir + "/" + assetPath + "/backgrounds/1").mkdirs(); - new File(outputDir + "/" + assetPath + "/images/1").mkdirs(); - new File(outputDir + "/" + assetPath + "/model").mkdirs(); - new File(outputDir + "/" + assetPath + "/music").mkdirs(); - new File(outputDir + "/" + assetPath + "/sounds").mkdirs(); - new File(outputDir + "/" + assetPath + "/test").mkdirs(); - new File(outputDir + "/" + assetPath + "/ui/1").mkdirs(); - - - project.files.add(new ProjectFile("android/assets/model/00.chapter", assetPath + "/model/00.chapter", false)); - project.files.add(new ProjectFile("android/assets/model/world.properties", assetPath + "/model/world.properties", false)); - project.files.add(new ProjectFile("android/assets/model/world.xml", assetPath + "/model/world.xml", false)); - project.files.add(new ProjectFile("android/assets/model/world_es.properties", assetPath + "/model/world_es.properties", false)); - - project.files.add(new ProjectFile("android/assets/ui/ArchitectsDaughter_fix.ttf", assetPath + "/ui/ArchitectsDaughter_fix.ttf", false)); - project.files.add(new ProjectFile("android/assets/ui/credits.txt", assetPath + "/ui/credits.txt", false)); - project.files.add(new ProjectFile("android/assets/ui/Roboto-Black.ttf", assetPath + "/ui/Roboto-Black.ttf", false)); - project.files.add(new ProjectFile("android/assets/ui/Roboto-Regular.ttf", assetPath + "/ui/Roboto-Regular.ttf", false)); - project.files.add(new ProjectFile("android/assets/ui/Roboto-Thin.ttf", assetPath + "/ui/Roboto-Thin.ttf", false)); - project.files.add(new ProjectFile("android/assets/ui/Ubuntu-M.ttf", assetPath + "/ui/Ubuntu-M.ttf", false)); - project.files.add(new ProjectFile("android/assets/ui/ui.json", assetPath + "/ui/ui.json", false)); - - project.files.add(new ProjectFile("android/assets/ui/1/blade_logo.png", assetPath + "/ui/1/blade_logo.png", false)); - project.files.add(new ProjectFile("android/assets/ui/1/helpDesktop.png", assetPath + "/ui/1/helpDesktop.png", false)); - project.files.add(new ProjectFile("android/assets/ui/1/helpDesktop_es.png", assetPath + "/ui/1/helpDesktop_es.png", false)); - project.files.add(new ProjectFile("android/assets/ui/1/helpPie.png", assetPath + "/ui/1/helpPie.png", false)); - project.files.add(new ProjectFile("android/assets/ui/1/helpPie_es.png", assetPath + "/ui/1/helpPie_es.png", false)); - project.files.add(new ProjectFile("android/assets/ui/1/libgdx_logo.png", assetPath + "/ui/1/libgdx_logo.png", false)); - project.files.add(new ProjectFile("android/assets/ui/1/ui.atlas", assetPath + "/ui/1/ui.atlas", false)); - project.files.add(new ProjectFile("android/assets/ui/1/ui.png", assetPath + "/ui/1/ui.png", false)); - - project.files.add(new ProjectFile("android/assets/BladeEngine.properties", assetPath + "/BladeEngine.properties", false)); - - // android project - if (builder.modules.contains(ProjectType.ANDROID)) { - project.files.add(new ProjectFile("android/res/values/strings.xml")); - project.files.add(new ProjectFile("android/res/values/styles.xml", false)); - project.files.add(new ProjectFile("android/res/drawable-hdpi/ic_launcher.png", false)); - project.files.add(new ProjectFile("android/res/drawable-mdpi/ic_launcher.png", false)); - project.files.add(new ProjectFile("android/res/drawable-xhdpi/ic_launcher.png", false)); - project.files.add(new ProjectFile("android/res/drawable-xxhdpi/ic_launcher.png", false)); - project.files.add(new ProjectFile("android/src/AndroidLauncher", "android/src/" + packageDir + "/android/AndroidLauncher.java", true)); - project.files.add(new ProjectFile("android/AndroidManifest.xml")); - project.files.add(new ProjectFile("android/build.gradle", true)); - project.files.add(new ProjectFile("android/ic_launcher-web.png", false)); - project.files.add(new ProjectFile("android/proguard-project.txt", false)); - project.files.add(new ProjectFile("android/project.properties", false)); - project.files.add(new ProjectFile("local.properties", true)); - } - - // html project - if (builder.modules.contains(ProjectType.HTML)) { - project.files.add(new ProjectFile("html/build.gradle")); - project.files.add(new ProjectFile("html/src/HtmlLauncher", "html/src/" + packageDir + "/client/HtmlLauncher.java", true)); - project.files.add(new ProjectFile("html/GdxDefinition", "html/src/" + packageDir + "/GdxDefinition.gwt.xml", true)); - project.files.add(new ProjectFile("html/GdxDefinitionSuperdev", "html/src/" + packageDir + "/GdxDefinitionSuperdev.gwt.xml", true)); - project.files.add(new ProjectFile("html/war/index", "html/webapp/index.html", true)); - project.files.add(new ProjectFile("html/war/styles.css", "html/webapp/styles.css", false)); - project.files.add(new ProjectFile("html/war/refresh.png", "html/webapp/refresh.png", false)); - project.files.add(new ProjectFile("html/war/soundmanager2-jsmin.js", "html/webapp/soundmanager2-jsmin.js", false)); - project.files.add(new ProjectFile("html/war/soundmanager2-setup.js", "html/webapp/soundmanager2-setup.js", false)); - project.files.add(new ProjectFile("html/war/WEB-INF/web.xml", "html/webapp/WEB-INF/web.xml", true)); - } - - // ios robovm - if (builder.modules.contains(ProjectType.IOS)) { - project.files.add(new ProjectFile("ios/src/IOSLauncher", "ios/src/" + packageDir + "/ios/IOSLauncher.java", true)); - project.files.add(new ProjectFile("ios/data/Default.png", false)); - project.files.add(new ProjectFile("ios/data/Default@2x.png", false)); - project.files.add(new ProjectFile("ios/data/Default@2x~ipad.png", false)); - project.files.add(new ProjectFile("ios/data/Default-568h@2x.png", false)); - project.files.add(new ProjectFile("ios/data/Default~ipad.png", false)); - project.files.add(new ProjectFile("ios/data/Icon.png", false)); - project.files.add(new ProjectFile("ios/data/Icon@2x.png", false)); - project.files.add(new ProjectFile("ios/data/Icon-72.png", false)); - project.files.add(new ProjectFile("ios/data/Icon-72@2x.png", false)); - project.files.add(new ProjectFile("ios/build.gradle", true)); - project.files.add(new ProjectFile("ios/Info.plist.xml", false)); - project.files.add(new ProjectFile("ios/robovm.properties")); - project.files.add(new ProjectFile("ios/robovm.xml", true)); - } - - Map values = new HashMap(); - values.put("%APP_NAME%", appName); - values.put("%PACKAGE%", packageName); - values.put("%PACKAGE_DIR%", packageDir); - values.put("%MAIN_CLASS%", mainClass); - values.put("%ANDROID_SDK%", sdkPath); - values.put("%ASSET_PATH%", assetPath); - values.put("%BUILD_TOOLS_VERSION%", Versions.getBuildToolsVersion()); - values.put("%API_LEVEL%", Versions.getAndroidAPILevel()); - values.put("%GWT_VERSION%", Versions.getGwtVersion()); - if (builder.modules.contains(ProjectType.HTML)) { - values.put("%GWT_INHERITS%", parseGwtInherits(builder.bank.gwtInheritances, builder)); - } - - copyAndReplace(outputDir, project, values); - copyLibs(outputDir); - - builder.cleanUp(); - - // HACK executable flag isn't preserved for whatever reason... - new File(outputDir, "gradlew").setExecutable(true); - - RunProccess.runGradle(new File(outputDir), "clean" + parseGradleArgs(builder.modules, gradleArgs)); - } - - /** - * Copy the blade-engine.jar and libgdx-spine.jar to the output folder - * @param outputDir - * @throws IOException - */ - private void copyLibs(String outputDir) throws IOException { -// File bladeEngineFile = new File(BladeEngine.class.getProtectionDomain().getCodeSource().getLocation().getPath()); - File libSpineFile = new File(Skeleton.class.getProtectionDomain().getCodeSource().getLocation().getPath()); - - FileUtils.copyFileToDirectory(libSpineFile, new File(outputDir + "/libs")); - - // blade-engine.jar is in Maven Central now -// if(bladeEngineFile.isDirectory()) { -// EditorLogger.error("Editor is running inside IDE. Trying to build blade-engine.jar"); -// RunProccess.runGradle(bladeEngineFile.getParentFile().getParentFile(), ":blade-engine:jar"); -// -// FileUtils.copyDirectory(new File(bladeEngineFile.getParent() + "/build/libs"), new File(outputDir + "/libs")); -// } else { -// FileUtils.copyFileToDirectory(bladeEngineFile, new File(outputDir + "/libs")); -// } - } - - private void copyAndReplace (String outputDir, Project project, Map values) throws IOException { - File out = new File(outputDir); - if (!out.exists() && !out.mkdirs()) { - throw new RuntimeException("Couldn't create output directory '" + out.getAbsolutePath() + "'"); - } - - for (ProjectFile file : project.files) { - copyFile(file, out, values); - } - } - - private byte[] readResource (String resource, String path) { - InputStream in = null; - try { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024 * 10]; - in = BladeEngineSetup.class.getResourceAsStream(path + resource); - if (in == null) throw new RuntimeException("Couldn't read resource '" + resource + "'"); - int read = 0; - while ((read = in.read(buffer)) > 0) { - bytes.write(buffer, 0, read); - } - return bytes.toByteArray(); - } catch (IOException e) { - throw new RuntimeException("Couldn't read resource '" + resource + "'", e); - } finally { - if (in != null) try { - in.close(); - } catch (IOException e) { - } - } - } - - private byte[] readResource (File file) throws IOException { - InputStream in = null; - try { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024 * 10]; - in = new FileInputStream(file); - int read = 0; - while ((read = in.read(buffer)) > 0) { - bytes.write(buffer, 0, read); - } - return bytes.toByteArray(); - } catch (Exception e) { - throw new IOException("Couldn't read resource '" + file.getAbsoluteFile() + "'", e); - } finally { - if (in != null) try { - in.close(); - } catch (IOException e) { - } - } - } - - private String readResourceAsString (String resource, String path) { - try { - return new String(readResource(resource, path), "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - - private String readResourceAsString (File file) throws IOException { - try { - return new String(readResource(file), "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - - private void writeFile (File outFile, byte[] bytes) { - OutputStream out = null; - - try { - out = new BufferedOutputStream(new FileOutputStream(outFile)); - out.write(bytes); - } catch (IOException e) { - throw new RuntimeException("Couldn't write file '" + outFile.getAbsolutePath() + "'", e); - } finally { - if (out != null) try { - out.close(); - } catch (IOException e) { - } - } - } - - private void writeFile (File outFile, String text) { - try { - writeFile(outFile, text.getBytes("UTF-8")); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - - private void copyFile (ProjectFile file, File out, Map values) throws IOException { - File outFile = new File(out, file.outputName); - if (!outFile.getParentFile().exists() && !outFile.getParentFile().mkdirs()) { - throw new RuntimeException("Couldn't create dir '" + outFile.getAbsolutePath() + "'"); - } - - boolean isTemp = file instanceof TemporaryProjectFile ? true : false; - - if (file.isTemplate) { - String txt; - if (isTemp) { - txt = readResourceAsString(((TemporaryProjectFile)file).file); - } else { - txt = readResourceAsString(file.resourceName, file.resourceLoc); - } - txt = replace(txt, values); - writeFile(outFile, txt); - } else { - if (isTemp) { - writeFile(outFile, readResource(((TemporaryProjectFile)file).file)); - } else { - writeFile(outFile, readResource(file.resourceName, file.resourceLoc)); - } - } - } - - private String replace (String txt, Map values) { - for (String key : values.keySet()) { - String value = values.get(key); - txt = txt.replace(key, value); - } - return txt; - } - - private static void printHelp () { - System.out - .println("Usage: GdxSetup --dir --name --package --mainClass --sdkLocation "); - System.out.println("dir ... the directory to write the project files to"); - System.out.println("name ... the name of the application"); - System.out.println("package ... the Java package name of the application"); - System.out.println("mainClass ... the name of your main ApplicationListener"); - System.out.println("sdkLocation ... the location of your android SDK. Uses ANDROID_HOME if not specified"); - } - - private static Map parseArgs (String[] args) { - if (args.length % 2 != 0) { - printHelp(); - System.exit(-1); - } - - Map params = new HashMap(); - for (int i = 0; i < args.length; i += 2) { - String param = args[i].replace("--", ""); - String value = args[i + 1]; - params.put(param, value); - } - return params; - } - - private String parseGwtInherits (HashMap gwtInheritances, ProjectBuilder builder) { - String parsed = ""; - for (ProjectDependency dep : gwtInheritances.keySet()) { - if (containsDependency(builder.dependencies, dep)) { - for (String inherit : gwtInheritances.get(dep)) { - parsed += "\t\n"; - } - } - } - return parsed; - } - - private String parseGradleArgs (List modules, List args) { - String argString = ""; - if (args == null) return argString; - for (String argument : args) { - if (argument.equals("afterEclipseImport") && !modules.contains(ProjectType.DESKTOP)) continue; - argString += " " + argument; - } - return argString; - } - - private boolean containsDependency (List dependencyList, ProjectDependency projectDependency) { - for (Dependency dep : dependencyList) { - if (dep.getName().equals(projectDependency.name())) { - return true; - } - } - return false; - } - - public static void main (String[] args) throws IOException { - Map params = parseArgs(args); - if (!params.containsKey("dir") || - !params.containsKey("name") || - !params.containsKey("package") || - !params.containsKey("mainClass") || - ((!params.containsKey("sdkLocation") && System.getenv("ANDROID_HOME") == null))) { - printHelp(); - } else { - String sdkLocation = ""; - if (System.getenv("ANDROID_HOME") != null && !params.containsKey("sdkLocation")) { - sdkLocation = System.getenv("ANDROID_HOME"); - } else { - sdkLocation = params.get("sdkLocation"); - } - - DependencyBank bank = new DependencyBank(); - ProjectBuilder builder = new ProjectBuilder(bank); - List projects = new ArrayList(); - projects.add(ProjectType.CORE); - projects.add(ProjectType.DESKTOP); - projects.add(ProjectType.ANDROID); - projects.add(ProjectType.IOS); - projects.add(ProjectType.HTML); - - List dependencies = new ArrayList(); - dependencies.add(bank.getDependency(ProjectDependency.GDX)); - - builder.buildProject(projects, dependencies); - builder.build(); - new BladeEngineSetup().build(builder, params.get("dir"), params.get("name"), params.get("package"), params.get("mainClass"), - sdkLocation, null); - } - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/BuildScriptHelper.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/BuildScriptHelper.java deleted file mode 100644 index f6bfba87a..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/BuildScriptHelper.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.bladecoder.engineeditor.setup; - - -import java.io.BufferedWriter; -import java.io.IOException; -import java.util.List; - -import com.bladecoder.engineeditor.setup.DependencyBank.ProjectType; -import com.bladecoder.engineeditor.utils.Versions; - -public class BuildScriptHelper { - - private static int indent = 0; - - public static void addBuildScript(List projects, BufferedWriter wr) throws IOException { - write(wr, "buildscript {"); - //repos - write(wr, "repositories {"); - write(wr, DependencyBank.mavenCentral); - if (projects.contains(ProjectType.HTML)) { - write(wr, DependencyBank.jCenter); - } - write(wr, "}"); - //dependencies - write(wr, "dependencies {"); - if (projects.contains(ProjectType.HTML)) { - write(wr, "classpath '" + DependencyBank.gwtPluginImport + "'"); - } - if (projects.contains(ProjectType.ANDROID)) { - write(wr, "classpath '" + DependencyBank.androidPluginImport + "'"); - } - if (projects.contains(ProjectType.IOS)) { - write(wr, "classpath '" + DependencyBank.roboVMPluginImport + "'"); - } - write(wr, "}"); - write(wr, "}"); - space(wr); - } - - public static void addAllProjects(BufferedWriter wr) throws IOException { - write(wr, "allprojects {"); - write(wr, "apply plugin: \"eclipse\""); - write(wr, "apply plugin: \"idea\""); - space(wr); - write(wr, "version = '1.0'"); - - write(wr, "if(project.hasProperty('passed_version'))\n version = passed_version"); - - write(wr, "ext {"); - write(wr, "appName = '%APP_NAME%'"); - write(wr, "bladeEngineVersion = '" + Versions.getVersion() + "'"); - write(wr, "gdxVersion = '" + Versions.getLibgdxVersion() + "'"); - write(wr, "roboVMVersion = '" + Versions.getRoboVMVersion() + "'"); - write(wr, "}"); - space(wr); - write(wr, "repositories {"); - write(wr, DependencyBank.mavenCentral); - write(wr, "maven { url \"" + DependencyBank.libGDXSnapshotsUrl + "\" }"); - write(wr, "maven { url \"" + DependencyBank.libGDXReleaseUrl + "\" }"); - write(wr, "}"); - write(wr, "}"); - } - - public static void addProject(ProjectType project, List dependencies, BufferedWriter wr) throws IOException { - space(wr); - write(wr, "project(\":" + project.getName() + "\") {"); - for (String plugin : project.getPlugins()) { - write(wr, "apply plugin: \"" + plugin + "\""); - } - space(wr); - addConfigurations(project, wr); - space(wr); - addDependencies(project, dependencies, wr); - write(wr, "}"); - } - - private static void addDependencies(ProjectType project, List dependencyList, BufferedWriter wr) throws IOException { - write(wr, "dependencies {"); - if (!project.equals(ProjectType.CORE)) { - write(wr, "compile project(\":" + ProjectType.CORE.getName() + "\")"); - } - for (Dependency dep : dependencyList) { - if (dep.getDependencies(project) == null) continue; - for (String moduleDependency : dep.getDependencies(project)) { - if (moduleDependency == null) continue; - if ((project.equals(ProjectType.ANDROID) || project.equals(ProjectType.IOS)) && moduleDependency.contains("native")) { - write(wr, "natives \"" + moduleDependency + "\""); - } else { - if(moduleDependency.startsWith("fileTree(")) - write(wr, "compile " + moduleDependency); - else - write(wr, "compile \"" + moduleDependency + "\""); - } - } - } - write(wr, "}"); - } - - private static void addConfigurations(ProjectType project, BufferedWriter wr) throws IOException { - if (project.equals(ProjectType.IOS) || project.equals(ProjectType.ANDROID)) { - write(wr, "configurations { natives }"); - } - } - - private static void write(BufferedWriter wr, String input) throws IOException { - int delta = StringUtils.countMatches(input, '{') - StringUtils.countMatches(input, '}'); - indent += delta *= 4; - indent = clamp(indent); - if (delta > 0) { - wr.write(StringUtils.repeat(" ", clamp(indent - 4)) + input + "\n"); - } else if (delta < 0) { - wr.write(StringUtils.repeat(" ", clamp(indent)) + input + "\n"); - } else { - wr.write(StringUtils.repeat(" ", indent) + input + "\n"); - } - } - - private static void space(BufferedWriter wr) throws IOException { - wr.write("\n"); - } - - private static int clamp(int indent) { - if (indent < 0) { - return 0; - } - return indent; - } - - static class StringUtils { - - public static int countMatches(String input, char match) { - int count = 0; - for (int i = 0; i < input.length(); i++) { - if (input.charAt(i) == match) { - count++; - } - } - return count; - } - - public static String repeat(String toRepeat, int count) { - String repeat = ""; - for (int i = 0; i < count; i++) { - repeat += toRepeat; - } - return repeat; - } - } - -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/Dependency.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/Dependency.java deleted file mode 100644 index 8a2b77099..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/Dependency.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.bladecoder.engineeditor.setup; - - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import com.bladecoder.engineeditor.setup.DependencyBank.ProjectType; - - -public class Dependency { - - private HashMap subDependencyMap = new HashMap(); - private String name; - - public Dependency(String name, String[]... subDependencies) { - this.name = name; - for (ProjectType type : ProjectType.values()) { - subDependencyMap.put(type, subDependencies[type.ordinal()]); - } - } - - public String[] getDependencies(ProjectType type) { - return subDependencyMap.get(type); - } - - public List getIncompatibilities(ProjectType type) { - List incompat = new ArrayList(); - String[] subArray = subDependencyMap.get(type); - if (subArray == null) { - incompat.add("Dependency " + name + " is not compatible with sub module " + type.getName().toUpperCase()); - } - return incompat; - } - - public String getName() { - return name; - } - -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/DependencyBank.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/DependencyBank.java deleted file mode 100644 index 97d886729..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/DependencyBank.java +++ /dev/null @@ -1,190 +0,0 @@ -package com.bladecoder.engineeditor.setup; - - -import java.util.HashMap; -import java.util.LinkedHashMap; - -public class DependencyBank { - //Repositories - static String mavenCentral = "mavenCentral()"; - static String jCenter = "jcenter()"; - static String libGDXSnapshotsUrl = "https://oss.sonatype.org/content/repositories/snapshots/"; - static String libGDXReleaseUrl = "https://oss.sonatype.org/content/repositories/releases/"; - - //Project plugins - static String gwtPluginImport = "de.richsource.gradle.plugins:gwt-gradle-plugin:0.5"; - static String androidPluginImport = "com.android.tools.build:gradle:0.13+"; - static String roboVMPluginImport = "org.robovm:robovm-gradle-plugin:1.0.0-alpha-04"; - - HashMap gdxDependencies = new HashMap(); - LinkedHashMap gwtInheritances = new LinkedHashMap(); - - public DependencyBank() { - for (ProjectDependency projectDep : ProjectDependency.values()) { - Dependency dependency = new Dependency(projectDep.name(), - projectDep.getDependencies(ProjectType.CORE), - projectDep.getDependencies(ProjectType.DESKTOP), - projectDep.getDependencies(ProjectType.ANDROID), - projectDep.getDependencies(ProjectType.IOS), - projectDep.getDependencies(ProjectType.HTML)); - gdxDependencies.put(projectDep, dependency); - } - gwtInheritances.put(ProjectDependency.GDX, new String[]{"com.badlogic.gdx.backends.gdx_backends_gwt"}); - gwtInheritances.put(ProjectDependency.CONTROLLERS, new String[]{"com.badlogic.gdx.controllers.controllers-gwt"}); - gwtInheritances.put(ProjectDependency.BOX2D, new String[]{"com.badlogic.gdx.physics.box2d.box2d-gwt"}); - gwtInheritances.put(ProjectDependency.BOX2DLIGHTS, new String[]{"Box2DLights"}); - gwtInheritances.put(ProjectDependency.ASHLEY, new String[]{"com.badlogic.ashley_gwt"}); - } - - public Dependency getDependency(ProjectDependency gdx) { - return gdxDependencies.get(gdx); - } - - - /** - * This enum will hold all dependencies available for libgdx, allowing the setup to pick the ones needed by default, - * and allow the option to choose extensions as the user wishes. - *

- * These depedency strings can be later used in a simple gradle plugin to manipulate the users project either after/before - * project generation - * - * @see Dependency for the object that handles sub-module dependencies. If no dependency is found for a sub-module, ie - * FreeTypeFont for gwt, an exception is thrown so the user can be notified of incompatability - */ - public enum ProjectDependency { - GDX( - new String[]{"com.badlogicgames.gdx:gdx:$gdxVersion", "fileTree(dir: '../libs', include: '*.jar')", "com.bladecoder.engine:blade-engine:$bladeEngineVersion"}, - new String[]{"com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion", "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"}, - new String[]{"com.badlogicgames.gdx:gdx-backend-android:$gdxVersion", "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi", "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a", "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86", "fileTree(dir: '../libs', include: '*.jar')"}, - new String[]{"org.robovm:robovm-rt:${roboVMVersion}", "org.robovm:robovm-cocoatouch:${roboVMVersion}", "com.badlogicgames.gdx:gdx-backend-robovm:$gdxVersion", "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-ios"}, - new String[]{"com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion", "com.badlogicgames.gdx:gdx:$gdxVersion:sources", "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion:sources"}, - - "Core Library for LibGDX" - ), - BULLET( - new String[]{"com.badlogicgames.gdx:gdx-bullet:$gdxVersion"}, - new String[]{"com.badlogicgames.gdx:gdx-bullet-platform:$gdxVersion:natives-desktop"}, - new String[]{"com.badlogicgames.gdx:gdx-bullet:$gdxVersion", "com.badlogicgames.gdx:gdx-bullet-platform:$gdxVersion:natives-armeabi", "com.badlogicgames.gdx:gdx-bullet-platform:$gdxVersion:natives-armeabi-v7a", "com.badlogicgames.gdx:gdx-bullet-platform:$gdxVersion:natives-x86"}, - new String[]{"com.badlogicgames.gdx:gdx-bullet-platform:$gdxVersion:natives-ios"}, - null, - - "3D Collision Detection and Rigid Body Dynamics" - ), - FREETYPE( - new String[]{"com.badlogicgames.gdx:gdx-freetype:$gdxVersion"}, - new String[]{"com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop"}, - new String[]{"com.badlogicgames.gdx:gdx-freetype:$gdxVersion", "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi", "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a", "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86"}, - new String[]{"com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-ios"}, - null, - - "Generate BitmapFonts from .ttf font files" - ), - TOOLS( - new String[]{}, - new String[]{"com.badlogicgames.gdx:gdx-tools:$gdxVersion"}, - new String[]{}, - new String[]{}, - new String[]{}, - - "Collection of tools, including 2D/3D particle editors, texture packers, and file processors" - ), - CONTROLLERS( - new String[]{"com.badlogicgames.gdx:gdx-controllers:$gdxVersion"}, - new String[]{"com.badlogicgames.gdx:gdx-controllers-desktop:$gdxVersion", "com.badlogicgames.gdx:gdx-controllers-platform:$gdxVersion:natives-desktop"}, - new String[]{"com.badlogicgames.gdx:gdx-controllers:$gdxVersion", "com.badlogicgames.gdx:gdx-controllers-android:$gdxVersion"}, - new String[] {}, // works on iOS but never reports any controllers :) - new String[]{"com.badlogicgames.gdx:gdx-controllers:$gdxVersion:sources", "com.badlogicgames.gdx:gdx-controllers-gwt:$gdxVersion", "com.badlogicgames.gdx:gdx-controllers-gwt:$gdxVersion:sources"}, - - "Controller/Gamepad API" - ), - BOX2D( - new String[]{"com.badlogicgames.gdx:gdx-box2d:$gdxVersion"}, - new String[]{"com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop"}, - new String[]{"com.badlogicgames.gdx:gdx-box2d:$gdxVersion", "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-armeabi", "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-armeabi-v7a", "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-x86"}, - new String[]{"com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-ios"}, - new String[]{"com.badlogicgames.gdx:gdx-box2d:$gdxVersion:sources", "com.badlogicgames.gdx:gdx-box2d-gwt:$gdxVersion:sources"}, - - "2D Physics Library" - ), - BOX2DLIGHTS( - new String[]{"com.badlogicgames.box2dlights:box2dlights:1.2"}, - new String[]{}, - new String[]{"com.badlogicgames.box2dlights:box2dlights:1.2"}, - new String[]{}, - new String[]{"com.badlogicgames.box2dlights:box2dlights:1.2:sources"}, - - "2D Lighting framework that utilises Box2D" - ), - ASHLEY( - new String[]{"com.badlogicgames.ashley:ashley:1.1.0"}, - new String[]{}, - new String[]{"com.badlogicgames.ashley:ashley:1.1.0"}, - new String[]{}, - new String[]{"com.badlogicgames.ashley:ashley:1.1.0:sources"}, - - "Lightweight Entity framework" - ); - - private String[] coreDependencies; - private String[] desktopDependencies; - private String[] androidDependencies; - private String[] iosDependencies; - private String[] gwtDependencies; - private String description; - - ProjectDependency(String[] coreDeps, String[] desktopDeps, String[] androidDeps, String[] iosDeps, String[] gwtDeps, String description) { - this.coreDependencies = coreDeps; - this.desktopDependencies = desktopDeps; - this.androidDependencies = androidDeps; - this.iosDependencies = iosDeps; - this.gwtDependencies = gwtDeps; - this.description = description; - } - - public String[] getDependencies(ProjectType type) { - switch (type) { - case CORE: - return coreDependencies; - case DESKTOP: - return desktopDependencies; - case ANDROID: - return androidDependencies; - case IOS: - return iosDependencies; - case HTML: - return gwtDependencies; - } - return null; - } - - public String getDescription() { - return description; - } - } - - - public enum ProjectType { - CORE("core", new String[]{"java"}), - DESKTOP("desktop", new String[]{"java"}), - ANDROID("android", new String[]{"android"}), - IOS("ios", new String[]{"java", "robovm"}), - HTML("html", new String[]{"gwt", "war"}); - - private final String name; - private final String[] plugins; - - ProjectType(String name, String plugins[]) { - this.name = name; - this.plugins = plugins; - } - - public String getName() { - return name; - } - - public String[] getPlugins() { - return plugins; - } - } - -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/ProjectBuilder.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/ProjectBuilder.java deleted file mode 100644 index 5af578b00..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/ProjectBuilder.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.bladecoder.engineeditor.setup; - - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.bladecoder.engineeditor.setup.DependencyBank.ProjectType; - -public class ProjectBuilder { - - DependencyBank bank; - List modules = new ArrayList(); - List dependencies = new ArrayList(); - File settingsFile; - File buildFile; - - public ProjectBuilder(DependencyBank bank) { - this.bank = bank; - } - - public List buildProject(List projects, List dependencies) { - List incompatibilities = new ArrayList(); - for (Dependency dep : dependencies) { - for (ProjectType type : projects) { - dep.getDependencies(type); - incompatibilities.addAll(dep.getIncompatibilities(type)); - } - } - this.modules = projects; - this.dependencies = dependencies; - return incompatibilities; - } - - public boolean build() throws IOException { - settingsFile = File.createTempFile("libgdx-setup-settings", ".gradle"); - buildFile = File.createTempFile("libgdx-setup-build", ".gradle"); - if (!settingsFile.exists()) { - settingsFile.createNewFile(); - } - if (!buildFile.exists()) { - buildFile.createNewFile(); - } - settingsFile.setWritable(true); - buildFile.setWritable(true); - try { - FileWriter settingsWriter = new FileWriter(settingsFile.getAbsoluteFile()); - BufferedWriter settingsBw = new BufferedWriter(settingsWriter); - String settingsContents = "include "; - for (ProjectType module : modules) { - settingsContents += "'" + module.getName() + "'"; - if (modules.indexOf(module) != modules.size() - 1) { - settingsContents += ", "; - } - } - settingsBw.write(settingsContents); - settingsBw.close(); - settingsWriter.close(); - - FileWriter buildWriter = new FileWriter(buildFile.getAbsoluteFile()); - BufferedWriter buildBw = new BufferedWriter(buildWriter); - - BuildScriptHelper.addBuildScript(modules, buildBw); - BuildScriptHelper.addAllProjects(buildBw); - for (ProjectType module : modules) { - BuildScriptHelper.addProject(module, dependencies, buildBw); - } - - //Add task here for now - buildBw.write("\n"); - buildBw.write("tasks.eclipse.doLast {\n"); - buildBw.write(" delete \".project\"\n"); - buildBw.write("}"); - - buildBw.close(); - buildWriter.close(); - return true; - } catch (IOException e) { - e.printStackTrace(); - return false; - } - } - - public void cleanUp() { - settingsFile.deleteOnExit(); - buildFile.deleteOnExit(); - } - -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ActorList.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ActorList.java deleted file mode 100644 index 1a90427aa..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ActorList.java +++ /dev/null @@ -1,177 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.ChapterDocument; -import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.ui.components.CellRenderer; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.ElementList; - -public class ActorList extends ElementList { - - private ImageButton playerBtn; - - public ActorList(Skin skin) { - super(skin, true); - - playerBtn = new ImageButton(skin); - toolbar.addToolBarButton(playerBtn, "ic_check", - "Set player", "Set player"); - playerBtn.setDisabled(true); - - list.addListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, Actor actor) { -// EditorLogger.debug("ACTOR LIST ELEMENT SELECTED"); - int pos = list.getSelectedIndex(); - - if (pos == -1) { - Ctx.project.setSelectedActor(null); - } else { - Element a = list.getItems().get(pos); - Ctx.project.setSelectedActor(a); - } - - toolbar.disableEdit(pos == -1); - playerBtn.setDisabled(pos== -1); - } - }); - - playerBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - setPlayer(); - } - }); - - list.setCellRenderer(listCellRenderer); - - Ctx.project.addPropertyChangeListener(Project.NOTIFY_ACTOR_SELECTED, - new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent e) { - int pos = list.getSelectedIndex(); - - // Element newActor = (Element) e.getNewValue(); - Element newActor = Ctx.project.getSelectedActor(); - - if (newActor == null) - return; - - if (pos != -1) { - Element oldActor = list.getItems().get(pos); - - if (oldActor == newActor) { - return; - } - } - - int i = list.getItems().indexOf(newActor, true); - if(i >= 0) - list.setSelectedIndex(i); - } - }); - } - - @Override - protected EditElementDialog getEditElementDialogInstance( - Element e) { - return new EditActorDialog(skin, doc, parent, e); - } - - private void setPlayer() { - ChapterDocument scn = (ChapterDocument) doc; - - int pos = list.getSelectedIndex(); - - if (pos == -1) - return; - - Element e = list.getItems().get(pos); - - if (!e.getAttribute("type").equals(ChapterDocument.NO_RENDERER_ACTOR_TYPE) - ) { - String id = e.getAttribute("id"); - - scn.setRootAttr(parent, "player", id); - } - } - - // ------------------------------------------------------------------------- - // ListCellRenderer - // ------------------------------------------------------------------------- - private final CellRenderer listCellRenderer = new CellRenderer() { - - @Override - protected String getCellTitle(Element e) { - return e.getAttribute("id"); - } - - @Override - protected String getCellSubTitle(Element e) { - return doc.getTranslation(e.getAttribute("desc")); - } - - @Override - public TextureRegion getCellImage(Element e) { - String type = e.getAttribute("type"); - - boolean isPlayer = ((Element)e.getParentNode()).getAttribute("player").equals( - e.getAttribute("id")); - - String u = null; - - if (isPlayer) { - u = "ic_character_actor"; - } else if (type.equals(ChapterDocument.IMAGE_ACTOR_TYPE)) { - u = "ic_sprite_actor"; - } else if (type.equals(ChapterDocument.ATLAS_ACTOR_TYPE)) { - u = "ic_sprite_actor"; - } else if (type.equals(ChapterDocument.NO_RENDERER_ACTOR_TYPE)) { - u = "ic_base_actor"; - } else if (type.equals(ChapterDocument.SPINE_ACTOR_TYPE)) { - u = "ic_spine"; - } else if (type.equals(ChapterDocument.SPRITE3D_ACTOR_TYPE)) { - u = "ic_3d"; - } - - return Ctx.assetManager.getIcon(u); - } - - @Override - protected boolean hasSubtitle() { - return true; - } - - @Override - protected boolean hasImage() { - return true; - } - }; -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ActorPanel.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ActorPanel.java deleted file mode 100644 index 5265e6d5b..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ActorPanel.java +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.ChapterDocument; -import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.ui.components.HeaderPanel; -import com.bladecoder.engineeditor.ui.components.TabPanel; - -public class ActorPanel extends HeaderPanel { - - private TabPanel tabPanel; - private VerbList verbList; - private DialogList dialogList; - private SpriteList faList; - private SoundList soundList; - private ActorProps props; - - public ActorPanel(Skin skin) { - super(skin, "ACTOR"); - tabPanel = new TabPanel(skin); - verbList = new VerbList(skin); - dialogList = new DialogList(skin); - faList = new SpriteList(skin); - props = new ActorProps(skin); - soundList = new SoundList(skin); - - setContent(tabPanel); - - Ctx.project.addPropertyChangeListener(Project.NOTIFY_ACTOR_SELECTED, - new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent e) { - Element a = (Element) e.getNewValue(); - ChapterDocument doc = Ctx.project.getSelectedChapter(); - - String selTitle = tabPanel.getSelectedIndex() == -1? null: tabPanel.getTitleAt(tabPanel.getSelectedIndex()); - tabPanel.clear(); - - if (a != null) { - - String type = doc.getType(a); - - if (!type.equals(ChapterDocument.NO_RENDERER_ACTOR_TYPE)) - tabPanel.addTab("Sprites", faList); - - if (!type.equals("foreground")) { - tabPanel.addTab("Verbs", verbList); - tabPanel.addTab("Sounds", soundList); - } - - tabPanel.addTab("Dialogs", dialogList); - tabPanel.addTab("Properties", props); - setTile("ACTOR " + doc.getId(a)); - - // select previous selected tab - if (selTitle != null) { - for (int i = 0; i < tabPanel.getTabCount(); i++) { - if (tabPanel.getTitleAt(i).equals(selTitle)) { - tabPanel.setTab(i); - } - } - } - - } else { - setTile("ACTOR"); - } - - faList.addElements(doc, a, "frame_animation"); - verbList.addElements(doc, a, "verb"); - dialogList.addElements(doc, a, "dialog"); - soundList.addElements(doc, a, "sound"); - props.setActorDocument(doc, a); - } - - }); - - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ActorProps.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ActorProps.java deleted file mode 100644 index 4667438a3..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ActorProps.java +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.bladecoder.engineeditor.model.ChapterDocument; -import com.bladecoder.engineeditor.ui.components.PropertyTable; -import com.bladecoder.engineeditor.utils.EditorLogger; - -public class ActorProps extends PropertyTable { - - public static final String DESC_PROP = "Description"; - public static final String POS_X_PROP = "pos X"; - public static final String POS_Y_PROP = "pos Y"; - public static final String VISIBLE_PROP = "visible"; - public static final String ACTIVE_PROP = "active"; - public static final String STATE_PROP = "state"; - public static final String WALKING_SPEED_PROP = "Walking Speed"; - - private ChapterDocument doc; - private Element actor; - -// TableModelListener tableModelListener = new TableModelListener() { -// @Override -// public void tableChanged(TableModelEvent e) { -// if (e.getType() == TableModelEvent.UPDATE) { -// int row = e.getFirstRow(); -// updateModel((String) propertyTable.getModel().getValueAt(row, 0), -// (String) propertyTable.getModel().getValueAt(row, 1)); -// } -// } -// }; - - PropertyChangeListener propertyChangeListener = new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - EditorLogger.debug("Property Listener: " + evt.getPropertyName()); - setActorDocument(doc, actor); - } - }; - - public ActorProps(Skin skin) { - super(skin); - } - - public void setActorDocument(ChapterDocument doc, Element a) { - this.doc = doc; - this.actor = a; - clear(); - - if (a != null) { - - if (!a.getAttribute("type").equals(ChapterDocument.NO_RENDERER_ACTOR_TYPE)) { - Vector2 pos = doc.getPos(a); - addProperty(POS_X_PROP, Float.toString(pos.x), Types.FLOAT); - addProperty(POS_Y_PROP, Float.toString(pos.y), Types.FLOAT); - } - - addProperty(DESC_PROP, doc.getRootAttr(a, "desc")); - - addProperty(VISIBLE_PROP, doc.getRootAttr(a, "visible"), Types.BOOLEAN); - - addProperty(ACTIVE_PROP, doc.getRootAttr(a, "active"), Types.BOOLEAN); - addProperty(STATE_PROP, doc.getRootAttr(a, "state")); - - - if (!a.getAttribute("type").equals("background") && - !a.getAttribute("type").equals("foreground")) { - addProperty(WALKING_SPEED_PROP, doc.getRootAttr(a, "walking_speed")); - } - - doc.addPropertyChangeListener(propertyChangeListener); - - invalidateHierarchy(); - } - } - - @Override - protected void updateModel(String property, String value) { - if (property.equals(DESC_PROP)) { - doc.setRootAttr(actor, "desc", value); - } else if (property.equals(POS_X_PROP)) { - Vector2 pos = doc.getPos(actor); - pos.x = Float.parseFloat(value); - doc.setPos(actor, pos); - } else if (property.equals(POS_Y_PROP)) { - Vector2 pos = doc.getPos(actor); - pos.y = Float.parseFloat(value); - doc.setPos(actor, pos); - } else if (property.equals(VISIBLE_PROP)) { - doc.setRootAttr(actor, "visible", value); - } else if (property.equals(ACTIVE_PROP)) { - doc.setRootAttr(actor, "active", value); - } else if (property.equals(STATE_PROP)) { - doc.setRootAttr(actor, "state", value); - } else if (property.equals(WALKING_SPEED_PROP)) { - doc.setRootAttr(actor, "walking_speed", value); - } - - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/AssetsList.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/AssetsList.java deleted file mode 100644 index 878adee93..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/AssetsList.java +++ /dev/null @@ -1,337 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.awt.Desktop; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; -import java.util.List; - -import javax.swing.JFileChooser; -import javax.swing.filechooser.FileNameExtensionFilter; - -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Container; -import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; -import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.utils.Array; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.ui.components.CustomList; -import com.bladecoder.engineeditor.ui.components.EditToolbar; -import com.bladecoder.engineeditor.utils.ImageUtils; - -public class AssetsList extends Table { - private static final String[] ASSET_TYPES = { "3d models", "backgrounds", - "atlases", "music", "sounds", "images", "spine" }; - - private SelectBox assetTypes; - protected EditToolbar toolbar; - protected CustomList list; - protected Skin skin; - protected Container container; - - private File lastDir; - - public AssetsList(Skin skin) { - super(skin); - - assetTypes = new SelectBox(skin); - assetTypes.setItems(ASSET_TYPES); - - this.skin = skin; - - list = new CustomList(skin); - - Array items = new Array(); - list.setItems(items); - - ScrollPane scrollPane = new ScrollPane(list, skin); - container = new Container(scrollPane); - container.fill(); - container.prefHeight(100); - - toolbar = new EditToolbar(skin); -// debug(); - add(assetTypes).expandX().fillX(); - row().fill(); - add(toolbar).expandX().fillX(); - row().fill(); - add(container).expandY().fill(); - - toolbar.addCreateListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, Actor actor) { - create(); - } - }); - - toolbar.addEditListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, Actor actor) { - edit(); - } - }); - - toolbar.addDeleteListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, Actor actor) { - delete(); - } - }); - - - list.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - toolbar.disableEdit(false); - } - }); - - - Ctx.project.addPropertyChangeListener(Project.NOTIFY_PROJECT_LOADED, - new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent arg0) { - toolbar.disableCreate(Ctx.project.getProjectDir() == null); - addAssets(); - } - }); - - assetTypes.addListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, Actor actor) { - addAssets(); - } - }); - } - - private void addAssets() { - list.getItems().clear(); - - if (Ctx.project.getProjectDir() != null) { - String type = assetTypes.getSelected(); - String dir = getAssetDir(type); - - if (type.equals("backgrounds") || type.equals("images") || type.equals("atlases")) - dir += "/1"; - - String[] files = new File(dir).list(new FilenameFilter() { - @Override - public boolean accept(File arg0, String arg1) { - String type = assetTypes.getSelected(); - - if (type.equals("atlases") && !arg1.endsWith(".atlas")) - return false; - - return true; - } - }); - - if (files != null) - for (String f : files) - list.getItems().add(f); - - if (list.getItems().size > 0) { - list.setSelectedIndex(0); - } - } - - toolbar.disableCreate(Ctx.project.getProjectDir() == null); - } - - private String getAssetDir(String type) { - String dir; - - if (type.equals("backgrounds")) { - dir = Ctx.project.getProjectPath() + "/" + Project.BACKGROUNDS_PATH; - } else if (type.equals("atlases")) { - dir = Ctx.project.getProjectPath() + "/" + Project.ATLASES_PATH; - } else if (type.equals("music")) { - dir = Ctx.project.getProjectPath() + "/" + Project.MUSIC_PATH; - } else if (type.equals("sounds")) { - dir = Ctx.project.getProjectPath() + "/" + Project.SOUND_PATH; - } else if (type.equals("images")) { - dir = Ctx.project.getProjectPath() + "/" + Project.IMAGE_PATH; - } else if (type.equals("3d models")) { - dir = Ctx.project.getProjectPath() + "/" + Project.SPRITE3D_PATH; - } else if (type.equals("spine")) { - dir = Ctx.project.getProjectPath() + "/" + Project.SPINE_PATH; - } else { - dir = Ctx.project.getProjectPath() + Project.ASSETS_PATH; - } - - return dir; - } - - private void create() { - String type = assetTypes.getSelected(); - - if (type.equals("atlases")) { - new CreateAtlasDialog(skin).setVisible(true); - } else { - - JFileChooser chooser = new JFileChooser(lastDir); - chooser.setDialogTitle("Select the '" + type + "' asset files"); - chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); - chooser.setMultiSelectionEnabled(true); - - FileNameExtensionFilter filter = null; - - if (type.equals("backgrounds") || type.equals("images")) - filter = new FileNameExtensionFilter("Images", "jpg", "png", - "etc1"); - else if (type.equals("music") || type.equals("sounds")) - filter = new FileNameExtensionFilter("Music", "wav", "mp3", - "ogg"); - else if (type.equals("3d models")) - filter = new FileNameExtensionFilter("3D Models", "g3db", "png"); - else if (type.equals("spine")) - filter = new FileNameExtensionFilter("Spine", "skel", "json"); - - chooser.removeChoosableFileFilter(chooser.getChoosableFileFilters()[0]); - chooser.addChoosableFileFilter(filter); - - if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { - try { - File[] files = chooser.getSelectedFiles(); - String dir = getAssetDir(type); - lastDir = chooser.getSelectedFile(); - - for (File f : files) { - if (type.equals("backgrounds") - || type.equals("images")) { - List res = Ctx.project.getResolutions(); - - for (String r : res) { - File destFile = new File(dir + "/" + r - + "/" + f.getName()); - float scale = Float.parseFloat(r); - - if (scale != 1.0f) { - - ImageUtils.scaleImageFile(f, destFile, - scale); - } else { - Files.copy(f.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING); - } - } - } else { - File destFile = new File(dir + "/" + f.getName()); - Files.copy(f.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING); - } - - } - - } catch (Exception ex) { - String msg = "Something went wrong while getting the assets.\n\n" - + ex.getClass().getSimpleName() - + " - " - + ex.getMessage(); - Ctx.msg.show(getStage(), msg, 4); - ex.printStackTrace(); - } - } - } - - addAssets(); - } - - private void edit() { - if (Desktop.isDesktopSupported()) { - try { - Desktop.getDesktop().open( - new File(Ctx.project.getProjectDir().getAbsoluteFile() - + "/assets")); - } catch (IOException e1) { - String msg = "Something went wrong while opening assets folder.\n\n" - + e1.getClass().getSimpleName() - + " - " - + e1.getMessage(); - Ctx.msg.show(getStage(), msg, 4); - } - } - } - - private void delete() { - String type = assetTypes.getSelected(); - String dir = getAssetDir(type); - - String name = list.getSelected(); - try { - if (type.equals("backgrounds") || type.equals("images") - || type.equals("atlases")) { - List res = Ctx.project.getResolutions(); - - for (String r : res) { - File file = new File(dir + "/" + r + "/" + name); - - file.delete(); - - // delete pages on atlases - if (type.equals("atlases")) { - File atlasDir = new File(dir + "/" + r); - - File[] files = atlasDir.listFiles(); - - if (files != null) - for (File f : files) { - String destName = f.getName(); - String nameWithoutExt = name.substring(0, - name.lastIndexOf('.')); - String destNameWithoutExt = destName.substring(0, - destName.lastIndexOf('.')); - - if(destNameWithoutExt.length() < nameWithoutExt.length()) - continue; - - String suffix = destNameWithoutExt.substring( nameWithoutExt.length()); - - if(!suffix.isEmpty() && !suffix.matches("[0-9]+")) - continue; - - if (destName.startsWith(nameWithoutExt) - && destName.toLowerCase().endsWith(".png")) - Files.delete(f.toPath()); - } - } - } - } else { - File file = new File(dir + "/" + name); - file.delete(); - } - - addAssets(); - } catch (Exception ex) { - String msg = "Something went wrong while deleting the asset.\n\n" - + ex.getClass().getSimpleName() + " - " + ex.getMessage(); - Ctx.msg.show(getStage(), msg, 4); - ex.printStackTrace(); - } - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/CreateAtlasDialog.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/CreateAtlasDialog.java deleted file mode 100644 index 083b1ee15..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/CreateAtlasDialog.java +++ /dev/null @@ -1,216 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -import com.badlogic.gdx.graphics.Pixmap.Format; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.Texture.TextureFilter; -import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.tools.texturepacker.TexturePacker; -import com.badlogic.gdx.tools.texturepacker.TexturePacker.Settings; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.ui.components.EditDialog; -import com.bladecoder.engineeditor.ui.components.FileInputPanel; -import com.bladecoder.engineeditor.ui.components.InputPanel; -import com.bladecoder.engineeditor.utils.DesktopUtils; -import com.bladecoder.engineeditor.utils.EditorLogger; -import com.bladecoder.engineeditor.utils.ImageUtils; - -public class CreateAtlasDialog extends EditDialog { - - private static final String INFO = "Package all the images in the selected dir to a new atlas"; - - private static final String[] FILTERS = { "Linear", "Nearest", "MipMap", - "MipMapLinearLinear", "MipMapLinearNearest", "MipMapNearestLinear", - "MipMapNearestNearest" }; - - private InputPanel name; - private InputPanel dir; - private InputPanel filterMin; - private InputPanel filterMag; - - - public CreateAtlasDialog(Skin skin) { - super("CREATE ATLAS", skin); - - name = new InputPanel(skin, "Atlas Name", - "The name of the sprite atlas", true); - dir = new FileInputPanel(skin, "Input Image Directory", - "Select the output directory with the images to create the Atlas", - true); - - filterMin = new InputPanel(skin, "Min Filter", - "The filter when the texture is scaled down", FILTERS); - filterMag = new InputPanel(skin, "Mag Filter", - "The filter when the texture is scaled up", FILTERS); - - addInputPanel(name); - addInputPanel(dir); - addInputPanel(filterMin); - addInputPanel(filterMag); - - filterMin.setText(FILTERS[0]); - filterMag.setText(FILTERS[1]); - - setInfo(INFO); - } - - @Override - protected void ok() { - new Thread(new Runnable() { - Stage stage = getStage(); - - @Override - public void run() { - Ctx.msg.show(stage, "Generating atlas...", true); - - String msg = genAtlas(); - - Ctx.msg.hide(); - - if(msg != null) - Ctx.msg.show(stage, msg, 3); - } - }).start(); - } - - @Override - protected boolean validateFields() { - boolean ok = true; - - if (!dir.validateField()) - ok = false; - - if (!name.validateField()) - ok = false; - - return ok; - } - - private String genAtlas() { - File inDir = new File(dir.getText()); - String outdir = Ctx.project.getProjectPath() + Project.ATLASES_PATH; - List res = Ctx.project.getResolutions(); - String name = this.name.getText(); - String fMin = filterMin.getText(); - String fMag = filterMag.getText(); - - Settings settings = new Settings(); - - settings.pot = false; - settings.paddingX = 2; - settings.paddingY = 2; - settings.duplicatePadding = true; - settings.edgePadding = true; - settings.rotation = false; - settings.minWidth = 16; - settings.minWidth = 16; - settings.stripWhitespaceX = false; - settings.stripWhitespaceY = false; - settings.alphaThreshold = 0; - - if (fMin.equals("Linear")) - settings.filterMin = TextureFilter.Linear; - else if (fMin.equals("Nearest")) - settings.filterMin = TextureFilter.Nearest; - else if (fMin.equals("MipMap")) - settings.filterMin = TextureFilter.MipMap; - else if (fMin.equals("MipMapLinearLinear")) - settings.filterMin = TextureFilter.MipMapLinearLinear; - else if (fMin.equals("MipMapLinearNearest")) - settings.filterMin = TextureFilter.MipMapLinearNearest; - else if (fMin.equals("MipMapNearestLinear")) - settings.filterMin = TextureFilter.MipMapNearestLinear; - else if (fMin.equals("MipMapNearestNearest")) - settings.filterMin = TextureFilter.MipMapNearestNearest; - - if (fMag.equals("Linear")) - settings.filterMag = TextureFilter.Linear; - else if (fMag.equals("Nearest")) - settings.filterMag = TextureFilter.Nearest; - else if (fMag.equals("MipMap")) - settings.filterMag = TextureFilter.MipMap; - else if (fMag.equals("MipMapLinearLinear")) - settings.filterMag = TextureFilter.MipMapLinearLinear; - else if (fMag.equals("MipMapLinearNearest")) - settings.filterMag = TextureFilter.MipMapLinearNearest; - else if (fMag.equals("MipMapNearestLinear")) - settings.filterMag = TextureFilter.MipMapNearestLinear; - else if (fMag.equals("MipMapNearestNearest")) - settings.filterMag = TextureFilter.MipMapNearestNearest; - - settings.wrapX = Texture.TextureWrap.ClampToEdge; - settings.wrapY = Texture.TextureWrap.ClampToEdge; - settings.format = Format.RGBA8888; - settings.alias = true; - settings.outputFormat = "png"; - settings.jpegQuality = 0.9f; - settings.ignoreBlankImages = true; - settings.fast = false; - settings.debug = false; - - int wWidth = Ctx.project.getWorld().getWidth(); - - for (String r : res) { - float scale = Float.parseFloat(r); - settings.maxWidth = calcPOT((int)(wWidth * scale * 2f)); - settings.maxHeight = calcPOT((int)(wWidth * scale * 2f)); - - EditorLogger.debug("ATLAS MAXWIDTH: " + settings.maxWidth); - - File inTmpDir = inDir; - - try { - - // Resize images to create atlas for diferent resolutions - if (scale != 1.0f) { - inTmpDir = DesktopUtils.createTempDirectory(); - - ImageUtils.scaleDirFiles(inDir, inTmpDir, scale); - } - - TexturePacker.process(settings, inTmpDir.getAbsolutePath(), - outdir + "/" + r, name + ".atlas"); - - if (scale != 1.0f) { - DesktopUtils.removeDir(inTmpDir.getAbsolutePath()); - } - } catch (IOException e) { - EditorLogger.error(e.getMessage()); - } - } - - return null; - } - - private int calcPOT(int v) { - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - - return v; - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/CreateProjectDialog.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/CreateProjectDialog.java deleted file mode 100644 index 9921e2b63..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/CreateProjectDialog.java +++ /dev/null @@ -1,134 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.io.File; - -import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.ui.components.EditDialog; -import com.bladecoder.engineeditor.ui.components.FileInputPanel; -import com.bladecoder.engineeditor.ui.components.InputPanel; -import com.bladecoder.engineeditor.utils.EditorLogger; - -public class CreateProjectDialog extends EditDialog { - - public static final String INFO = "A project folder with the proper structure will be created in the selected location."; - - private static final String ANDROID_SDK_PROP = "package.SDK"; - - private InputPanel projectName; - private FileInputPanel location; - private FileInputPanel androidSdk; - - public CreateProjectDialog(Skin skin) { - super("CREATE PROJECT", skin); - - setInfo(INFO); - - projectName = new InputPanel(skin, "Project Name", - "Select the name of the project"); - - location = new FileInputPanel(skin, "Location", - "Select the folder location for the project", true); - - androidSdk = new FileInputPanel(skin, "Android SDK", - "Select the Android SDK folder. If empty, the ANDROID_HOME variable will be used", true); - - addInputPanel(projectName); - addInputPanel(location); - addInputPanel(androidSdk); - - String sdkprop = Ctx.project.getConfig().getProperty(ANDROID_SDK_PROP); - - if(sdkprop != null && new File(sdkprop).exists()) { - androidSdk.setText(sdkprop); - } - -// getStage().setKeyboardFocus(projectName.getField()); - } - - @Override - protected void ok() { - try { - Ctx.project.getConfig().setProperty(ANDROID_SDK_PROP, androidSdk.getText()); - Ctx.project.saveProject(); - } catch (Exception ex) { - String msg = "Something went wrong while saving the current project.\n\n" - + ex.getClass().getSimpleName() + " - " + ex.getMessage(); - Ctx.msg.show(getStage(), msg, 2); - } - - new Thread(new Runnable() { - Stage stage = getStage(); - - @Override - public void run() { - createProject(stage); - } - }).start(); - } - - private void createProject(Stage stage) { - Ctx.msg.show(stage, "Creating project...", true); - - try { - Ctx.project.createProject( - location.getText(), - projectName.getText(), - androidSdk.getText()); - - Ctx.project.loadProject(new File(location.getText() + "/" - + projectName.getText())); - - Ctx.msg.show(stage, "Project successfully created", 3); - } catch (Exception e) { - String msg = "Something went wrong while creating project.\n\n" - + e.getClass().getSimpleName() + " - " + e.getMessage(); - Ctx.msg.show(stage, msg, 3); - EditorLogger.error(msg); - return; - } - } - - @Override - protected boolean validateFields() { - boolean isOk = true; - - if (projectName.getText().trim().isEmpty()) { - projectName.setError(true); - isOk = false; - } else - projectName.setError(false); - - if (location.getFile() != null) { - location.setError(false); - } else { - location.setError(true); - isOk = false; - } - - if (System.getenv("ANDROID_HOME") == null && androidSdk.getFile() == null) { - androidSdk.setError(true); - isOk = false; - } else { - androidSdk.setError(false); - } - - return isOk; - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/DialogList.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/DialogList.java deleted file mode 100644 index 3cfc7751d..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/DialogList.java +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.BaseDocument; -import com.bladecoder.engineeditor.ui.components.CellRenderer; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.ElementList; - -public class DialogList extends ElementList { - - private DialogOptionTree options; - - @Override - protected EditElementDialog getEditElementDialogInstance(Element e) { - return new EditDialogDialog(skin, doc, parent, e); - } - - public DialogList(Skin skin) { - super(skin, true); - - options = new DialogOptionTree(skin); - row(); - add(options).expand().fill(); - - list.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - int pos = list.getSelectedIndex(); - - Element v = null; - - if(pos != -1) { - v = list.getItems().get(pos); - options.addOptions(doc, parent, v); - } else { - options.addOptions(doc, parent, null); - } - - toolbar.disableEdit(pos == -1); - } - }); - - list.setCellRenderer(listCellRenderer); - } - - - @Override - public void addElements(BaseDocument doc, Element parent, String tag) { - options.addOptions(doc, null, null); - super.addElements(doc, parent, tag); - } - - - // ------------------------------------------------------------------------- - // ListCellRenderer - // ------------------------------------------------------------------------- - private final CellRenderer listCellRenderer = new CellRenderer() { - - @Override - protected String getCellTitle(Element e) { - return e.getAttribute("id"); - } - - @Override - public TextureRegion getCellImage(Element e) { - return Ctx.assetManager.getIcon("ic_talkto"); - } - - @Override - protected boolean hasSubtitle() { - return false; - } - - @Override - protected boolean hasImage() { - return true; - } - }; - -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/DialogOptionTree.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/DialogOptionTree.java deleted file mode 100644 index 8deb3cbab..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/DialogOptionTree.java +++ /dev/null @@ -1,367 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.NodeList; - -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup; -import com.badlogic.gdx.scenes.scene2d.ui.Tree.Node; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.BaseDocument; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.EditTree; - -public class DialogOptionTree extends EditTree { - - BaseDocument doc; - - Element dialog; - Element actor; - - Element clipboard; - - public DialogOptionTree(Skin skin) { - super(skin); - } - - public void addOptions(BaseDocument doc, Element a, Element dialog) { - this.dialog = dialog; - this.actor = a; - this.doc = doc; - - tree.clearChildren(); - - if(dialog != null) - createTree(dialog); - - toolbar.disableCreate(dialog == null); - -// if(tree.getRootNodes().size > 0) -// tree.getSelection().add(tree.getRootNodes().first()); - } - - @Override - public void create() { - Element parent = dialog; - - if(!tree.getSelection().isEmpty()) { - Node sel = tree.getSelection().getLastSelected(); - - if(sel.getParent() != null) - parent = (Element)sel.getParent().getObject(); - } - - EditDialogOptionDialog o = new EditDialogOptionDialog(skin, doc, - parent, null); - o.show(getStage()); - - o.setListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - Node sel = null; - if(!tree.getSelection().isEmpty()) - sel = tree.getSelection().getLastSelected(); - - Element e = ((EditElementDialog)actor).getElement(); - - Node n = createNode(e); - if(sel != null) { - sel.add(n); - } else { - tree.add(n); - } - } - }); - } - - @Override - public void edit() { - Node sel = tree.getSelection().getLastSelected(); - - Element parent = dialog; - - if(sel != null) { - parent = (Element)sel.getParent().getObject(); - } - - EditDialogOptionDialog o = new EditDialogOptionDialog(skin, doc, - parent, (Element)sel.getObject()); - o.show(getStage()); - } - - @Override - public void delete() { - Node sel = tree.getSelection().getLastSelected(); - Element selElement = (Element)sel.getObject(); - Node parent = sel.getParent(); - Element parentElement = (Element)parent.getObject(); - - doc.deleteElement(selElement); - - clipboard = selElement; - toolbar.disablePaste(false); - -// Node childBefore = parent.getChildBefore(on); -// Node childAfter = parent.getChildAfter(on); - - parent.remove(sel); - - Node nextPath = null; - - // TODO Set NEXT SELECTION - -// if(childBefore != null) { -// nextPath = new TreePath(((DefaultTreeModel) tree.getModel()).getPathToRoot(childBefore)); -// } else { -// nextPath = new TreePath(((DefaultTreeModel) tree.getModel()).getPathToRoot(childAfter)); -// } -// -// tree.expandPath(nextPath); -// tree.setSelectionPath(nextPath); - } - - @Override - public void copy() { - Node sel = tree.getSelection().getLastSelected(); - Element selElement = (Element)sel.getObject(); - - clipboard = (Element) selElement.cloneNode(true); - toolbar.disablePaste(false); - } - - @Override - public void paste() { - Element newElement = (Element) clipboard.cloneNode(true); - Node sel = tree.getSelection().getLastSelected(); - - Element parent = dialog; - - Node parentNode = null; - if(sel != null) { - parentNode = sel.getParent(); - } - - parent.appendChild(newElement); - doc.setModified(newElement); - - - Node newOption = createNode(newElement); - - if(parentNode != null) - parentNode.add(newOption); - else tree.add(newOption); - - // TODO Insert in the selected position -// int idx = -1; -// if(path != null) -// idx = parentOption.getIndex((OptionNode) path.getLastPathComponent()); -// parentOption.insert(newOption, idx + 1); -// -// ((DefaultTreeModel) tree.getModel()).reload(parentOption); -// -// tree.setSelectionPath(new TreePath(((DefaultTreeModel) tree.getModel()).getPathToRoot(newOption))); - } - - @Override - public void upNode() { -// TreePath path = tree.getSelectionPath(); -// OptionNode on = (OptionNode) path.getLastPathComponent(); -// -// Element e = on.getElement(); -// -// Node n = e.getPreviousSibling(); -// -// while(!(n instanceof Element)){ -// n = n.getPreviousSibling(); -// } -// -// Element e2 = (Element)n; -// -// Node parent = e.getParentNode(); -// parent.removeChild(e); -// parent.insertBefore(e, e2); -// doc.setModified(e); -// -//// addOptions(doc, actor, dialog); -// -// OptionNode parentOption = (OptionNode) on.getParent(); -// -// int idx = parentOption.getIndex(on); -// parentOption.insert(on, idx - 1); -// -// ((DefaultTreeModel) tree.getModel()).reload(parentOption); -// -// tree.setSelectionPath(new TreePath(((DefaultTreeModel) tree.getModel()).getPathToRoot(on))); - } - - @Override - public void downNode() { -// TreePath path = tree.getSelectionPath(); -// OptionNode on = (OptionNode) path.getLastPathComponent(); -// -// Element e = on.getElement(); -// Node n = e.getNextSibling(); -// -// while(!(n instanceof Element)){ -// n = n.getNextSibling(); -// } -// -// Element e2 = (Element)n; -// -// Node parent = e.getParentNode(); -// parent.removeChild(e2); -// parent.insertBefore(e2, e); -// doc.setModified(e); -// -// OptionNode parentOption = (OptionNode) on.getParent(); -// -// int idx = parentOption.getIndex(on); -// parentOption.insert(on, idx + 1); -// -// ((DefaultTreeModel) tree.getModel()).reload(parentOption); -// -// tree.setSelectionPath(new TreePath(((DefaultTreeModel) tree.getModel()).getPathToRoot(on))); - } - - @Override - public void leftNode() { -// TreePath path = tree.getSelectionPath(); -// OptionNode on = (OptionNode) path.getLastPathComponent(); -// Element e = on.getElement(); -// -// Node parent = e.getParentNode(); -// parent.removeChild(e); -// -// Node grandpa = parent.getParentNode(); -// grandpa.replaceChild(e, parent); -// grandpa.insertBefore(parent, e); -// doc.setModified(e); -// -// OptionNode parentOption = (OptionNode) on.getParent(); -// -// OptionNode grandpaOption = (OptionNode) parentOption.getParent(); -// -// int idx = grandpaOption.getIndex(parentOption); -// grandpaOption.insert(on, idx + 1); -// -// ((DefaultTreeModel) tree.getModel()).reload(grandpaOption); -// -// tree.setSelectionPath(new TreePath(((DefaultTreeModel) tree.getModel()).getPathToRoot(on))); - } - - @Override - public void rightNode() { -// TreePath path = tree.getSelectionPath(); -// OptionNode on = (OptionNode) path.getLastPathComponent(); -// Element e = on.getElement(); -// -// Node n = e.getPreviousSibling(); -// -// while(!(n instanceof Element)){ -// n = n.getPreviousSibling(); -// } -// -// Element e2 = (Element)n; -// -// Node parent = e.getParentNode(); -// parent.removeChild(e); -// e2.appendChild(e); -// -// doc.setModified(e); -// -// OptionNode parentOption = (OptionNode)((OptionNode) on.getParent()).getChildBefore(on); -// -// OptionNode grandpaOption = (OptionNode) on.getParent(); -// -// parentOption.add(on); -// -// ((DefaultTreeModel) tree.getModel()).reload(grandpaOption); -// -// tree.setSelectionPath(new TreePath(((DefaultTreeModel) tree.getModel()).getPathToRoot(on))); - } - - - private void createTree(Element dialog) { - NodeList childs = dialog.getChildNodes(); - int n = childs.getLength(); - for (int i = 0; i < n; i++) { - if (childs.item(i) instanceof Element) - tree.add(createNode((Element) childs.item(i))); - } - } - - private Node createNode(Element e) { - Label textLbl = new Label(null, skin); - Label infoLbl = new Label(null, skin); - - String text = e.getAttribute("text"); - - textLbl.setText(Ctx.project.getSelectedChapter().getTranslation(text)); - - StringBuilder sb = new StringBuilder(); - - // if(!actor.isEmpty()) - // sb.append(" actor '").append(actor).append("'"); - - NamedNodeMap attr = e.getAttributes(); - - String response = e.getAttribute("response_text"); - - if (!response.isEmpty()) - sb.append("R: ") - .append(Ctx.project.getSelectedChapter().getTranslation(response)).append(' '); - - for (int i = 0; i < attr.getLength(); i++) { - org.w3c.dom.Node n = attr.item(i); - String name = n.getNodeName(); - - if (name.equals("text") || name.equals("response_text")) - continue; - - String v = n.getNodeValue(); - sb.append(name).append(':') - .append(Ctx.project.getSelectedChapter().getTranslation(v)).append(' '); - } - - infoLbl.setText(sb.toString()); - - VerticalGroup vg = new VerticalGroup(); - vg.left(); - vg.addActor(textLbl); - vg.addActor(infoLbl); - - Node node = new Node(vg); - node.setObject(e); - - NodeList childs = e.getChildNodes(); - int n = childs.getLength(); - - for (int i = 0; i < n; i++) { - if (childs.item(i) instanceof Element) { - node.add(createNode((Element) childs.item(i))); - } - } - - - return node; - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditActionDialog.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditActionDialog.java deleted file mode 100644 index e5f76740b..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditActionDialog.java +++ /dev/null @@ -1,175 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.util.Arrays; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.TextField; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.scenes.scene2d.utils.FocusListener; -import com.bladecoder.engine.actions.Action; -import com.bladecoder.engine.actions.ActionFactory; -import com.bladecoder.engine.actions.Param; -import com.bladecoder.engine.actions.Param.Type; -import com.bladecoder.engineeditor.model.BaseDocument; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.InputPanel; - -public class EditActionDialog extends EditElementDialog { - private static final String CUSTOM_ACTION_STR = "CUSTOM ACTION"; - - private static final String CUSTOM_INFO="Custom action definition"; - - private InputPanel actionPanel; - private InputPanel actorPanel; - private InputPanel classPanel; - - private InputPanel parameters[]; - - @SuppressWarnings("unchecked") - public EditActionDialog(Skin skin, BaseDocument doc, Element parent, Element e) { - super(skin); - - String[] actions = ActionFactory.getActionList(); - Arrays.sort(actions); - String[] actions2 = new String[actions.length + 1]; - System.arraycopy(actions, 0, actions2, 0, actions.length); - actions2[actions2.length - 1] = CUSTOM_ACTION_STR; - - actionPanel = new InputPanel(skin, "Action", - "Select the action to create.", actions2); - - actorPanel = new InputPanel(skin, "Target BaseActor", - "Select the target actor id. Default is current actor.",Type.ACTOR,false); - classPanel = new InputPanel(skin, "Class", - "Select the class for the custom action.", true); - - setAction(); - - ((SelectBox) actionPanel.getField()) - .addListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, Actor actor) { - setAction(); - } - }); - - ((TextField) classPanel.getField()).addListener(new FocusListener() { - @Override - public void keyboardFocusChanged (FocusEvent event, Actor actor, boolean focused) { - if(!event.isFocused()) - setAction(); - } - }); - - if(e != null) { - actorPanel.setText(e.getAttribute("actor")); - classPanel.setText(e.getAttribute("class")); - - if(!e.getAttribute("action_name").isEmpty()) { - actionPanel.setText(e.getAttribute("action_name")); - } - - if(!e.getAttribute("class").isEmpty()) { - actionPanel.setText(CUSTOM_ACTION_STR); - } - - setAction(); - } - - init(parameters, getAttrs(), doc, parent, "action", e); - } - - private String[] getAttrs() { - String inputs[] = new String[parameters.length]; - - for (int j = 0; j < parameters.length ; j++) { - InputPanel i= parameters[j]; - inputs[j] = i.getTitle(); - } - - return inputs; - } - - private void setAction() { - String id = actionPanel.getText(); - - getCenterPanel().clear(); - addInputPanel(actionPanel); - addInputPanel(actorPanel); - - Action ac = null; - - if (id.equals(CUSTOM_ACTION_STR)) { - addInputPanel(classPanel); - if(!classPanel.getText().trim().isEmpty()) - ac = ActionFactory.createByClass(classPanel.getText(), null); - } else { - ac = ActionFactory.create(id, null); - } - - if (ac != null) { - setInfo(ac.getInfo()); - - Param[] params = ac.getParams(); - - parameters = new InputPanel[params.length]; - - for (int i = 0; i < params.length; i++) { - parameters[i] = new InputPanel(getSkin(),params[i].name, params[i].desc, - params[i].type, params[i].mandatory, params[i].defaultValue, params[i].options); - addInputPanel(parameters[i]); - } - - i = parameters; - a = getAttrs(); - } else { - setInfo(CUSTOM_INFO); - i = new InputPanel[0]; - a = new String[0]; - } - - } - - @Override - protected void fill() { - String actor = actorPanel.getText().trim(); - - // Remove previous params - while(e.getAttributes().getLength() > 0) { - e.removeAttribute(e.getAttributes().item(0).getNodeName()); - } - - if (!actor.isEmpty()) - e.setAttribute("actor", actor); - - String id = actionPanel.getText(); - - if (id.equals(CUSTOM_ACTION_STR)) { - e.setAttribute("class", classPanel.getText()); - } else { - e.setAttribute("action_name", id); - } - - super.fill(); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditActorDialog.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditActorDialog.java deleted file mode 100644 index 87ddacb0f..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditActorDialog.java +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.bladecoder.engine.actions.Param; -import com.bladecoder.engineeditor.model.BaseDocument; -import com.bladecoder.engineeditor.model.ChapterDocument; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.InputPanel; - -public class EditActorDialog extends EditElementDialog { - - public static final String TYPES_INFO[] = { - "No renderer actor, only define an interactive area", - "Atlas actor allows 2d image and animations", - "3d actors allow 3d models and animations", - "Spine actors allow Spine 2d skeletal animations", - "Image actors show image files" - }; - - private InputPanel[] inputs = new InputPanel[12]; - InputPanel typePanel; - - String attrs[] = { "type", "id", "layer", "desc", "state", "interaction", "visible", - "walking_speed", "depth_type", "sprite_size", "camera", "fov" }; - - @SuppressWarnings("unchecked") - public EditActorDialog(Skin skin, BaseDocument doc, Element parent, - Element e) { - super(skin); - - inputs[0] = new InputPanel(skin, "BaseActor Type", - "Actors can be from different types", - ChapterDocument.ACTOR_TYPES); - - inputs[1] = new InputPanel(skin, "BaseActor ID", - "IDs can not contain '.' or '_' characters.", true); - - inputs[2] = new InputPanel(skin, "BaseActor Layer", - "The layer for drawing order", - ChapterDocument.ACTOR_LAYERS); - - inputs[3] = new InputPanel(skin, "Description", - "The text showed when the cursor is over the actor."); - inputs[4] = new InputPanel( - skin, - "State", - "Initial state of the actor. Actors can be in differentes states during the game."); - inputs[5] = new InputPanel(skin, "Interaction", - "True when the actor reacts to the user input.", - Param.Type.BOOLEAN, false); - inputs[6] = new InputPanel(skin, "Visible", "The actor visibility.", - Param.Type.BOOLEAN, false); - inputs[7] = new InputPanel(skin, "Walking Speed", - "The walking speed in pix/sec. Default 700.", Param.Type.FLOAT, - false); - inputs[8] = new InputPanel(skin, "Depth Type", - "Scene fake depth for scaling", new String[] { "none", - "vector"}); - inputs[9] = new InputPanel(skin, "Sprite Dimensions", - "The size of the 3d sprite", Param.Type.DIMENSION, true); - inputs[10] = new InputPanel(skin, "Camera Name", - "The name of the camera in the model", Param.Type.STRING, true, - "Camera", null); - inputs[11] = new InputPanel(skin, "Camera FOV", - "The camera field of view", Param.Type.FLOAT, true, "49.3", - null); - - setInfo(TYPES_INFO[0]); - - typePanel = inputs[0]; - - ((SelectBox) typePanel.getField()) - .addListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, Actor actor) { - typeChanged(); - } - }); - - init(inputs, attrs, doc, parent, "actor", e); - - typeChanged(); - - } - - private void typeChanged() { - int i = typePanel.getSelectedIndex(); - - setInfo(TYPES_INFO[i]); - - setVisible(inputs[9],false); - setVisible(inputs[10],false); - setVisible(inputs[11],false); - - if (ChapterDocument.ACTOR_TYPES[i] - .equals(ChapterDocument.SPRITE3D_ACTOR_TYPE)) { - setVisible(inputs[9],true); - setVisible(inputs[10],true); - setVisible(inputs[11],true); - } - } - - @Override - protected void fill() { - int i = typePanel.getSelectedIndex(); - if (((ChapterDocument)doc).getBBox(e) == null && ChapterDocument.ACTOR_TYPES[i] - .equals(ChapterDocument.NO_RENDERER_ACTOR_TYPE)) { - ((ChapterDocument) doc).setBbox(e, null); - } - - if(((ChapterDocument)doc).getPos(e) == null) - ((ChapterDocument) doc).setPos(e, new Vector2(0, 0)); - - super.fill(); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditDialogOptionDialog.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditDialogOptionDialog.java deleted file mode 100644 index 45946bc2c..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditDialogOptionDialog.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.bladecoder.engine.actions.Param; -import com.bladecoder.engineeditor.model.BaseDocument; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.InputPanel; - -public class EditDialogOptionDialog extends EditElementDialog { - - private InputPanel[] inputs; - - String attrs[] = { "text", "response_text", "verb", "next", "visible" }; - - public EditDialogOptionDialog(Skin skin, BaseDocument doc, - Element parent, Element e) { - super(skin); - - inputs = new InputPanel[5]; - - inputs[0] = new InputPanel(skin, "Text", "The sentence of the dialog to say by the player"); - inputs[1] = new InputPanel(skin, "Response Text", "The response by the character"); - inputs[2] = new InputPanel(skin, "Verb", "The verb to execute when choosing this option"); - inputs[3] = new InputPanel(skin, "Next Option", - "The next option to show when this option is selected"); - inputs[4] = new InputPanel(skin, "Visible", "The visibility", Param.Type.BOOLEAN, false); - - setInfo("A dialog is composed of an option tree. Each option is a dialog sentence that the user can choose to say"); - - init(inputs, attrs, doc, parent, "option", e); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditSceneDialog.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditSceneDialog.java deleted file mode 100644 index 2c6c2149d..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditSceneDialog.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.io.File; -import java.io.FilenameFilter; -import java.util.ArrayList; -import java.util.Arrays; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Image; -import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; -import com.badlogic.gdx.utils.Scaling; -import com.bladecoder.engine.actions.Param; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.BaseDocument; -import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.InputPanel; - -public class EditSceneDialog extends EditElementDialog { - - public static final String INFO = "An adventure is composed of many scenes (screens).\n" + - "Inside a scene there are actors and a 'player'.\nThe player/user can interact with the actors throught 'verbs'."; - - private String bgList[] = getBgList(); - private String musicList[] = getMusicList(); - - private InputPanel[] inputs = new InputPanel[8]; - - private Image bgImage; - - - String attrs[] = {"id", "background", "lightmap", "depth_vector", "music", "loop_music", "initial_music_delay", "repeat_music_delay"}; - - @SuppressWarnings("unchecked") - public EditSceneDialog(Skin skin, BaseDocument doc, Element parent, - Element e) { - - super(skin); - - inputs[0] = new InputPanel(skin, "Scene ID", - "The ID is mandatory for scenes. \nIDs can not contain '.' or '_' characters."); - inputs[1] = new InputPanel(skin, "Background", - "The background for the scene", bgList); - inputs[2] = new InputPanel(skin, "Lightmap", - "The lightmap for the scene", bgList); - inputs[3] = new InputPanel(skin, "Depth Vector", - "X: the actor scale when y=0, Y: the actor scale when y=scene height .", Param.Type.VECTOR2, false); - inputs[4] = new InputPanel(skin, "Music Filename", - "The music for the scene", musicList); - inputs[5] = new InputPanel(skin, "Loop Music", - "If the music is playing in looping", Param.Type.BOOLEAN, false); - inputs[6] = new InputPanel(skin, "Initial music delay", - "The time to wait before playing", Param.Type.FLOAT, false); - inputs[7] = new InputPanel(skin, "Repeat music delay", - "The time to wait before repetitions", Param.Type.FLOAT, false); - - bgImage = new Image(); - bgImage.setScaling(Scaling.fit); - setInfo(INFO); - - inputs[0].setMandatory(true); - - init(inputs, attrs, doc, parent, "scene", e); - - ((SelectBox) inputs[1].getField()).addListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, Actor actor) { - String bg = inputs[1].getText(); - - if(!bg.isEmpty()) - bgImage.setDrawable(new TextureRegionDrawable(Ctx.project.getBgIcon(bg))); - - setInfoWidget(bgImage); - } - }); - } - - private String[] getBgList() { - String bgPath = Ctx.project.getProjectPath() + Project.BACKGROUNDS_PATH + "/" - + Ctx.project.getResDir(); - - File f = new File(bgPath); - - String bgs[] = f.list(new FilenameFilter() { - - @Override - public boolean accept(File arg0, String arg1) { - if ((arg1.matches("_[1-9]\\."))) - return false; - - return true; - } - }); - - Arrays.sort(bgs); - - ArrayList l = new ArrayList(Arrays.asList(bgs)); - l.add(0,""); - - return l.toArray(new String[bgs.length + 1]); - } - - private String[] getMusicList() { - String path = Ctx.project.getProjectPath() + Project.MUSIC_PATH; - - File f = new File(path); - - String musicFiles[] = f.list(new FilenameFilter() { - - @Override - public boolean accept(File arg0, String arg1) { - if (arg1.endsWith(".ogg") || arg1.endsWith(".mp3")) - return true; - - return false; - } - }); - - Arrays.sort(musicFiles); - - String musicFiles2[] = new String[musicFiles.length + 1]; - musicFiles2[0] = ""; - - for(int i=0; i < musicFiles.length; i++) - musicFiles2[i + 1] = musicFiles[i]; - - return musicFiles2; - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditSoundDialog.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditSoundDialog.java deleted file mode 100644 index 9ae9b3bb6..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditSoundDialog.java +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.io.File; -import java.io.FilenameFilter; -import java.util.Arrays; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.bladecoder.engine.actions.Param; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.BaseDocument; -import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.InputPanel; - -public class EditSoundDialog extends EditElementDialog { - - private InputPanel[] inputs; - - - String attrs[] = { "id", "filename", "loop", "volume"}; - - public EditSoundDialog(Skin skin, BaseDocument doc, Element parent, Element e) { - super(skin); - - inputs = new InputPanel [4]; - inputs[0] = new InputPanel(skin, "Sound ID", "The id of the sound"); - inputs[1] = new InputPanel(skin, "Filename", "Filename of the sound", getSoundList()); - inputs[2] = new InputPanel(skin, "Loop", "True if the sound is looping", Param.Type.BOOLEAN, false); - inputs[3] = new InputPanel(skin, "Volume", "Select the volume"); - - inputs[0].setMandatory(true); - inputs[1].setMandatory(true); - - setInfo("Actors and scenes can have a list of sounds that can be associated to Sprites or played with the 'sound' action"); - - init(inputs, attrs, doc, parent, "sound", e); - } - - private String[] getSoundList() { - String path = Ctx.project.getProjectPath() + Project.SOUND_PATH; - - File f = new File(path); - - String soundFiles[] = f.list(new FilenameFilter() { - - @Override - public boolean accept(File arg0, String arg1) { - if (arg1.endsWith(".ogg") || arg1.endsWith(".wav") || arg1.endsWith(".mp3")) - return true; - - return false; - } - }); - - Arrays.sort(soundFiles); - - return soundFiles; - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditSpriteDialog.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditSpriteDialog.java deleted file mode 100644 index b609cbd5d..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditSpriteDialog.java +++ /dev/null @@ -1,285 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.io.File; -import java.io.FilenameFilter; -import java.util.Arrays; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.TextField; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.ChangeEvent; -import com.bladecoder.engine.actions.Param; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.BaseDocument; -import com.bladecoder.engineeditor.model.ChapterDocument; -import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.scneditor.SpriteWidget; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.InputPanel; -import com.bladecoder.engineeditor.utils.EditorLogger; - -public class EditSpriteDialog extends EditElementDialog { - public static final String INFO = "Define sprites and frame animations"; - - private InputPanel[] inputs = new InputPanel[11]; - InputPanel typePanel; - - String attrs[] = { "source", "id", "animation_type", "speed", "delay", - "count", "inD", "outD", "sound", "preload", "disposed_when_played" }; - - SpriteWidget spriteWidget = new SpriteWidget(this); - - @SuppressWarnings("unchecked") - public EditSpriteDialog(Skin skin, BaseDocument doc, Element p, Element e) { - super(skin); - - setInfo(INFO); - - inputs[0] = new InputPanel(skin, "Source", - "Select the source where the sprite or animation is defined", - new String[0]); - inputs[1] = new InputPanel(skin, "ID", - "Select the id of the animation", new String[0]); - inputs[2] = new InputPanel(skin, "Animation type", - "Select the type of the animation", - ChapterDocument.ANIMATION_TYPES); - inputs[3] = new InputPanel(skin, "Speed", - "Select the speed of the animation in secods", - Param.Type.FLOAT, true, "1.0"); - inputs[4] = new InputPanel(skin, "Delay", - "Select the delay between repeats in seconds", - Param.Type.FLOAT, false); - inputs[5] = new InputPanel(skin, "Count", "Select the repeat times", - Param.Type.INTEGER, false); - inputs[6] = new InputPanel( - skin, - "In Dist", - "Select the distance in pixels to add to the actor position when the sprite is displayed", - Param.Type.VECTOR2, false); - inputs[7] = new InputPanel( - skin, - "Out Dist", - "Select the distance in pixels to add to the actor position when the sprite is changed", - Param.Type.VECTOR2, false); - inputs[8] = new InputPanel(skin, "Sound", - "Select the sound ID that will be play when displayed"); - inputs[9] = new InputPanel(skin, "Preload", - "Preload the animation when the scene is loaded", - Param.Type.BOOLEAN, true, "true", null); - inputs[10] = new InputPanel(skin, "Dispose When Played", - "Dispose de animation when the animation is played", - Param.Type.BOOLEAN, true, "false", null); - - typePanel = inputs[2]; - - ((SelectBox) typePanel.getField()) - .addListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, Actor actor) { - String type = typePanel.getText(); - - if (type.equals("repeat") || type.equals("yoyo")) { - setVisible(inputs[4],true); - setVisible(inputs[5],true); - } else { - setVisible(inputs[4],false); - setVisible(inputs[5],false); - } - } - }); - - ((SelectBox) inputs[0].getField()) - .addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - EditorLogger.debug("CreateEditFADialog.setSource():" - + inputs[0].getText()); - - spriteWidget.setSource(parent.getAttribute("type"), - inputs[0].getText()); - - fillAnimations(); - } - }); - - ((SelectBox) inputs[1].getField()) - .addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - setSprite(); - } - }); - - ((TextField) inputs[3].getField()).addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - setSprite(); - } - }); - - setInfoWidget(spriteWidget); - init(inputs, attrs, doc, p, "frame_animation", e); - - setVisible(inputs[4],false); - setVisible(inputs[5],false); - - addSources(); - if(e != null) { - inputs[0].setText(e.getAttribute(attrs[0])); - } - - if (inputs[0].getText() != null && !inputs[0].getText().isEmpty()) { - spriteWidget.setSource(parent.getAttribute("type"), - inputs[0].getText()); - - fillAnimations(); - - if(e != null) { - inputs[1].setText(e.getAttribute(attrs[1])); - } - } - } - - private void setSprite() { - String id = inputs[1].getText(); - String type = typePanel.getText(); - String speed = inputs[3].getText(); - - @SuppressWarnings("unchecked") - SelectBox cb = (SelectBox) inputs[1].getField(); - - if (e != null || cb.getSelectedIndex() != 0) - spriteWidget.setFrameAnimation(id, speed, type); - } - - private void fillAnimations() { - EditorLogger.debug("CreateEditFADialog.fillAnimations()"); - - @SuppressWarnings("unchecked") - SelectBox cb = (SelectBox) inputs[1].getField(); - cb.getItems().clear(); - - // When creating, give option to add all elements - if (e == null) - cb.getItems().add(""); - - String ids[] = spriteWidget.getAnimations(); - for (String s : ids) - cb.getItems().add(s); - - cb.getList().setItems(cb.getItems()); - - cb.invalidateHierarchy(); - - setSprite(); - } - - String ext; - - private void addSources() { - @SuppressWarnings("unchecked") - SelectBox cb = (SelectBox) inputs[0].getField(); - String[] src = getSources(); - cb.getItems().clear(); - - for (String s : src) - cb.getItems().add(s); - - cb.getList().setItems(cb.getItems()); - if (cb.getItems().size > 0) - cb.setSelectedIndex(0); - cb.invalidateHierarchy(); - } - - private String[] getSources() { - String path = null; - String type = parent.getAttribute("type"); - - if (type.equals(ChapterDocument.ATLAS_ACTOR_TYPE)) { - path = Ctx.project.getProjectPath() + Project.ATLASES_PATH + "/" - + Ctx.project.getResDir(); - ext = ".atlas"; - } else if (type.equals(ChapterDocument.SPRITE3D_ACTOR_TYPE)) { - path = Ctx.project.getProjectPath() + Project.SPRITE3D_PATH; - ext = ".g3db"; - } else if (type.equals(ChapterDocument.SPINE_ACTOR_TYPE)) { - path = Ctx.project.getProjectPath() + Project.SPINE_PATH; - ext = ".skel"; - } else if (type.equals(ChapterDocument.IMAGE_ACTOR_TYPE)) { - path = Ctx.project.getProjectPath() + Project.IMAGE_PATH + "/" - + Ctx.project.getResDir(); - ext = ""; - } - - File f = new File(path); - - String sources[] = f.list(new FilenameFilter() { - - @Override - public boolean accept(File arg0, String arg1) { - if (arg1.endsWith(ext)) - return true; - - return false; - } - }); - - if (sources != null) { - Arrays.sort(sources); - - for (int i = 0; i < sources.length; i++) - sources[i] = sources[i].substring(0, - sources[i].length() - ext.length()); - } else { - sources = new String[0]; - } - - return sources; - } - - /** - * Override to append all animations if selected. - */ - @Override - protected void ok() { - @SuppressWarnings("unchecked") - SelectBox cb = (SelectBox) inputs[1].getField(); - - if (e == null && cb.getSelectedIndex() == 0) { - for (int i = 1; i < cb.getItems().size; i++) { - cb.setSelectedIndex(i); - create(); - fill(); -// doc.setId(e, cb.getItems().get(i)); - - if (listener != null) - listener.changed(new ChangeEvent(), this); - } - - - } else { - super.ok(); - } - } - -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditVerbDialog.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditVerbDialog.java deleted file mode 100644 index 6111c1ada..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditVerbDialog.java +++ /dev/null @@ -1,147 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.bladecoder.engineeditor.model.BaseDocument; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.InputPanel; - -public class EditVerbDialog extends EditElementDialog { - public static final String VERBS[] = { "lookat", "pickup", "talkto", "use", "leave", "custom" }; - - public static final String SCENE_VERBS[] = { "init", "test", "custom" }; - - public static final String VERBS_INFO[] = { - "Called when the user clicks\n in the 'lookat' icon\n over a object in scene", - "Called when the user clicks\n in the 'pickup' icon\n over a object in scene", - "Called when the user clicks\n in the 'talkto' icon\n over a character in scene", - "Called when the user drags and drops\n an inventory object over\n an object in scene or in inventory", - "Called when the user clicks\n in an exit zone in scene", - "User defined verbs can be called\n from dialogs or inside actions using \nthe 'run_verb' action" }; - - public static final String SCENE_VERBS_INFO[] = { - "Called every time\n that the scene is loaded", - "Called every time\n that the scene is loaded in test mode.\n'test' verb is called before the 'init' verb", - "User defined verbs can be called\n from dialogs or inside actions using \nthe 'run_verb' action" }; - - - private InputPanel[] inputs; - - - String attrs[] = { "id", "state", "target"}; - - @SuppressWarnings("unchecked") - public EditVerbDialog(Skin skin, BaseDocument doc, Element parentElement, Element e) { - super(skin); - - inputs = new InputPanel [4]; - inputs[0] = new InputPanel(skin, "Verb ID", "Select the verb to create.", parentElement.getTagName().equals("scene")?SCENE_VERBS:VERBS); - inputs[1] = new InputPanel(skin, "State", "Select the state."); - inputs[2] = new InputPanel(skin, "Target BaseActor", "Select the target actor id for the 'use' verb"); - inputs[3] = new InputPanel(skin, "Custom Verb Name", "Select the Custom verb id"); - - if(parentElement.getTagName().equals("scene")) - setInfo(SCENE_VERBS_INFO[0]); - else - setInfo(VERBS_INFO[0]); - - ((SelectBox) inputs[0].getField()).addListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, Actor actor) { - String id = (String) inputs[0].getText(); - int i = inputs[0].getSelectedIndex(); - - if(parent.getTagName().equals("scene")) - setInfo(SCENE_VERBS_INFO[i]); - else - setInfo(VERBS_INFO[i]); - - if (id.equals("use")) - setVisible(inputs[2],true); - else - setVisible(inputs[2],false); - - if (id.equals("custom")) - setVisible(inputs[3],true); - else - setVisible(inputs[3],false); - } - - }); - - init(inputs, attrs, doc, parentElement, "verb", e); - - setVisible(inputs[2],false); - setVisible(inputs[3],false); - - if(e != null) { - boolean isCustom = true; - String id = e.getAttribute("id"); - - String verbs[] = parent.getTagName().equals("scene")?SCENE_VERBS:VERBS; - - for(String v:verbs) { - if(v.equals(id) && !id.equals("custom")) { - isCustom = false; - break; - } - } - - if(isCustom) { - inputs[0].setText("custom"); - setVisible(inputs[3],true); - inputs[3].setText(id); - } - } - } - - @Override - protected boolean validateFields() { - boolean isOk = true; - - if(inputs[0].getText().equals("custom") && inputs[3].getText().isEmpty()) { - inputs[3].setError(true); - isOk = false; - } else { - inputs[3].setError(false); - } - - return isOk; - } - - @Override - protected void fill() { - for (int j = 0; j < a.length; j++) { - InputPanel input = i[j]; - - if (!input.getText().isEmpty()) { - e.setAttribute(a[j], input.getText()); - } else { - e.removeAttribute(a[j]); - } - } - - if(e.getAttribute("id").equals("custom")) - e.setAttribute("id", inputs[3].getText()); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/PackageDialog.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/PackageDialog.java deleted file mode 100644 index 54c4116ed..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/PackageDialog.java +++ /dev/null @@ -1,396 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; - -import org.apache.commons.io.FileUtils; - -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogicgames.packr.Packr; -import com.badlogicgames.packr.Packr.Platform; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.ui.components.EditDialog; -import com.bladecoder.engineeditor.ui.components.FileInputPanel; -import com.bladecoder.engineeditor.ui.components.InputPanel; -import com.bladecoder.engineeditor.utils.RunProccess; - -public class PackageDialog extends EditDialog { - private static final String ARCH_PROP = "package.arch"; - private static final String DIR_PROP = "package.dir"; - - private static final String DESKTOP_LAUNCHER = "org/bladecoder/engine/desktop/DesktopLauncher"; - - private static final String INFO = "Package the Adventure for distribution"; - private static final String[] ARCHS = { "desktop", "android", "ios", "html" }; - private static final String[] TYPES = { "Bundle JRE", "Runnable jar" }; - private static final String[] OSS = { "all", "windows", "linux64", "linux32", "macOSX" }; - - private InputPanel arch; - private InputPanel dir; - private InputPanel type; - private InputPanel os; - private InputPanel linux64JRE; - private InputPanel linux32JRE; - private InputPanel winJRE; - private InputPanel osxJRE; - private InputPanel version; - private InputPanel icon; - private InputPanel androidSDK; - private InputPanel androidKeyStore; - private InputPanel androidKeyAlias; - private InputPanel androidKeyStorePassword; - private InputPanel androidKeyAliasPassword; - - private InputPanel[] options = new InputPanel[11]; - - @SuppressWarnings("unchecked") - public PackageDialog(Skin skin) { - super("PACKAGE ADVENTURE", skin); - - arch = new InputPanel(skin, "Architecture", "Select the target Architecture for the game", ARCHS); - dir = new FileInputPanel(skin, "Output Directory", "Select the output directory to put the package", true); - type = new InputPanel(skin, "Type", "Select the type of the package", TYPES); - os = new InputPanel(skin, "OS", "Select the OS of the package", OSS); - linux64JRE = new FileInputPanel(skin, "JRE.Linux64", "Select the 64 bits Linux JRE Location to bundle. Must be a ZIP file", false); - linux32JRE = new FileInputPanel(skin, "JRE.Linux32", "Select the 32 bits Linux JRE Location to bundle. Must be a ZIP file", false); - winJRE = new FileInputPanel(skin, "JRE.Windows", "Select the Windows JRE Location to bundle. Must be a ZIP file", false); - osxJRE = new FileInputPanel(skin, "JRE.OSX", "Select the OSX JRE Location to bundle. Must be a ZIP file", false); - version = new InputPanel(skin, "Version", "Select the version of the package"); - icon = new FileInputPanel(skin, "Icon", "The icon for the .exe file", false); - androidSDK = new FileInputPanel(skin, "SDK", "Select the Android SDK Location", true); - androidKeyStore = new FileInputPanel(skin, "KeyStore", "Select the Key Store Location", false); - androidKeyAlias = new InputPanel(skin, "KeyAlias", "Select the Key Alias Location"); - androidKeyStorePassword = new InputPanel(skin, "KeyStorePasswd", "Key Store Password", false); - androidKeyAliasPassword = new InputPanel(skin, "KeyAliasPasswd", "Key Alias Password", false); - - options[0] = type; - options[1] = os; - options[2] = linux64JRE; - options[3] = linux32JRE; - options[4] = winJRE; - options[5] = osxJRE; - options[6] = version; - options[7] = icon; - options[8] = androidSDK; - options[9] = androidKeyStore; - options[10] = androidKeyAlias; - - addInputPanel(arch); - addInputPanel(dir); - - for (InputPanel i : options) { - addInputPanel(i); - i.setMandatory(true); - } - - addInputPanel(androidKeyStorePassword); - addInputPanel(androidKeyAliasPassword); - - dir.setMandatory(true); - - arch.setText(Ctx.project.getConfig().getProperty(ARCH_PROP, ARCHS[0])); - dir.setText(Ctx.project.getConfig().getProperty(DIR_PROP, "")); - - for (InputPanel i : options) { - String prop = Ctx.project.getConfig().getProperty("package." + i.getTitle()); - - if (prop != null && !prop.isEmpty()) - i.setText(prop); - } - - - setInfo(INFO); - - ((SelectBox) (arch.getField())).addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - archChanged(); - } - }); - - ((SelectBox) (type.getField())).addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - typeChanged(); - } - }); - - ((SelectBox) (os.getField())).addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - osChanged(); - } - }); - - archChanged(); - } - - @Override - protected void ok() { - - new Thread(new Runnable() { - Stage stage = getStage(); - - @Override - public void run() { - Ctx.msg.show(stage, "Generating package...",true); - String msg; - - try { - msg = packageAdv(); - } catch (Exception e) { - msg = "Error Generating package\n\n" + e.getMessage(); - } - - Ctx.project.getConfig().setProperty(ARCH_PROP, arch.getText()); - Ctx.project.getConfig().setProperty(DIR_PROP, dir.getText()); - - for (InputPanel i : options) { - Ctx.project.getConfig().setProperty("package." + i.getTitle(), i.getText()); - } - - Ctx.msg.hide(); - - if(msg != null) - Ctx.msg.show(stage, msg, 3); - } - }).start(); - - } - - private String packageAdv() throws IOException { - String msg = "Package generated SUCCESSFULLY"; - - String projectName = Ctx.project.getProjectDir().getName(); - String versionParam = "-Ppassed_version=" + version.getText() + " "; - - if (arch.getText().equals("desktop")) { - String jar = Ctx.project.getProjectDir().getAbsolutePath() + - "/desktop/build/libs/" + projectName + "-desktop-" + version.getText() + ".jar"; - - msg = genDesktopJar(projectName, versionParam, jar); - - if (type.getText().equals(TYPES[0])) { // RUNNABLE JAR - if (os.getText().equals("linux64")) { - packr(Platform.linux64, linux64JRE.getText(), projectName, jar, DESKTOP_LAUNCHER, dir.getText()); - } else if (os.getText().equals("linux32")) { - packr(Platform.linux32, linux32JRE.getText(), projectName, jar, DESKTOP_LAUNCHER, dir.getText()); - } else if (os.getText().equals("windows")) { - packr(Platform.windows, winJRE.getText(), projectName, jar, DESKTOP_LAUNCHER, dir.getText()); - } else if (os.getText().equals("macOSX")) { - packr(Platform.mac, osxJRE.getText(), projectName, jar, DESKTOP_LAUNCHER, dir.getText()); - } else if (os.getText().equals("all")) { - packr(Platform.linux64, linux64JRE.getText(), projectName, jar, DESKTOP_LAUNCHER, dir.getText()); - packr(Platform.linux32, linux32JRE.getText(), projectName, jar, DESKTOP_LAUNCHER, dir.getText()); - packr(Platform.windows, winJRE.getText(), projectName, jar, DESKTOP_LAUNCHER, dir.getText()); - packr(Platform.mac, osxJRE.getText(), projectName, jar, DESKTOP_LAUNCHER, dir.getText()); - } - } - } else if (arch.getText().equals("android")) { - String params = versionParam + - "-Pkeystore=" + androidKeyStore.getText() + " " + - "-PstorePassword=" + androidKeyStorePassword.getText() + " " + - "-Palias=" + androidKeyAlias.getText() + " " + - "-PkeyPassword=" + androidKeyAliasPassword.getText() + " "; - - if(RunProccess.runGradle(Ctx.project.getProjectDir(), params + "android:assembleRelease")) { - FileUtils.copyDirectory(new File(Ctx.project.getProjectDir().getAbsolutePath() + - "/android/build/apk/") - , new File(dir.getText())); - } else { - msg = "Error Generating package" ; - } - } else if (arch.getText().equals("ios")) { - if(RunProccess.runGradle(Ctx.project.getProjectDir(), "ios:createIPA")) { - FileUtils.copyDirectory(new File(Ctx.project.getProjectDir().getAbsolutePath() + - "/ios/build/robovm/") - , new File(dir.getText())); - } else { - msg = "Error Generating package" ; - } - } else if (arch.getText().equals("html")) { - if(RunProccess.runGradle(Ctx.project.getProjectDir(), "html:dist")) { - FileUtils.copyDirectory(new File(Ctx.project.getProjectDir().getAbsolutePath() + - "/html/build/dist") - , new File(dir.getText())); - } else { - msg = "Error Generating package" ; - } - } - - return msg; - } - - private void archChanged() { - for (InputPanel ip : options) { - setVisible(ip, false); - } - - setVisible(androidKeyStorePassword, false); - setVisible(androidKeyAliasPassword, false); - setVisible(version, true); - - String a = arch.getText(); - if (a.equals("desktop")) { - setVisible(type, true); - typeChanged(); - } else if (a.equals("android")) { - setVisible(androidSDK, true); - setVisible(androidKeyStore, true); - setVisible(androidKeyAlias, true); - setVisible(androidKeyStorePassword, true); - setVisible(androidKeyAliasPassword, true); - } - } - - private void typeChanged() { - if (type.getText().equals(TYPES[0])) { - setVisible(os, true); - } else { - setVisible(os, false); - setVisible(icon, false); - } - - osChanged(); - } - - private void osChanged() { - if (os.isVisible() && (os.getText().equals("windows") || os.getText().equals("all"))) { - setVisible(icon, true); - setVisible(winJRE, true); - } else { - setVisible(icon, false); - setVisible(winJRE, false); - } - - if (os.isVisible() && (os.getText().equals("linux32") || os.getText().equals("all"))) { - setVisible(linux32JRE, true); - } else { - setVisible(linux32JRE, false); - } - - if (os.isVisible() && (os.getText().equals("linux64") || os.getText().equals("all"))) { - setVisible(linux64JRE, true); - } else { - setVisible(linux64JRE, false); - } - - if (os.isVisible() && (os.getText().equals("macOSX") || os.getText().equals("all"))) { - setVisible(osxJRE, true); - } else { - setVisible(osxJRE, false); - } - } - - @Override - protected boolean validateFields() { - boolean ok = true; - - if (!dir.validateField()) - ok = false; - - for (InputPanel i : options) { - if (i.isVisible() && !i.validateField()) - ok = false; - } - - if (androidKeyStorePassword.isVisible() && !androidKeyStorePassword.validateField()) - ok = false; - - if (androidKeyAliasPassword.isVisible() && !androidKeyAliasPassword.validateField()) - ok = false; - -// if (icon.isVisible() && !icon.getText().endsWith(".ico")) { -// icon.setError(true); -// ok = false; -// } - - if (linux32JRE.isVisible() && (!new File(linux32JRE.getText()).exists() || !linux32JRE.getText().toLowerCase().endsWith(".zip"))) { - linux32JRE.setError(true); - ok = false; - } - - if (linux64JRE.isVisible() && (!new File(linux64JRE.getText()).exists() || !linux64JRE.getText().toLowerCase().endsWith(".zip"))){ - linux64JRE.setError(true); - ok = false; - } - - if (winJRE.isVisible() && (!new File(winJRE.getText()).exists() || !winJRE.getText().toLowerCase().endsWith(".zip"))){ - winJRE.setError(true); - ok = false; - } - - if (osxJRE.isVisible() && (!new File(osxJRE.getText()).exists() || !osxJRE.getText().toLowerCase().endsWith(".zip"))){ - osxJRE.setError(true); - ok = false; - } - - return ok; - } - - private String genDesktopJar(String projectName, String versionParam, String jar) throws IOException { - String msg = null; - - if(RunProccess.runGradle(Ctx.project.getProjectDir(), versionParam + "desktop:dist")) { - File f = new File(jar); - FileUtils.copyFileToDirectory(f, new File(dir.getText())); - new File(dir.getText() + "/" + projectName + "-desktop-" + version.getText() + ".jar").setExecutable(true); - } else { - msg = "Error Generating package" ; - } - - return msg; - } - - private void packr(Platform platform, String jdk, String exe, String jar, String mainClass, String outDir) throws IOException { - String suffix = null;; - - switch(platform) { - case linux32: - suffix = "lin32"; - break; - case linux64: - suffix = "lin64"; - break; - case mac: - suffix = "mac"; - break; - case windows: - suffix = "win"; - break; - - } - - Packr.Config config = new Packr.Config(); - config.platform = platform; - config.jdk = jdk; - config.executable = exe; - config.jar = jar; - config.mainClass = mainClass; - config.vmArgs = Arrays.asList("-Xmx1G"); - config.minimizeJre = new String[] { "jre/lib/rt/com/sun/corba", "jre/lib/rt/com/sun/jndi" }; - config.outDir = outDir + "/" + exe + "-" + suffix; - - new Packr().pack(config); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ProjectToolbar.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ProjectToolbar.java deleted file mode 100644 index e73789f24..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ProjectToolbar.java +++ /dev/null @@ -1,279 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.awt.Desktop; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.File; -import java.io.IOException; - -import javax.swing.JFileChooser; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Button.ButtonStyle; -import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; -import com.badlogic.gdx.scenes.scene2d.ui.ImageButton.ImageButtonStyle; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.utils.RunProccess; - -public class ProjectToolbar extends Table { - private ImageButton newBtn; - private ImageButton loadBtn; - private ImageButton saveBtn; - private ImageButton packageBtn; - private ImageButton exitBtn; - private ImageButton playBtn; - private ImageButton assetsBtn; - private ImageButton atlasBtn; - - private Skin skin; - - public ProjectToolbar(Skin skin) { - super(skin); - this.skin = skin; - left(); - newBtn = new ImageButton(skin); - saveBtn = new ImageButton(skin); - loadBtn = new ImageButton(skin); - packageBtn = new ImageButton(skin); - exitBtn = new ImageButton(skin); - playBtn = new ImageButton(skin); - assetsBtn = new ImageButton(skin); - atlasBtn = new ImageButton(skin); - - addToolBarButton(skin, newBtn, "ic_new", "New", "Create a new project"); - addToolBarButton(skin, loadBtn, "ic_load", "Load", - "Load an existing project"); - addToolBarButton(skin, saveBtn, "ic_save", "Save", - "Save the current project"); - addToolBarButton(skin, exitBtn, "ic_exit", "Exit", - "Save changes and exits"); - row(); - - addToolBarButton(skin, playBtn, "ic_play", "Play", "Play Adventure"); - addToolBarButton(skin, packageBtn, "ic_package", "Package", - "Package the game for distribution"); - addToolBarButton(skin, assetsBtn, "ic_assets", "Assets", - "Open assets folder"); - addToolBarButton(skin, atlasBtn, "ic_atlases", "Atlas", "Create Atlas"); - - newBtn.setDisabled(false); - loadBtn.setDisabled(false); - exitBtn.setDisabled(false); - - newBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - newProject(); - } - }); - - loadBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - loadProject(); - } - }); - - exitBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - exit(); - } - }); - - saveBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - saveProject(); - } - }); - - playBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - play(); - } - }); - - packageBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - packageProject(); - } - }); - - assetsBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - openProjectFolder(); - } - }); - - atlasBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - createAtlas(); - } - }); - - Ctx.project.getWorld().addPropertyChangeListener( - new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent e) { - saveBtn.setDisabled(e.getPropertyName().equals( - "DOCUMENT_SAVED")); - } - }); - - Ctx.project.addPropertyChangeListener(Project.NOTIFY_PROJECT_LOADED, - new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent arg0) { - packageBtn.setDisabled(Ctx.project.getProjectDir() == null); - playBtn.setDisabled(Ctx.project.getProjectDir() == null); - assetsBtn.setDisabled(Ctx.project.getProjectDir() == null); - atlasBtn.setDisabled(Ctx.project.getProjectDir() == null); - } - }); - } - - private void addToolBarButton(Skin skin, ImageButton button, String icon, - String text, String tooltip) { - ImageButtonStyle style = new ImageButtonStyle( - skin.get(ButtonStyle.class)); - TextureRegion image = Ctx.assetManager.getIcon(icon); - style.imageUp = new TextureRegionDrawable(image); - - try { - TextureRegion imageDisabled = Ctx.assetManager.getIcon(icon - + "_disabled"); - style.imageDisabled = new TextureRegionDrawable(imageDisabled); - } catch (Exception e) { - - } - - button.setStyle(style); - - add(button); - button.setDisabled(true); - } - - private void newProject() { - CreateProjectDialog dialog = new CreateProjectDialog(skin); - dialog.show(getStage()); - // TODO - // if (!dialog.isCancel()) { - // playBtn.setDisabled(false); - // packageBtn.setDisabled(false); - // } - } - - private void loadProject() { - JFileChooser chooser = new JFileChooser( - Ctx.project.getProjectDir() != null ? Ctx.project - .getProjectDir() : new File(".")); - chooser.setDialogTitle("Select the project to load"); - chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - chooser.setMultiSelectionEnabled(false); - - if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { - try { - Ctx.project.saveProject(); - Ctx.project.loadProject(chooser.getSelectedFile()); - playBtn.setDisabled(false); - packageBtn.setDisabled(false); - } catch (Exception ex) { - String msg = "Something went wrong while loading the project.\n\n" - + ex.getClass().getSimpleName() - + " - " - + ex.getMessage(); - Ctx.msg.show(getStage(), msg, 2); - ex.printStackTrace(); - } - } - } - - public void exit() { - Gdx.app.exit(); - } - - private void saveProject() { - File file = Ctx.project.getProjectDir(); - - if (file == null) { - String msg = "Please create a new project first."; - Ctx.msg.show(getStage(), msg, 2); - return; - } - - try { - Ctx.project.saveProject(); - } catch (Exception ex) { - String msg = "Something went wrong while saving the project.\n\n" - + ex.getClass().getSimpleName() + " - " + ex.getMessage(); - Ctx.msg.show(getStage(), msg, 2); - } - } - - private void packageProject() { - saveProject(); - - new PackageDialog(skin).show(getStage()); - } - - private void play() { - try { - saveProject(); - - if(!RunProccess.runBladeEngine(Ctx.project.getProjectDir(), null, null)) - Ctx.msg.show(getStage(), "There was a problem running the project", 3); - } catch (IOException e) { - String msg = "Something went wrong while playing the project.\n\n" - + e.getClass().getSimpleName() + " - " + e.getMessage(); - Ctx.msg.show(getStage(), msg, 2); - } - } - - private void openProjectFolder() { - if (Desktop.isDesktopSupported()) { - try { - Desktop.getDesktop().open( - new File(Ctx.project.getProjectDir().getAbsoluteFile() - + "/assets")); - } catch (IOException e1) { - String msg = "Something went wrong while opening assets folder.\n\n" - + e1.getClass().getSimpleName() - + " - " - + e1.getMessage(); - Ctx.msg.show(getStage(), msg, 2); - } - } - } - - private void createAtlas() { - new CreateAtlasDialog(skin).show(getStage()); - } - -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/SceneList.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/SceneList.java deleted file mode 100644 index 8d45f35ba..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/SceneList.java +++ /dev/null @@ -1,250 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.IOException; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; - -import org.w3c.dom.Element; -import org.xml.sax.SAXException; - -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup; -import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.utils.Array; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.model.WorldDocument; -import com.bladecoder.engineeditor.ui.components.CellRenderer; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.ElementList; -import com.bladecoder.engineeditor.utils.EditorLogger; - -public class SceneList extends ElementList { - - private ImageButton initBtn; - private SelectBox chapters; - - public SceneList(Skin skin) { - super(skin, true); - - HorizontalGroup chapterPanel = new HorizontalGroup(); - chapters = new SelectBox(skin); - chapters.setFillParent(true); - - chapterPanel.addActor(new Label("CHAPTER ", skin, "big")); - chapterPanel.addActor(chapters); - - clearChildren(); - - add(chapterPanel).expandX().fillX(); - row(); - add(toolbar).expandX().fillX(); - row().fill(); - add(container).expandY().fill(); - - initBtn = new ImageButton(skin); - toolbar.addToolBarButton(initBtn, "ic_check", - "Set init scene", "Set init scene"); - - initBtn.setDisabled(true); - - list.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - int pos = list.getSelectedIndex(); - - if (pos == -1) { - Ctx.project.setSelectedScene(null); - } else { - Element a = list.getItems().get(pos); - Ctx.project.setSelectedScene(a); - } - - toolbar.disableEdit(pos == -1); - initBtn.setDisabled(pos == -1); - } - }); - - list.setCellRenderer(listCellRenderer); - - initBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - setDefault(); - } - - }); - - Ctx.project.addPropertyChangeListener(Project.NOTIFY_PROJECT_LOADED, - new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent arg0) { - toolbar.disableCreate(Ctx.project.getProjectDir() == null); - - addChapters(); - } - }); - - chapters.addListener(chapterListener); - - Ctx.project.getWorld().addPropertyChangeListener( - new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - EditorLogger.debug(evt.getPropertyName() + " NEW:" - + evt.getNewValue() + " OLD:" - + evt.getOldValue()); - - if (evt.getPropertyName().equals("chapter")) { - addChapters(); - } else if (evt.getPropertyName().equals( - "ELEMENT_DELETED")) { - Element e = (Element) evt.getNewValue(); - - if (e.getTagName().equals("chapter")) { - addChapters(); - } - } - } - }); - - } - - ChangeListener chapterListener = new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - String selChapter = (String) chapters.getSelected(); - - if (selChapter != null && !selChapter.equals(Ctx.project.getSelectedChapter().getId())) { - - // Save the project when changing chapter - try { - Ctx.project.saveProject(); - } catch (IOException | TransformerException e1) { - Ctx.msg.show(getStage(), - "Error saving project", 3); - EditorLogger.error(e1.getMessage()); - } - - try { - if(selChapter != null) - Ctx.project.loadChapter(selChapter); - - doc = Ctx.project.getSelectedChapter(); - - addElements(doc, doc.getElement(), "scene"); - } catch (ParserConfigurationException | SAXException - | IOException e1) { - e1.printStackTrace(); - } - } - } - }; - - public void addChapters() { - WorldDocument w = Ctx.project.getWorld(); - String[] nl = w.getChapters(); - Array array = new Array(); - - for (int i = 0; i < nl.length; i++) { - array.add(nl[i]); - } - - chapters.setItems(array); - chapters.setSelected(Ctx.project.getSelectedChapter().getId()); - invalidate(); - } - - private void setDefault() { - - int pos = list.getSelectedIndex(); - - if (pos == -1) - return; - - String id = list.getItems().get(pos).getAttribute("id"); - - doc.setRootAttr((Element) list.getItems().get(pos).getParentNode(), - "init_scene", id); - - } - - @Override - protected EditElementDialog getEditElementDialogInstance( - Element e) { - return new EditSceneDialog(skin, doc, parent, e); - } - - // ------------------------------------------------------------------------- - // ListCellRenderer - // ------------------------------------------------------------------------- - private final CellRenderer listCellRenderer = new CellRenderer() { - - @Override - protected String getCellTitle(Element e) { - String name = e.getAttribute("id"); - - Element chapter = (Element) e.getParentNode(); - - String init = chapter.getAttribute("init_scene"); - - if (init.equals(name)) - name += " "; - - return name; - } - - @Override - protected String getCellSubTitle(Element e) { - return e.getAttribute("background"); - } - - @Override - public TextureRegion getCellImage(Element e) { - String bg = e.getAttribute("background"); - - TextureRegion r = null; - - if(!bg.isEmpty()) - r = Ctx.project.getBgIcon(bg); - - if (r == null) - r = Ctx.assetManager.getIcon("ic_no_scene"); - - return r; - } - - @Override - protected boolean hasSubtitle() { - return true; - } - - @Override - protected boolean hasImage() { - return true; - } - }; -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/SoundList.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/SoundList.java deleted file mode 100644 index 7d19233e5..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/SoundList.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.bladecoder.engineeditor.ui.components.CellRenderer; -import com.bladecoder.engineeditor.ui.components.ElementList; - -public class SoundList extends ElementList { - - public SoundList(Skin skin) { - super(skin, true); - - setCellRenderer(listCellRenderer); - } - - @Override - protected EditSoundDialog getEditElementDialogInstance(Element e) { - return new EditSoundDialog(skin, doc, parent, e); - } - - // ------------------------------------------------------------------------- - // ListCellRenderer - // ------------------------------------------------------------------------- - private static final CellRenderer listCellRenderer = new CellRenderer() { - - @Override - protected String getCellTitle(Element e) { - String id = e.getAttribute("id"); - - return id; - } - - @Override - protected String getCellSubTitle(Element e) { - String filename = e.getAttribute("filename"); - String loop = e.getAttribute("loop"); - String volume = e.getAttribute("volume"); - - StringBuilder sb = new StringBuilder(); - - if (!filename.isEmpty()) - sb.append("filename: ").append(filename); - if (!loop.isEmpty()) - sb.append(" loop: ").append(loop); - if (!volume.isEmpty()) - sb.append(" volume: ").append(volume); - - return sb.toString(); - } - - @Override - protected boolean hasSubtitle() { - return true; - } - }; -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/SpriteList.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/SpriteList.java deleted file mode 100644 index d952bcef0..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/SpriteList.java +++ /dev/null @@ -1,163 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.ChapterDocument; -import com.bladecoder.engineeditor.ui.components.CellRenderer; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.ElementList; - -public class SpriteList extends ElementList { - - private ImageButton initBtn; - - public SpriteList(Skin skin) { - super(skin, true); - - initBtn = new ImageButton(skin); - toolbar.addToolBarButton(initBtn, "ic_check", "Set init scene", "Set init scene"); - initBtn.setDisabled(true); - - setCellRenderer(listCellRenderer); - - list.addListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, Actor actor) { - int pos = list.getSelectedIndex(); - - String id = null; - - if (pos != -1) - id = list.getItems().get(pos).getAttribute("id"); - - Ctx.project.setSelectedFA(id); - - toolbar.disableEdit(pos== -1); - initBtn.setDisabled(pos== -1); - } - }); - - initBtn.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - setDefault(); - } - }); - } - - private void setDefault() { - ChapterDocument scn = (ChapterDocument) doc; - - int pos = list.getSelectedIndex(); - - if (pos == -1) - return; - - String id = list.getItems().get(pos).getAttribute("id"); -// String prev = w.getRootAttr("init_scene"); - - scn.setRootAttr((Element)list.getItems().get(pos).getParentNode(), "init_frame_animation", id); - } - - @Override - protected EditElementDialog getEditElementDialogInstance(Element e) { - return new EditSpriteDialog(skin, doc, parent, e); - } - - // ------------------------------------------------------------------------- - // ListCellRenderer - // ------------------------------------------------------------------------- - private final CellRenderer listCellRenderer = new CellRenderer() { - - @Override - protected String getCellTitle(Element e) { - String name = e.getAttribute("id"); - Element actor = (Element)e.getParentNode(); - - String init = actor.getAttribute("init_frame_animation"); - - if(init == null || init.isEmpty()) { - Node n = actor.getFirstChild(); - while(!(n instanceof Element)) - n = n.getNextSibling(); - - init = ((Element)n).getAttribute("id"); - } - - if(init.equals(name)) - name += " "; - - return name; - } - - @Override - protected String getCellSubTitle(Element e) { - String source = e.getAttribute("source"); - String speed = e.getAttribute("speed"); - String delay = e.getAttribute("delay"); - String count = e.getAttribute("count"); - - StringBuilder sb = new StringBuilder(); - - if (!source.isEmpty()) - sb.append("source: ").append(source); - if (!speed.isEmpty()) - sb.append(" speed: ").append(speed); - if (!delay.isEmpty()) - sb.append(" delay: ").append(delay); - if (!count.isEmpty()) - sb.append(" count: ").append(count); - - - return sb.toString(); - } - - @Override - public TextureRegion getCellImage(Element e) { - String u = null; - - if (e.getAttribute("animation_type").equalsIgnoreCase("repeat")) { - u = "ic_repeat"; - } else if (e.getAttribute("animation_type").equalsIgnoreCase("yoyo")) { - u = "ic_yoyo"; - } else { - u = "ic_sprite_actor"; - } - - return Ctx.assetManager.getIcon(u); - } - - @Override - protected boolean hasSubtitle() { - return true; - } - - @Override - protected boolean hasImage() { - return true; - } - }; -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/VerbList.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/VerbList.java deleted file mode 100644 index b434fc346..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/VerbList.java +++ /dev/null @@ -1,139 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.text.MessageFormat; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.BaseDocument; -import com.bladecoder.engineeditor.ui.components.CellRenderer; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.ElementList; - - -public class VerbList extends ElementList { - - public static final String VERBS[] = { "lookat", "pickup", "talkto", "use", "leave", "init", - "test", "custom" }; - - private ActionList actionList; - - public VerbList(Skin skin) { - super(skin, true); - actionList = new ActionList(skin); - -// addActor(actionList); - row(); - add(actionList).expand().fill(); - - list.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - addActions(); - } - }); - - list.setCellRenderer(listCellRenderer); - } - - @Override - protected EditElementDialog getEditElementDialogInstance(Element e) { - return new EditVerbDialog(skin, doc, parent, e); - } - - @Override - public void addElements(BaseDocument doc, Element parent, String tag) { - super.addElements(doc, parent, tag); - addActions(); - } - - private void addActions() { - int pos = list.getSelectedIndex(); - - Element v = null; - - if (pos != -1) { - v = list.getItems().get(pos); - } - - actionList.addElements(doc, v, "action"); - } - - // ------------------------------------------------------------------------- - // ListCellRenderer - // ------------------------------------------------------------------------- - private final CellRenderer listCellRenderer = new CellRenderer() { - - @Override - protected String getCellTitle(Element e) { - return e.getAttribute("id"); - } - - @Override - protected String getCellSubTitle(Element e) { - String state = e.getAttribute("state"); - String target = e.getAttribute("target"); - - StringBuilder sb = new StringBuilder(); - - if (!state.isEmpty()) - sb.append("when ").append(state); - if (!target.isEmpty()) - sb.append(" with target '").append(target).append("'"); - - return sb.toString(); - } - - @Override - public TextureRegion getCellImage(Element e) { - boolean custom = true; - - String verbName = e.getAttribute("id"); - for(String v:VERBS) { - if(v.equals(verbName)) { - custom = false; - break; - } - } - - String iconName = MessageFormat.format("ic_{0}", e.getAttribute("id")); - TextureRegion image = null; - - if(!custom) - image = Ctx.assetManager.getIcon(iconName); - else - image = Ctx.assetManager.getIcon("ic_custom"); - - return image; - } - - @Override - protected boolean hasSubtitle() { - return true; - } - - @Override - protected boolean hasImage() { - return true; - } - }; -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/WorldProps.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/WorldProps.java deleted file mode 100644 index 7db2c88ca..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/WorldProps.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.ui.components.PropertyTable; - - -public class WorldProps extends PropertyTable { - - public static final String WIDTH_PROP = "width"; - public static final String HEIGHT_PROP = "height"; - public static final String TITLE_PROP = "title"; - -// TableModelListener tableModelListener = new TableModelListener() { -// @Override -// public void tableChanged(TableModelEvent e) { -// if (e.getType() == TableModelEvent.UPDATE) { -// int row = e.getFirstRow(); -// updateModel((String) propertyTable.getModel().getValueAt(row, 0), -// (String) propertyTable.getModel().getValueAt(row, 1)); -// } -// } -// }; - - public WorldProps(Skin skin) { - super(skin); - - Ctx.project.addPropertyChangeListener(Project.NOTIFY_PROJECT_LOADED, - new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent arg0) { - setProject(); - } - }); - } - - @Override - protected void updateModel(String property, String value) { - if (property.equals(WIDTH_PROP)) { - Ctx.project.getWorld().setWidth(value); - } else if (property.equals(TITLE_PROP)) { - Ctx.project.getConfig().setProperty(TITLE_PROP, value); - } else if (property.equals(HEIGHT_PROP)) { - Ctx.project.getWorld().setHeight(value); - } - } - - private void setProject() { - clear(); - addProperty(WIDTH_PROP, Ctx.project.getWorld().getWidth()); - addProperty(HEIGHT_PROP, Ctx.project.getWorld().getHeight()); - addProperty(TITLE_PROP, Ctx.project.getTitle()); - - invalidateHierarchy(); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditElementDialog.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditElementDialog.java deleted file mode 100644 index 2cbfe6627..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditElementDialog.java +++ /dev/null @@ -1,131 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui.components; - -import java.text.MessageFormat; - -import org.w3c.dom.Element; - -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.ChangeEvent; -import com.bladecoder.engineeditor.model.BaseDocument; - -public abstract class EditElementDialog extends EditDialog { - - protected Element e; - protected Element parent; - protected String type; - protected BaseDocument doc; - - protected InputPanel[] i; - protected String a[]; - - protected ChangeListener listener; - - public EditElementDialog(Skin skin) { - super("", skin); - } - - protected void init(InputPanel[] inputs, String attrs[], BaseDocument doc, Element parent, String type, Element e) { - this.i = inputs; - this.a = attrs; - this.e = e; - this.doc = doc; - this.parent = parent; - this.type = type; - - for (InputPanel i : inputs) { - addInputPanel(i); - } - - if (e == null) { - setTitle("CREATE " + type.toUpperCase()); - } else { - String s = e.getAttribute("id"); - - if(s==null||s.isEmpty()) s = e.getTagName(); - - setTitle(MessageFormat.format("EDIT ELEMENT ''{0}''", s)); - - for (int pos = 0; pos < attrs.length; pos++) { - InputPanel i = inputs[pos]; - i.setText(e.getAttribute(attrs[pos])); - } - } - - // TODO Set focus to the 1st element -// if(inputs.length > 0) { -// getStage().setKeyboardFocus(inputs[0].getField()); -// } - } - - @Override - protected void ok() { - - if (e == null) { - create(); - } - - fill(); - - if(listener != null) - listener.changed(new ChangeEvent(), this); - } - - public void setListener(ChangeListener l) { - listener = l; - } - - protected void create() { - e = doc.createElement(parent, type); - } - - protected void fill() { - for (int j = 0; j < a.length; j++) { - InputPanel input = i[j]; - - if (!input.getText().isEmpty() && input.isVisible()) { - if(a[j].equals("id")) { - doc.setId(e, input.getText()); - } else { - e.setAttribute(a[j], input.getText()); - } - } else { - e.removeAttribute(a[j]); - } - - - } - - doc.setModified(e); - } - - public Element getElement() { - return e; - } - - @Override - protected boolean validateFields() { - - for (InputPanel p : i) { - if (p.isVisible() && !p.validateField()) - return false; - } - - return true; - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/ElementList.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/ElementList.java deleted file mode 100644 index 5074da685..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/ElementList.java +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui.components; - -import java.util.Comparator; - -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.bladecoder.engineeditor.model.BaseDocument; - -public abstract class ElementList extends EditList { - - protected BaseDocument doc; - protected Element parent; - - protected Element clipboard; - - private boolean sorted; - - public ElementList(Skin skin, boolean sorted) { - super(skin); - - list.addListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - int pos = list.getSelectedIndex(); - - toolbar.disableEdit(pos == -1); - } - }); - - this.sorted = sorted; - - } - - public void addElements(BaseDocument doc, Element parent, String tag) { - this.doc = doc; - this.parent = parent; - - list.getItems().clear(); - list.getSelection().clear(); - - if (parent != null) { - - NodeList nl; - - if(tag == null) - nl = parent.getChildNodes(); - else { -// nl = parent.getElementsByTagName(tag); - nl = doc.getChildrenByTag(parent, tag); - } - - for (int i = 0; i < nl.getLength(); i++) { - if(nl.item(i) instanceof Element) - addItem((Element) nl.item(i)); - } - } - - if (getItems().size > 0) - list.setSelectedIndex(0); - - toolbar.disableEdit(list.getSelectedIndex() < 0); - - if(sorted) { - list.getItems().sort(new Comparator() { - @Override - public int compare(Element o1, Element o2) { - return o1.getAttribute("id").compareTo(o2.getAttribute("id")); - } - }); - } - - toolbar.disableCreate(parent == null); -// list.setWidth(getWidth()); - list.invalidateHierarchy(); - } - - @Override - protected void create() { - EditElementDialog dialog = getEditElementDialogInstance(null); - dialog.show(getStage()); - dialog.setListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - Element e = ((EditElementDialog)actor).getElement(); - addItem(e); - int i = getItems().indexOf(e, true); - if(i != -1) - list.setSelectedIndex(i); - - list.invalidateHierarchy(); - } - }); - } - - @Override - protected void edit() { - - Element e = list.getSelected(); - - if (e == null) - return; - - - EditElementDialog dialog = getEditElementDialogInstance(e); - dialog.show(getStage()); - dialog.setListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - Element e = ((EditElementDialog)actor).getElement(); - doc.setModified(e); - } - }); - } - - protected abstract EditElementDialog getEditElementDialogInstance(Element e); - - @Override - protected void delete() { - int pos = list.getSelectedIndex(); - - if (pos == -1) - return; - - Element e = list.getItems().removeIndex(pos); - - doc.deleteElement(e); - - clipboard = e; - toolbar.disablePaste(false); - - if (pos > 0) - list.setSelectedIndex(pos - 1); - else if (pos == 0 && list.getItems().size > 0) - list.setSelectedIndex(0); -// else -// list.clearSelection(); - } - - @Override - protected void copy() { - Element e = list.getSelected(); - - if (e == null) - return; - - clipboard = (Element) e.cloneNode(true); - toolbar.disablePaste(false); - } - - @Override - protected void paste() { - Element newElement = doc.cloneNode(parent, clipboard); - int pos = list.getSelectedIndex() + 1; - - Element e2 = null; - - if(pos!=0 && pos < list.getItems().size) - e2 = list.getItems().get(pos); - - list.getItems().insert(pos, newElement); - - Node parent = newElement.getParentNode(); - parent.insertBefore(newElement, e2); - - list.setSelectedIndex(pos); - list.invalidateHierarchy(); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/FileInputPanel.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/FileInputPanel.java deleted file mode 100644 index 0fd0553e4..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/FileInputPanel.java +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui.components; - -import java.io.File; - -import javax.swing.JFileChooser; - -import com.badlogic.gdx.scenes.scene2d.InputEvent; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.TextButton; -import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; -import com.bladecoder.engineeditor.Ctx; - -public class FileInputPanel extends InputPanel { - - private File cd; - private File selected; - - private boolean dirOnly = false; - private final static String FILE_TEXT = "Select file"; - private final static String DIR_TEXT = "Select folder"; - - public FileInputPanel(Skin skin, String title, String desc, boolean dirOnly) { - this(skin, title, desc, Ctx.project.getProjectDir() != null ? Ctx.project.getProjectDir() : new File("."), dirOnly); - } - - public FileInputPanel(Skin skin, String title, String desc, File current, boolean dOnly) { - super(skin, title, desc, new TextButton(dOnly?DIR_TEXT:FILE_TEXT, skin), null); - - this.cd = current; - this.dirOnly = dOnly; - -// ((TextField) getField()).setEditable(false); - - ((TextButton) getField()).addListener(new ClickListener() { - public void clicked (InputEvent event, float x, float y) { - JFileChooser chooser = new JFileChooser(cd); - - if(dirOnly) { - chooser.setDialogTitle("Select folder"); - chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - } else { - chooser.setDialogTitle("Select file"); - } - - chooser.setMultiSelectionEnabled(false); - - if (chooser.showDialog(null, "Ok") == JFileChooser.APPROVE_OPTION) { - ((TextButton) getField()).setText(chooser.getSelectedFile().getAbsolutePath()); - selected = cd = chooser.getSelectedFile(); - } - } - }); - } - - public File getFile() { - return selected; - } - - @Override - public String getText() { - if(selected != null) - return selected.getAbsolutePath(); - else - return ""; - } - - @Override - public void setText(String text) { - super.setText(text); - selected=cd= new File(text); - } - -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/InputPanel.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/InputPanel.java deleted file mode 100644 index e2842cbf1..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/InputPanel.java +++ /dev/null @@ -1,320 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui.components; - -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; -import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.ui.TextButton; -import com.badlogic.gdx.scenes.scene2d.ui.TextField; -import com.bladecoder.engine.actions.Param; -import com.bladecoder.engine.actions.Param.Type; -import com.bladecoder.engineeditor.Ctx; - -public class InputPanel extends Table { - private static final String[] booleanValues = {"true", "false"}; - private static final String[] booleanNotMandatoryValues = {"", "true", "false"}; - - private Actor field; - private Label title; - private Label desc; - private Param.Type type = Type.STRING; - private boolean mandatory = false; - - @SuppressWarnings("unchecked") - public InputPanel(Skin skin, String title, String desc, String[] options) { - init(skin, title, desc, new SelectBox(skin), mandatory, null); - - if(options != null) - ((SelectBox)field).setItems(options); - } - - public InputPanel(Skin skin, String title, String desc) { - init(skin, title, desc, new TextField("", skin), mandatory, null); - } - - public InputPanel(Skin skin, String title, String desc, boolean mandatory) { - init(skin, title, desc, new TextField("", skin), mandatory, null); - } - - public InputPanel(Skin skin, String title, String desc, Param.Type type, boolean mandatory) { - this(skin, title, desc, type, mandatory, null, null); - } - - public InputPanel(Skin skin, String title, String desc, Param.Type type, boolean mandatory, String defaultValue) { - this(skin, title, desc, type, mandatory, defaultValue, null); - } - - @SuppressWarnings("unchecked") - public InputPanel(Skin skin, String title, String desc, Param.Type type, boolean mandatory, String defaultValue, String[] options) { - this.type = type; - - if(options != null) { - init(skin, title, desc, new SelectBox(skin), mandatory, defaultValue); - - ((SelectBox)field).setItems(options); - return; - } - - switch(type){ - case BOOLEAN: - init(skin, title, desc, new SelectBox(skin), mandatory, defaultValue); - ((SelectBox)field).setItems(mandatory?booleanValues:booleanNotMandatoryValues); - if(defaultValue != null) - setText(defaultValue); - break; - - case VECTOR2: - init(skin, title, desc, new Vector2Panel(skin), mandatory, defaultValue); - break; - - case DIMENSION: - init(skin, title, desc, new DimPanel(skin), mandatory, defaultValue); - break; - - case ACTOR: - { - NodeList actors = Ctx.project.getSelectedChapter().getActors(Ctx.project.getSelectedScene()); - int l = actors.getLength(); - if(!mandatory) l++; - String values[] = new String[l]; - - if(!mandatory) { - values[0] = ""; - } - - for(int i = 0; i < actors.getLength(); i++) { - if(mandatory) - values[i] = ((Element)actors.item(i)).getAttribute("id"); - else - values[i+1] = ((Element)actors.item(i)).getAttribute("id"); - } - - init(skin, title, desc, new SelectBox(skin), mandatory, defaultValue); - ((SelectBox)field).setItems(values); - if(defaultValue != null) - setText(defaultValue); - } - break; - - case SCENE: - { - NodeList scenes = Ctx.project.getSelectedChapter().getScenes(); - int l = scenes.getLength(); - if(!mandatory) l++; - String values[] = new String[l]; - - if(!mandatory) { - values[0] = ""; - } - - for(int i = 0; i < scenes.getLength(); i++) { - if(mandatory) - values[i] = ((Element)scenes.item(i)).getAttribute("id"); - else - values[i+1] = ((Element)scenes.item(i)).getAttribute("id"); - } - - init(skin, title, desc, new SelectBox(skin), mandatory, defaultValue); - ((SelectBox)field).setItems(values); - if(defaultValue != null) - setText(defaultValue); - } - break; - - case CHAPTER: - { - String[] chapters = Ctx.project.getWorld().getChapters(); - int l = chapters.length; - if(!mandatory) l++; - String values[] = new String[l]; - - if(!mandatory) { - values[0] = ""; - } - - for(int i = 0; i < chapters.length; i++) { - if(mandatory) - values[i] = chapters[i]; - else - values[i+1] = chapters[i]; - } - - init(skin, title, desc, new SelectBox(skin), mandatory, defaultValue); - ((SelectBox)field).setItems(values); - if(defaultValue != null) - setText(defaultValue); - } - break; - - default: - init(skin, title, desc, new TextField("", skin), mandatory, defaultValue); - break; - - } - } - - public InputPanel(Skin skin, String title, String desc, Actor c, String defaultValue) { - init(skin, title, desc, c, false, defaultValue); - } - - private void init(Skin skin, String title, String desc, Actor c, boolean mandatory, String defaultValue) { - this.mandatory = mandatory; - - this.setSkin(skin); - LabelStyle style = new LabelStyle(skin.get(LabelStyle.class)); - this.title = new Label(title, style); - - this.desc = new Label(desc,skin, "subtitle"); - this.desc.setWrap(false); - - this.field = c; - - add(this.title).left(); - row().expand(); - add(field).left(); - row().expand(); - add(this.desc).left(); - - if(defaultValue != null) - setText(defaultValue); - } - - - public void setMandatory(boolean value) { - mandatory = value; - } - - public void setError(boolean value) { - if(value) - title.getStyle().fontColor = Color.RED; - else - title.getStyle().fontColor = Color.WHITE; - } - - @SuppressWarnings("unchecked") - public String getText() { - - if(field instanceof TextField) - return ((TextField)field).getText(); - else if(field instanceof SelectBox) - return (String)((SelectBox)field).getSelected(); - else if(field instanceof Vector2Panel) - return ((Vector2Panel)field).getText(); - else if(field instanceof DimPanel) - return ((DimPanel)field).getText(); - - return null; - } - - public String getTitle() { - return title.getText().toString(); - } - - @SuppressWarnings("unchecked") - public int getSelectedIndex() { - if(field instanceof SelectBox) - return ((SelectBox)field).getSelectedIndex(); - - return 0; - } - - public Actor getField() { - return field; - } - - @SuppressWarnings("unchecked") - public void setText(String text) { - if(field instanceof TextField) - ((TextField)field).setText(text); - else if(field instanceof SelectBox) { - int idx = ((SelectBox)field).getItems().indexOf(text, false); - if(idx != -1) - ((SelectBox)field).setSelectedIndex(idx); - } else if(field instanceof Vector2Panel) - ((Vector2Panel)field).setText(text); - else if(field instanceof DimPanel) - ((DimPanel)field).setText(text); - else if(field instanceof TextButton) - ((TextButton)field).setText(text); - } - - public boolean validateField() { - - String s = getText(); - - if(mandatory) { - if(s == null || s.trim().isEmpty()) { - setError(true); - return false; - } - } - - if(field instanceof SelectBox) return true; - - if(!mandatory && (s==null || s.trim().isEmpty())) { - setError(false); - return true; - } - - switch(type){ - case FLOAT: - try { - Float.parseFloat(s); - } catch (NumberFormatException e) { - setError(true); - return false; - } - break; - case INTEGER: - try { - Integer.parseInt(s); - } catch (NumberFormatException e) { - setError(true); - return false; - } - break; - case VECTOR2: - - if(!((Vector2Panel)field).validateField()) { - setError(true); - return false; - } - break; - case DIMENSION: - - if(!((DimPanel)field).validateField()) { - setError(true); - return false; - } - - break; - default: - break; - - } - - setError(false); - return true; - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/PropertyTable.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/PropertyTable.java deleted file mode 100644 index 3f5a51a15..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/PropertyTable.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.ui.components; - -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.ui.TextField; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.scenes.scene2d.utils.FocusListener; - -public class PropertyTable extends Table { - private static final String[] BOOLEAN_VALUES = {"", "true", "false"}; - - Skin skin; - - public enum Types { - INTEGER, BOOLEAN, FLOAT, STRING - } - - public PropertyTable(Skin skin) { - super(skin); - this.skin = skin; - top().left(); - - add(new Label("Name", skin)); - add(new Label("Value", skin)); - } - - public void addProperty(String name, String value, Types type) { - - row(); - add(new Label(name, skin)).expandX().left(); - - if(type == Types.BOOLEAN) { - SelectBox sb= new SelectBox(skin); - sb.setItems(BOOLEAN_VALUES); - if(value!=null) - sb.setSelected(value); - sb.setName(name); - add(sb).expandX().left(); - - sb.addListener(new ChangeListener() { - - @SuppressWarnings("unchecked") - @Override - public void changed( - com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.ChangeEvent event, - Actor actor) { - updateModel(actor.getName(), ((SelectBox)actor).getSelected()); - - } - }); - } else { - TextField tf = new TextField( value==null?"":value, skin); - tf.setName(name); - add(tf).expandX().left(); - - tf.addListener(new FocusListener() { - - @Override - public void keyboardFocusChanged (FocusEvent event, Actor actor, boolean focused) { - if(!focused) - updateModel(actor.getName(), ((TextField)actor).getText()); - } - }); - } - } - - public void addProperty(String name, int value) { - addProperty(name, Integer.toString(value), Types.INTEGER); - } - - public void addProperty(String name, float value) { - addProperty(name, Float.toString(value), Types.FLOAT); - } - - public void addProperty(String name, String value) { - addProperty(name, value, Types.STRING); - } - - public void addProperty(String name, boolean value) { - addProperty(name, Boolean.toString(value), Types.BOOLEAN); - } - - protected void updateModel(String property, String value) { - - } - -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/EditorLogger.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/EditorLogger.java deleted file mode 100644 index cd0b776e8..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/EditorLogger.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.utils; - -public class EditorLogger { - private static String TAG = "EDITOR"; - public static enum Levels {DEBUG, ERROR}; - - public static Levels level = Levels.ERROR; - - public static void debug(String message) { - if(level == Levels.DEBUG) - System.out.println(TAG + ": " + message); - } - - public static void error(String message) { - System.err.println(TAG + ": " + message); - } - - public static void error(String message, Exception e) { - System.out.println(TAG + ": " + message + " Exception: " + e.getMessage()); - } - - public static void toggle() { - if (level == Levels.DEBUG) - level = Levels.ERROR; - else - level = Levels.DEBUG; - } - - public static boolean debugMode() { - if (level == Levels.DEBUG) - return true; - - return false; - } - - public static Levels getDebugLevel() { - return level; - } - - public static void setDebugLevel(Levels l) { - level = l; - } - - public static void setDebug() { - level = Levels.DEBUG; - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/ExtractStrings.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/ExtractStrings.java deleted file mode 100644 index 7716ef489..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/ExtractStrings.java +++ /dev/null @@ -1,213 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.utils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.Properties; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -/** - * Extract all strings from chapter to the I18N properties file. - * - * @author rgarcia - */ -public class ExtractStrings { - private final static String[] i18nAttributes = {"text", "desc", "response_text"}; - - // other locale message properties to generate - private final static String[] locales = {"es"}; - - Properties prop = new Properties(); - - String xmlFilename; - String propFilename; - String propFilenameLocales[] = new String[locales.length]; - Properties propLocales[] = new Properties[locales.length]; - - Document doc; - - public void parseXML(String xmlFilename, String propFilename) throws ParserConfigurationException, SAXException, - IOException { - this.xmlFilename = xmlFilename; - this.propFilename = propFilename; - - // If the .properties name is not given, it is used the same that the xml - if(propFilename == null) { - this.propFilename = xmlFilename.substring(0, xmlFilename.length() - 4) + ".properties"; - - for(int i = 0; i < locales.length; i++) { - propFilenameLocales[i] = xmlFilename.substring(0, xmlFilename.length() - 4) + "_" + locales[i] + ".properties"; - } - } else { - for(int i = 0; i < locales.length; i++) { - propFilenameLocales[i] = this.propFilename.substring(0, this.propFilename.length() - 11) + "_" + locales[i] + ".properties"; - } - } - - File fXmlFile = new File(xmlFilename); - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - doc = dBuilder.parse(fXmlFile); - - File propFile = new File(this.propFilename); - - if(propFile.exists()) { - prop.load(new FileInputStream(propFile)); - } - - for(int i = 0; i < propFilenameLocales.length; i++) { - File propFileLocale = new File(propFilenameLocales[i]); - propLocales[i] = new Properties(); - - if(propFileLocale.exists()) { - propLocales[i].load(new FileInputStream(propFileLocale)); - } - } - } - - public void extract() { - extract(doc.getDocumentElement(), doc.getDocumentElement().getAttribute("id")); - } - - private void extract(Element e, String key) { - for(String attr:i18nAttributes) { - if(e.getAttribute(attr) != null && !e.getAttribute(attr).isEmpty()) { - String key2 = key + "." + attr; - String value = e.getAttribute(attr); - - if(e.getAttribute(attr).charAt(0) != '@') { - prop.put(key2, value); - - for(int i = 0; i < locales.length; i++) { - propLocales[i].put(key2, value); - } - - // change XML value - e.getAttributeNode(attr).setNodeValue("@" + key2); - } - } - } - - NodeList nodes = e.getChildNodes(); - - for (int i = 0, j=0; i < nodes.getLength(); i++) { - Node n = nodes.item(i); - - if (n.getNodeType() == Node.ELEMENT_NODE) { - Element e2 = (Element) n; - - String state = e2.getAttribute("state"); - String target = e2.getAttribute("target"); - String id = e2.getAttribute("id"); - - if (id.isEmpty()) - id = Integer.toString(j); - - if(!state.isEmpty()) id = id + "." + state; - if(!target.isEmpty()) id = id + "." + target; - - String key2 = key + "." + id; - - if(key.isEmpty()) key2 = id; - - extract(e2, key2); - - j++; - } - } - - } - - public void writeProp() throws IOException { - FileOutputStream os = new FileOutputStream(propFilename); - Writer out = new OutputStreamWriter(os, "ISO-8859-1"); - prop.store(out, null); - - for(int i = 0; i < locales.length; i++) { - FileOutputStream osES = new FileOutputStream(propFilenameLocales[i]); - Writer outES = new OutputStreamWriter(osES, "ISO-8859-1"); - propLocales[i].store(outES, null); - } - } - - public void writeXML() throws TransformerException, FileNotFoundException { - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - Transformer transformer = transformerFactory.newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - DOMSource source = new DOMSource(doc); - StreamResult result = new StreamResult(new FileOutputStream(xmlFilename)); - transformer.transform(source, result); - } - - /** - * Main method - * - * @param args - * XML filename - * Props filename (optional) - * @throws IOException - * @throws SAXException - * @throws ParserConfigurationException - * @throws TransformerException - */ - public static void main(String[] args) throws ParserConfigurationException, SAXException, - IOException, TransformerException { - - if (args.length < 1) { - usage(); - System.exit(0); - } - - String xmlFilename = args[0]; - String propFilename = null; - - if(args.length == 2) { - propFilename = args[1]; - } - - ExtractStrings e = new ExtractStrings(); - e.parseXML(xmlFilename, propFilename); - e.extract(); - e.writeProp(); - e.writeXML(); - System.out.println("Strings extracted successfully for " + args[0]); - } - - private static void usage() { - System.out.println("XML filename argument missing.\n"); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/HttpUtils.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/HttpUtils.java deleted file mode 100644 index 3307b8ba3..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/HttpUtils.java +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.utils; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; - -/** - * @author Aurelien Ribon | http://www.aurelienribon.com/ - */ -public class HttpUtils { - public static DownloadTask downloadAsync(URL input, OutputStream output, Callback callback) { - final DownloadTask task = new DownloadTask(input, output, callback); - - new Thread(new Runnable() { - @Override public void run() { - task.download(); - } - }).start(); - - return task; - } - - public static interface Callback { - public void completed(); - public void canceled(); - public void error(IOException ex); - public void updated(int length, int totalLength); - } - - public static class DownloadTask { - private final URL input; - private final OutputStream output; - private final Callback callback; - private boolean run = true; - - public DownloadTask(URL input, OutputStream output, Callback callback) { - this.input = input; - this.output = output; - this.callback = callback; - } - - public void stop() { - run = false; - } - - public URL getInput() { - return input; - } - - public OutputStream getOutput() { - return output; - } - - public Callback getCallback() { - return callback; - } - - private void download() { - OutputStream os = null; - InputStream is = null; - IOException ex = null; - - try { - HttpURLConnection connection = (HttpURLConnection) input.openConnection(); - connection.setDoInput(true); - connection.setDoOutput(false); - connection.setUseCaches(true); - connection.setConnectTimeout(3000); - connection.connect(); - - is = new BufferedInputStream(connection.getInputStream(), 4096); - os = output; - - byte[] data = new byte[4096]; - int length = connection.getContentLength(); - int total = 0; - - int count; - while (run && (count = is.read(data)) != -1) { - total += count; - os.write(data, 0, count); - if (callback != null) callback.updated(total, length); - } - - } catch (IOException ex1) { - ex = ex1; - - } finally { - if (os != null) try {os.flush(); os.close();} catch (IOException ex1) {} - if (is != null) try {is.close();} catch (IOException ex1) {} - - if (callback != null) { - if (ex != null) callback.error(ex); - else if (run == true) callback.completed(); - else callback.canceled(); - } - } - } - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/ImageUtils.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/ImageUtils.java deleted file mode 100644 index b7d2dcd43..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/ImageUtils.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.utils; - -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.RenderingHints; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.net.URL; - -import javax.imageio.ImageIO; -import javax.swing.ImageIcon; - -public class ImageUtils { - - public static ImageIcon getImageIcon(URL u, int w) throws IOException { - BufferedImage img = null; - BufferedImage tmp = ImageIO.read(u); - ImageIcon icon = null; - - if (tmp != null) { - float h = (float) tmp.getHeight() * (float) w / (float) tmp.getWidth(); - - img = scaleImage(w, (int) h, tmp); - icon = new ImageIcon((Image) img); - } - - return icon; - } - - public static BufferedImage scaleImage(int w, int h, BufferedImage img) { - BufferedImage bi; - bi = new BufferedImage(w, h, BufferedImage.TRANSLUCENT); - Graphics2D g2d = (Graphics2D) bi.createGraphics(); -// g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); -// g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, -// RenderingHints.VALUE_RENDER_QUALITY)); - - g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BICUBIC); - g2d.drawImage(img, 0, 0, w, h, null); - g2d.dispose(); - return bi; - } - - public static void scaleImageFile(File org, File dest, float scale) throws IOException { - BufferedImage destImg = null; - BufferedImage orgImg = ImageIO.read(org); - - if (orgImg != null) { - destImg = scaleImage((int)(orgImg.getWidth() * scale), (int)(orgImg.getHeight() * scale), orgImg); - ImageIO.write(destImg, org.getName().substring(org.getName().lastIndexOf('.') + 1), dest); - } - } - - public static void scaleDirFiles(File orgDir, File destDir, float scale) throws IOException { - File[] files = orgDir.listFiles(new FilenameFilter() { - - @Override - public boolean accept(File dir, String name) { - if(name.toLowerCase().endsWith("png")|| - name.toLowerCase().endsWith("jpg")|| - name.toLowerCase().endsWith("etc1")) return true; - - return false; - } - }); - - for(File f:files) { - ImageUtils.scaleImageFile(f, new File(destDir, f.getName()), scale); - } - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/Message.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/Message.java deleted file mode 100644 index bf9b998c7..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/Message.java +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.utils; - -import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeOut; -import static com.badlogic.gdx.scenes.scene2d.actions.Actions.sequence; - -import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds; -import com.badlogic.gdx.math.Interpolation; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.scenes.scene2d.actions.Actions; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.utils.Align; - -public class Message extends Label { - static public float fadeDuration = 0.4f; - boolean isModal = false; - - public Message(Skin skin) { - super("", skin, "message"); - - setWrap(true); - setAlignment(Align.center, Align.center); - } - - public void show (Stage stage, String text) { - show(stage, text, false); - } - - public void show (Stage stage, String text, boolean modal) { - isModal = modal; - - if(text == null) { - hide(); - return; - } - - add(stage, text); - - if (fadeDuration > 0) { - getColor().a = 0; - addAction(Actions.fadeIn(fadeDuration, Interpolation.fade)); - } - } - - private void add(Stage stage, String text) { - clearActions(); - - setText(text); - - TextBounds bounds2 = getStyle().font.getWrappedBounds(text, stage.getWidth() * .8f); - - setSize(bounds2.width + bounds2.height, bounds2.height + bounds2.height * 2); - - stage.addActor(this); - setPosition(Math.round((stage.getWidth() - getWidth()) / 2), Math.round((stage.getHeight() - getHeight()) / 2)); - invalidate(); - } - - @Override - public Actor hit(float x, float y, boolean touchable) { - if(isModal) - return this; - - return null; - } - - public void show (Stage stage, String text, float duration) { - isModal = false; - - if(text == null) { - hide(); - return; - } - - add(stage, text); - - if (fadeDuration > 0) { - getColor().a = 0; - addAction(sequence(Actions.fadeIn(fadeDuration, Interpolation.fade), - Actions.delay(duration, sequence(fadeOut(fadeDuration, Interpolation.fade), Actions.removeActor())))); - } - } - - public void hide () { - isModal = false; - setText(""); - - if (fadeDuration > 0) { - addAction(sequence(fadeOut(fadeDuration, Interpolation.fade), Actions.removeActor())); - } else - remove(); - } - -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/RunProccess.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/RunProccess.java deleted file mode 100644 index 9936d271d..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/RunProccess.java +++ /dev/null @@ -1,160 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.utils; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -/** - * Run Java Process in a new VM - * - * @author rgarcia - */ -public class RunProccess { - private static final String ANT_MAIN_CLASS = "org.apache.tools.ant.launch.Launcher"; - - private static String getClasspath(List classpathEntries) { - StringBuilder builder = new StringBuilder(); - int count = 0; - final int totalSize = classpathEntries.size(); - for (String classpathEntry : classpathEntries) { - builder.append(classpathEntry); - count++; - if (count < totalSize) { - builder.append(System.getProperty("path.separator")); - } - } - return builder.toString(); - } - - public static boolean runBladeEngine(File prjFolder, String chapter, String scene) throws IOException { - String args = ":desktop:run -PappArgs=[\"-w\""; - - if(chapter != null) { - args += ",\"-chapter\",\"" + chapter + "\""; - } - - if(scene != null) { - args += ",\"-t\",\"" + scene + "\""; - } - - args += "]"; - - return runGradle(prjFolder, args); - } - - public static void runAnt(String buildFile, String target, String distDir, String projectDir, Properties props) throws IOException { - String packageFilesDir = "package-files/"; - - if(!new File(packageFilesDir).exists()) { - EditorLogger.error("package-files folder not found. Searching folder for IDE mode."); - - packageFilesDir = "src/dist/package-files/"; - if(!new File(packageFilesDir).exists()) { - EditorLogger.error(new File(packageFilesDir).getAbsolutePath() + " folder not found in IDE mode."); - return; - } - } - - - List args = new ArrayList(); - args.add("-f"); - args.add(packageFilesDir + buildFile); - args.add("-Dproject=" + projectDir); - args.add("-Ddist=" + distDir); - - StringBuilder sb = new StringBuilder(); - - for(Object key:props.keySet()) { - sb.setLength(0); - sb.append("-D").append(key).append("=").append(props.get(key)); - args.add(sb.toString()); - } - - args.add(target); - - List cp = new ArrayList(); -// cp.add(System.getProperty("java.class.path") ); - cp.add(packageFilesDir + "ant.jar"); - cp.add(packageFilesDir + "ant-launcher.jar"); - - Process p = runJavaProccess(ANT_MAIN_CLASS, cp, args); - - try { - p.waitFor(); - EditorLogger.debug("ANT EXIT VALUE: " + p.exitValue()); - - if(p.exitValue() == 1) { - throw new IOException("ERROR IN ANT PROCCESS"); - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - public static Process runJavaProccess(String mainClass, List classpathEntries, List args) throws IOException { - String javaRT = System.getProperty("java.home") + "/bin/java"; - String workingDirectory = "."; - - - List argumentsList = new ArrayList(); - argumentsList.add(javaRT); - - if(classpathEntries!=null && classpathEntries.size() > 0) { - argumentsList.add("-classpath"); - argumentsList.add(getClasspath(classpathEntries)); - } - - argumentsList.add(mainClass); - - if(args != null) - argumentsList.addAll(args); - - ProcessBuilder processBuilder = new ProcessBuilder( - argumentsList.toArray(new String[argumentsList.size()])); -// processBuilder.redirectErrorStream(true); - processBuilder.directory(new File(workingDirectory)); - processBuilder.inheritIO(); - - return processBuilder.start(); - } - - public static boolean runGradle(File workingDir, String parameters) { - String exec = workingDir.getAbsolutePath() + "/" + (System.getProperty("os.name").contains("Windows") ? "gradlew.bat": "gradlew"); - String command = exec + " " + parameters; - - EditorLogger.debug("Executing '" + command + "'"); - - try { - final ProcessBuilder pb = new ProcessBuilder(command.split(" ")).directory(workingDir); - - // TODO: READ OUTPUT FROM pb AND print in output stream - if(System.console() != null) - pb.inheritIO(); - - final Process process = pb.start(); - - process.waitFor(); - return process.exitValue() == 0; - } catch (Exception e) { - e.printStackTrace(); - return false; - } - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/Versions.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/Versions.java deleted file mode 100644 index 0c272e975..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/Versions.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.utils; - -import java.io.InputStream; -import java.util.Properties; - -public class Versions { - private static final String VERSION_PROP="version"; - private static final String LIBGDX_VERSION_PROP="libgdxVersion"; - private static final String ROBOVM_VERSION_PROP="roboVMVersion"; - private static final String BUILDTOOLS_VERSION_PROP="buildToolsVersion"; - private static final String ANDROID_API_LEVEL_PROP="androidAPILevel"; - private static final String GWT_VERSION_PROP = "gwtVersion"; - - public static final String PROPERTIES_FILENAME = "/versions.properties"; - - private static Properties config = null; - - private static String getProperty(String key, String defaultValue) { - if(config == null) { - config = new Properties(); - - try { - InputStream is = Versions.class.getResourceAsStream(PROPERTIES_FILENAME); - config.load(is); - } catch (Exception e) { - EditorLogger.error("ERROR LOADING VERSION FILE: " + e.getMessage()); - } - } - - return config.getProperty(key, defaultValue); - } - - public static String getVersion() { - return getProperty(VERSION_PROP,null); - } - - public static String getLibgdxVersion() { - return getProperty(LIBGDX_VERSION_PROP,null); - } - - public static String getRoboVMVersion() { - return getProperty(ROBOVM_VERSION_PROP,null); - } - - public static String getBuildToolsVersion() { - return getProperty(BUILDTOOLS_VERSION_PROP,null); - } - - public static String getAndroidAPILevel() { - return getProperty(ANDROID_API_LEVEL_PROP,null); - } - - public static String getGwtVersion() { - return getProperty(GWT_VERSION_PROP,null); - } - - public static void setBuildToolsVersion(String v) { - config.setProperty(BUILDTOOLS_VERSION_PROP, v); - } - - public static void setAndroidAPILevel(String v) { - config.setProperty(ANDROID_API_LEVEL_PROP, v); - } -} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/ZipUtils.java b/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/ZipUtils.java deleted file mode 100644 index ef98ed49f..000000000 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/ZipUtils.java +++ /dev/null @@ -1,156 +0,0 @@ -/******************************************************************************* - * Copyright 2014 Rafael Garcia Moreno. - * - * 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 com.bladecoder.engineeditor.utils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.zip.Deflater; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; - -public class ZipUtils { - // 4MB buffer - private static final byte[] BUFFER = new byte[4096 * 1024]; - - // copy input to output stream - private static void copy(InputStream input, OutputStream output) throws IOException { - int bytesRead; - while ((bytesRead = input.read(BUFFER)) != -1) { - output.write(BUFFER, 0, bytesRead); - } - } - - public static void mergeZIPs(String f[], String dest) throws Exception { - // Needed to avoid appending repeated entries. - HashMap destEntries = new HashMap(); - - // read the org zips - ZipFile fZip[] = new ZipFile[f.length]; - - for (int i = 0; i < fZip.length; i++) - fZip[i] = new ZipFile(f[i]); - - // write the dest zip - ZipOutputStream destZip = new ZipOutputStream(new FileOutputStream(dest)); - - // copy contents from f zip to the dest zip - - for (ZipFile z : fZip) { - Enumeration entries = z.entries(); - while (entries.hasMoreElements()) { - ZipEntry e = entries.nextElement(); - - String name = e.getName(); - if (destEntries.get(name) == null) { - destEntries.put(name, name); - EditorLogger.debug("copy: " + e.getName()); - destZip.putNextEntry(e); - EditorLogger.debug("putnextEntry done"); - if (!e.isDirectory()) { - copy(z.getInputStream(e), destZip); - } - destZip.closeEntry(); - } - } - } - - EditorLogger.debug("appending done "); - - // close - for (ZipFile z : fZip) { - z.close(); - } - - destZip.close(); - } - - public static void packZip(List sources, File output) throws IOException { - EditorLogger.debug("Packaging to " + output.getName()); - ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(output)); - zipOut.setLevel(Deflater.DEFAULT_COMPRESSION); - - for (File source : sources) { - if (source.isDirectory()) { - zipDir(zipOut, "", source); - } else { - zipFile(zipOut, "", source); - } - } - zipOut.flush(); - zipOut.close(); - EditorLogger.debug("Done"); - } - - private static String buildPath(String path, String file) { - if (path == null || path.isEmpty()) { - return file; - } else { - return path + "/" + file; - } - } - - private static void zipDir(ZipOutputStream zos, String path, File dir) throws IOException { - if (!dir.canRead()) { - EditorLogger.error("Cannot read " + dir.getCanonicalPath() - + " (maybe because of permissions)"); - return; - } - - File[] files = dir.listFiles(); - path = buildPath(path, dir.getName()); - EditorLogger.debug("Adding Directory " + path); - - for (File source : files) { - if (source.isDirectory()) { - zipDir(zos, path, source); - } else { - zipFile(zos, path, source); - } - } - - EditorLogger.debug("Leaving Directory " + path); - } - - private static void zipFile(ZipOutputStream zos, String path, File file) throws IOException { - if (!file.canRead()) { - EditorLogger.error("Cannot read " + file.getCanonicalPath() - + " (maybe because of permissions)"); - return; - } - - EditorLogger.debug("Compressing " + file.getName()); - zos.putNextEntry(new ZipEntry(buildPath(path, file.getName()))); - - FileInputStream fis = new FileInputStream(file); - - byte[] buffer = new byte[4092]; - int byteCount = 0; - while ((byteCount = fis.read(buffer)) != -1) { - zos.write(buffer, 0, byteCount); - } - - fis.close(); - zos.closeEntry(); - } -} diff --git a/adventure-composer/src/main/resources/images/icons.png b/adventure-composer/src/main/resources/images/icons.png deleted file mode 100644 index dddde0db4..000000000 Binary files a/adventure-composer/src/main/resources/images/icons.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/android/AndroidManifest.xml b/adventure-composer/src/main/resources/projectTmpl/android/AndroidManifest.xml deleted file mode 100644 index 0621ea55f..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/android/AndroidManifest.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/BladeEngine.properties b/adventure-composer/src/main/resources/projectTmpl/android/assets/BladeEngine.properties deleted file mode 100644 index 0f2fc9068..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/android/assets/BladeEngine.properties +++ /dev/null @@ -1,8 +0,0 @@ -title=Blade Engine Adventure -pie_mode.desktop=false -inventory_pos=down -debug=false -#load_gamestate= -#play_recording=full -#force_res=1920 - diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/model/00.chapter b/adventure-composer/src/main/resources/projectTmpl/android/assets/model/00.chapter deleted file mode 100644 index b2a095c45..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/android/assets/model/00.chapter +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/model/world.properties b/adventure-composer/src/main/resources/projectTmpl/android/assets/model/world.properties deleted file mode 100644 index b1c67c358..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/android/assets/model/world.properties +++ /dev/null @@ -1,5 +0,0 @@ -#world.xml -#Fri Sep 20 11:21:23 CEST 2013 -default.use.0.text=I don't know what to do with that -default.lookat.0.text=Nothing interesting here -default.pickup.0.text=I can not take that diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/model/world.xml b/adventure-composer/src/main/resources/projectTmpl/android/assets/model/world.xml deleted file mode 100644 index e8bbada8b..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/android/assets/model/world.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/model/world_es.properties b/adventure-composer/src/main/resources/projectTmpl/android/assets/model/world_es.properties deleted file mode 100644 index 18ee3faf1..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/android/assets/model/world_es.properties +++ /dev/null @@ -1,4 +0,0 @@ -#Mon Apr 29 15:12:39 CEST 2013 -default.use.0.text=No se que hacer con esto -default.lookat.0.text=Nada interesante -default.pickup.0.text=No puedo coger eso diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/helpDesktop.png b/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/helpDesktop.png deleted file mode 100644 index fd127d022..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/helpDesktop.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/helpDesktop_es.png b/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/helpDesktop_es.png deleted file mode 100644 index bfc107447..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/helpDesktop_es.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/helpPie.png b/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/helpPie.png deleted file mode 100644 index a59cca9c5..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/helpPie.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/helpPie_es.png b/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/helpPie_es.png deleted file mode 100644 index 2e4e38e29..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/helpPie_es.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/ui.atlas b/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/ui.atlas deleted file mode 100644 index 24a4ed80d..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/ui.atlas +++ /dev/null @@ -1,191 +0,0 @@ - -ui.png -size: 1005,1005 -format: RGBA8888 -filter: MipMapLinearNearest,Nearest -repeat: none -back - rotate: false - xy: 349, 770 - size: 235, 235 - orig: 235, 235 - offset: 0, 0 - index: -1 -border_black_rect4 - rotate: false - xy: 955, 596 - size: 31, 31 - split: 5, 5, 5, 4 - orig: 31, 31 - offset: 0, 0 - index: -1 -border_rect2 - rotate: false - xy: 955, 631 - size: 32, 32 - split: 2, 2, 2, 2 - orig: 32, 32 - offset: 0, 0 - index: -1 -border_rect4 - rotate: false - xy: 800, 108 - size: 32, 32 - split: 4, 4, 5, 5 - orig: 32, 32 - offset: 0, 0 - index: -1 -bubblepointer - rotate: false - xy: 800, 144 - size: 79, 51 - orig: 79, 51 - offset: 0, 0 - index: -1 -circle - rotate: false - xy: 648, 47 - size: 148, 148 - orig: 148, 148 - offset: 0, 0 - index: -1 -circle_border - rotate: false - xy: 4, 347 - size: 312, 312 - orig: 312, 312 - offset: 0, 0 - index: -1 -circle_button - rotate: false - xy: 4, 663 - size: 341, 342 - orig: 341, 342 - offset: 0, 0 - index: -1 -config - rotate: false - xy: 529, 327 - size: 200, 200 - orig: 200, 200 - offset: 0, 0 - index: -1 -credits - rotate: false - xy: 4, 108 - size: 235, 235 - orig: 235, 235 - offset: 0, 0 - index: -1 -help - rotate: false - xy: 588, 770 - size: 235, 235 - orig: 235, 235 - offset: 0, 0 - index: -1 -hotspotpointer - rotate: false - xy: 320, 322 - size: 205, 205 - orig: 205, 205 - offset: 0, 0 - index: -1 -inventory - rotate: false - xy: 827, 834 - size: 171, 171 - orig: 171, 171 - offset: 0, 0 - index: -1 -inventory_plain - rotate: false - xy: 169, 7 - size: 136, 97 - orig: 136, 97 - offset: 0, 0 - index: -1 -leave - rotate: false - xy: 648, 199 - size: 197, 124 - orig: 197, 124 - offset: 0, 0 - index: -1 -left - rotate: false - xy: 243, 118 - size: 200, 200 - orig: 200, 200 - offset: 0, 0 - index: -1 -lookat - rotate: false - xy: 4, 4 - size: 161, 100 - orig: 161, 100 - offset: 0, 0 - index: -1 -menu - rotate: false - xy: 827, 667 - size: 163, 163 - orig: 163, 163 - offset: 0, 0 - index: -1 -pickup - rotate: false - xy: 849, 207 - size: 103, 116 - orig: 103, 116 - offset: 0, 0 - index: -1 -pie - rotate: false - xy: 447, 121 - size: 197, 197 - orig: 197, 197 - offset: 0, 0 - index: -1 -pointer - rotate: false - xy: 827, 540 - size: 124, 123 - orig: 124, 123 - offset: 0, 0 - index: -1 -quit - rotate: false - xy: 349, 531 - size: 235, 235 - orig: 235, 235 - offset: 0, 0 - index: -1 -reload - rotate: false - xy: 588, 531 - size: 235, 235 - orig: 235, 235 - offset: 0, 0 - index: -1 -right - rotate: false - xy: 733, 327 - size: 200, 200 - orig: 200, 200 - offset: 0, 0 - index: -1 -talkto - rotate: false - xy: 309, 10 - size: 125, 104 - orig: 125, 104 - offset: 0, 0 - index: -1 -white_pixel - rotate: false - xy: 1002, 1002 - size: 3, 3 - orig: 3, 3 - offset: 0, 0 - index: -1 diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/ui.png b/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/ui.png deleted file mode 100644 index da1ddb528..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/1/ui.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/ArchitectsDaughter_fix.ttf b/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/ArchitectsDaughter_fix.ttf deleted file mode 100644 index 52db80429..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/ArchitectsDaughter_fix.ttf and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/credits.txt b/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/credits.txt deleted file mode 100644 index 80967556d..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/credits.txt +++ /dev/null @@ -1,19 +0,0 @@ -t#SCRIPT -RAFAEL GARCÍA -t#CHAPTER DESIGN -ALMUDENA CASTILLEJO -RAFAEL GARCÍA -t#BACKGROUNDS -ALMUDENA CASTILLEJO -RAFAEL GARCÍA -t#PROGRAMMING -RAFAEL GARCÍA -t#MUSIC -Moonlight Sonata Op. 27 No. 2 Moonlight Sonata -Performed by Paul Pitman - musopen.org -t#SOUND FX -freesound.org -s#120 -i#libgdx_logo.png -s#250 -i#blade_logo.png diff --git a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/ui.json b/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/ui.json deleted file mode 100644 index 9f8131298..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/android/assets/ui/ui.json +++ /dev/null @@ -1,83 +0,0 @@ -{ -com.badlogic.gdx.graphics.g2d.BitmapFont: { - default: {file: Roboto-Regular.ttf, size: 20}, - debug: {file: Roboto-Regular.ttf, size: 15}, - big-font: {file: Roboto-Black.ttf, size: 35}, - title-font: {file: Roboto-Black.ttf, size: 60}, - dialog-font: {file: ArchitectsDaughter_fix.ttf, size: 20}, - text-manager-font: {file: ArchitectsDaughter_fix.ttf, size: 18}, - desc: {file: Ubuntu-M.ttf, size: 16}, - credits-title: {file: Ubuntu-M.ttf, size: 20}, - credits: {file: Ubuntu-M.ttf, size: 30} - }, -com.badlogic.gdx.graphics.Color: { - green: { a: 1, b: 0, g: 1, r: 0 }, - white: { a: 1, b: 1, g: 1, r: 1 }, - red: { a: 1, b: 0, g: 0, r: 1 }, - black: { a: 1, b: 0, g: 0, r: 0 }, - dark-grey: { a: 1, b: 0.25, g: 0.25, r: 0.25 }, - light-grey: { a: 1, b: 0.75, g: 0.75, r: 0.75 }, - grey: { a: 1, b: 0.5, g: 0.5, r: 0.5 }, - text-dark: { a: 1, b: 1, g: 1, r: 1 }, - indigo: { r: 0.24, g: 0.31, b: 0.70, a: 1 }, - indigo-light: { r: 0.50, g: 0.55, b: 0.82, a: 1 }, - red500: { r: 0.90, g: 0.11, b: 0.13, a: 1 }, - red-dark: { r: 0.71, g: 0.04, b: 0.06, a: 1 }, - red-light: { r: 0.99, g: 0.45, b: 0.47, a: 1 }, - black-trans: { r: 0.1, g: 0.1, b: 0.1, a: 0.7 } -}, -com.badlogic.gdx.scenes.scene2d.ui.Skin$TintedDrawable: { - black08: { name: white_pixel, color: { r: 0, g: 0, b: 0, a: 0.8 } }, - white: { name: white_pixel, color: white }, - grey: { name: white_pixel, color: grey}, - dark-grey: { name: white_pixel, color: dark-grey}, - red: { name: white_pixel, color: { r: 0.5, g: 0, b: 0, a: 1 }}, - circle: { name: circle_button, color: red-dark}, - circle-light: { name: circle_button, color: red500}, - circle-border: { name: circle_border, color: black-trans}, - circle-border-light: { name: circle_border, color: light-grey}, - border-rect-grey: { name: border_rect4, color: light-grey}, - border-rect-dark-grey: { name: border_rect2, color: { a: 1, b: 0.6, g: 0.6, r: 0.6 }}, -}, -com.badlogic.gdx.scenes.scene2d.ui.ImageButton$ImageButtonStyle: { - pie_lookat: {up:circle-border, down: circle-border-light, imageUp: lookat}, - pie_pickup: {up:circle-border, down: circle-border-light, imageUp: pickup}, - pie_talkto: {up:circle-border, down: circle-border-light, imageUp: talkto}, - inventory: {up:inventory}, - menu: {up:circle, down: circle-light, imageUp: menu} -}, -com.bladecoder.engine.ui.InventoryUI$InventoryUIStyle: { - default: {background: border-rect-grey, itemBackground: border-rect-dark-grey, menuButtonStyle: menu} -}, -com.badlogic.gdx.scenes.scene2d.ui.TextButton$TextButtonStyle: { - default: { font: default, up: grey, fontColor: white , downFontColor: grey, overFontColor: light-grey, disabledFontColor: dark-grey}, - menu: { font: big-font, fontColor: white , downFontColor: grey, overFontColor: light-grey, disabledFontColor: dark-grey} -}, -com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle: { - default: { font: default, fontColor: white}, - title: { font: title-font, fontColor: white}, -}, - -com.bladecoder.engine.ui.DialogUI$DialogUIStyle: { - default: {background: black08, font: dialog-font, fontColor: white, overFontColor: light-grey} -}, - -com.bladecoder.engine.ui.TextManagerUI$TextManagerUIStyle: { - default: {rectBackground: border_black_rect4, talkBackground: white, font: text-manager-font, talkBubble: bubblepointer} -}, -com.badlogic.gdx.scenes.scene2d.ui.TextField$TextFieldStyle: { - default: { selection: grey, background: dark-grey, focusedBackground: dark-grey, disabledBackground: grey, font: default, fontColor: white, focusedFontColor: text-dark, disabledFontColor: text-dark, cursor: white, messageFont: default, messageFontColor: text-dark } -}, -com.badlogic.gdx.scenes.scene2d.ui.ScrollPane$ScrollPaneStyle: { - default: {vScroll: dark-grey, hScrollKnob: dark-grey, background: grey, hScroll: dark-grey, vScrollKnob: dark-grey, corner: grey}, - opaque: { vScroll: dark-grey, hScrollKnob: dark-grey, background: grey, hScroll: dark-grey, vScrollKnob: dark-grey, corner: grey} - }, -com.badlogic.gdx.scenes.scene2d.ui.List$ListStyle: { - default: { fontColorUnselected: text-dark, selection: grey, fontColorSelected: text-dark, font: default }, - opaque: { fontColorUnselected: text-dark, selection: grey, fontColorSelected: text-dark, font: default } - }, - -com.badlogic.gdx.scenes.scene2d.ui.SelectBox$SelectBoxStyle: { - default: { background: dark-grey, backgroundOver: dark-grey, backgroundOpen: dark-grey, listStyle: default, scrollStyle: opaque, font: default, fontColor: white }, -} -} diff --git a/adventure-composer/src/main/resources/projectTmpl/android/build.gradle b/adventure-composer/src/main/resources/projectTmpl/android/build.gradle deleted file mode 100644 index 62dc8352f..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/android/build.gradle +++ /dev/null @@ -1,138 +0,0 @@ -android { - buildToolsVersion "%BUILD_TOOLS_VERSION%" - compileSdkVersion %API_LEVEL% - sourceSets { - main { - manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = ['src'] - aidl.srcDirs = ['src'] - renderscript.srcDirs = ['src'] - res.srcDirs = ['res'] - assets.srcDirs = ['assets'] - } - - instrumentTest.setRoot('tests') - - if(project.hasProperty('keystore')) { - signingConfigs { - release { - storeFile file(project.keystore) - storePassword project.storePassword - keyAlias project.alias - keyPassword project.keyPassword - } - } - - buildTypes { - release { - signingConfig signingConfigs.release - } - } - } - } -} - -// needed to add JNI shared libraries to APK when compiling on CLI -tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask -> - pkgTask.jniFolders = new HashSet() - pkgTask.jniFolders.add(new File(projectDir, 'libs')) -} - -// called every time gradle gets executed, takes the native dependencies of -// the natives configuration, and extracts them to the proper libs/ folders -// so they get packed with the APK. -task copyAndroidNatives() { - file("libs/armeabi/").mkdirs(); - file("libs/armeabi-v7a/").mkdirs(); - file("libs/x86/").mkdirs(); - - configurations.natives.files.each { jar -> - def outputDir = null - if(jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a") - if(jar.name.endsWith("natives-armeabi.jar")) outputDir = file("libs/armeabi") - if(jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86") - if(outputDir != null) { - copy { - from zipTree(jar) - into outputDir - include "*.so" - } - } - } -} - -task run(type: Exec) { - def path - def localProperties = project.file("../local.properties") - if (localProperties.exists()) { - Properties properties = new Properties() - localProperties.withInputStream { instr -> - properties.load(instr) - } - def sdkDir = properties.getProperty('sdk.dir') - if (sdkDir) { - path = sdkDir - } else { - path = "$System.env.ANDROID_HOME" - } - } else { - path = "$System.env.ANDROID_HOME" - } - - def adb = path + "/platform-tools/adb" - commandLine "$adb", 'shell', 'am', 'start', '-n', '%PACKAGE%.android/%PACKAGE%.android.AndroidLauncher' -} - -// sets up the Android Eclipse project, using the old Ant based build. -eclipse { - // need to specify Java source sets explicitely, SpringSource Gradle Eclipse plugin - // ignores any nodes added in classpath.file.withXml - sourceSets { - main { - java.srcDirs "src", 'gen' - } - } - - jdt { - sourceCompatibility = 1.6 - targetCompatibility = 1.6 - } - - classpath { - plusConfigurations += [ project.configurations.compile ] - containers 'com.android.ide.eclipse.adt.ANDROID_FRAMEWORK', 'com.android.ide.eclipse.adt.LIBRARIES' - } - - project { - name = appName + "-android" - natures 'com.android.ide.eclipse.adt.AndroidNature' - buildCommands.clear(); - buildCommand "com.android.ide.eclipse.adt.ResourceManagerBuilder" - buildCommand "com.android.ide.eclipse.adt.PreCompilerBuilder" - buildCommand "org.eclipse.jdt.core.javabuilder" - buildCommand "com.android.ide.eclipse.adt.ApkBuilder" - } -} - -// sets up the Android Idea project, using the old Ant based build. -idea { - module { - sourceDirs += file("src"); - scopes = [ COMPILE: [plus:[project.configurations.compile]]] - - iml { - withXml { - def node = it.asNode() - def builder = NodeBuilder.newInstance(); - builder.current = node; - builder.component(name: "FacetManager") { - facet(type: "android", name: "Android") { - configuration { - option(name: "UPDATE_PROPERTY_FILES", value:"true") - } - } - } - } - } - } -} \ No newline at end of file diff --git a/adventure-composer/src/main/resources/projectTmpl/android/ic_launcher-web.png b/adventure-composer/src/main/resources/projectTmpl/android/ic_launcher-web.png deleted file mode 100644 index c863b75be..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/android/ic_launcher-web.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/android/project.properties b/adventure-composer/src/main/resources/projectTmpl/android/project.properties deleted file mode 100644 index 4ab125693..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/android/project.properties +++ /dev/null @@ -1,14 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system edit -# "ant.properties", and override values to adapt the script to your -# project structure. -# -# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): -#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt - -# Project target. -target=android-19 diff --git a/adventure-composer/src/main/resources/projectTmpl/android/res/drawable-hdpi/ic_launcher.png b/adventure-composer/src/main/resources/projectTmpl/android/res/drawable-hdpi/ic_launcher.png deleted file mode 100644 index 09d798646..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/android/res/drawable-hdpi/ic_launcher.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/android/res/drawable-mdpi/ic_launcher.png b/adventure-composer/src/main/resources/projectTmpl/android/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index df54068b0..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/android/res/drawable-mdpi/ic_launcher.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/android/res/drawable-xhdpi/ic_launcher.png b/adventure-composer/src/main/resources/projectTmpl/android/res/drawable-xhdpi/ic_launcher.png deleted file mode 100644 index 1c24992c7..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/android/res/drawable-xhdpi/ic_launcher.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/android/res/drawable-xxhdpi/ic_launcher.png b/adventure-composer/src/main/resources/projectTmpl/android/res/drawable-xxhdpi/ic_launcher.png deleted file mode 100644 index 055c737ad..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/android/res/drawable-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/android/src/AndroidLauncher b/adventure-composer/src/main/resources/projectTmpl/android/src/AndroidLauncher deleted file mode 100644 index 0513e8d62..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/android/src/AndroidLauncher +++ /dev/null @@ -1,25 +0,0 @@ -package %PACKAGE%.android; - -import com.bladecoder.engine.BladeEngine; - -import android.os.Bundle; -import android.view.WindowManager; - -import com.badlogic.gdx.backends.android.AndroidApplication; -import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration; - -public class AndroidLauncher extends AndroidApplication { - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration(); - cfg.useAccelerometer = false; - cfg.useCompass = false; - cfg.numSamples = 2; - - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - - initialize(new BladeEngine(), cfg); - } -} \ No newline at end of file diff --git a/adventure-composer/src/main/resources/projectTmpl/core/build.gradle b/adventure-composer/src/main/resources/projectTmpl/core/build.gradle deleted file mode 100644 index 03cd1bea2..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/core/build.gradle +++ /dev/null @@ -1,11 +0,0 @@ -apply plugin: "java" - -sourceCompatibility = 1.6 -[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' - -sourceSets.main.java.srcDirs = [ "src/" ] - - -eclipse.project { - name = appName + "-core" -} diff --git a/adventure-composer/src/main/resources/projectTmpl/desktop/blade_engine.html b/adventure-composer/src/main/resources/projectTmpl/desktop/blade_engine.html deleted file mode 100644 index 7d9ce5dbf..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/desktop/blade_engine.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - BladeEngine - - - -

- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - \ No newline at end of file diff --git a/adventure-composer/src/main/resources/projectTmpl/desktop/build.gradle b/adventure-composer/src/main/resources/projectTmpl/desktop/build.gradle deleted file mode 100644 index 288fed43f..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/desktop/build.gradle +++ /dev/null @@ -1,53 +0,0 @@ -apply plugin: "java" - -sourceCompatibility = 1.6 -sourceSets.main.java.srcDirs = [ "src/" ] -sourceSets.main.resources.srcDirs = [ "src/" ] - -project.ext.mainClassName = "%PACKAGE%.desktop.DesktopLauncher" -project.ext.assetsDir = new File("../%ASSET_PATH%"); - -task run(dependsOn: classes, type: JavaExec) { - main = project.mainClassName - classpath = sourceSets.main.runtimeClasspath - standardInput = System.in - workingDir = project.assetsDir - ignoreExitValue = true - - if (project.hasProperty("appArgs") ) { - args Eval.me(appArgs) - } -} - -task dist(type: Jar) { - baseName = appName + "-desktop" - - from files(sourceSets.main.output.classesDir) - from files(sourceSets.main.output.resourcesDir) - from {configurations.compile.collect {zipTree(it)}} - from files(project.assetsDir); - - manifest { - attributes 'Main-Class': project.mainClassName - } -} - -dist.dependsOn classes - -eclipse { - project { - name = appName + "-desktop" - linkedResource name: 'assets', type: '2', location: 'PARENT-1-PROJECT_LOC/%ASSET_PATH%' - } -} - -task afterEclipseImport(description: "Post processing after project generation", group: "IDE") { - doLast { - def classpath = new XmlParser().parse(file(".classpath")) - new Node(classpath, "classpathentry", [ kind: 'src', path: 'assets' ]); - def writer = new FileWriter(file(".classpath")) - def printer = new XmlNodePrinter(new PrintWriter(writer)) - printer.setPreserveWhitespace(true) - printer.print(classpath) - } -} \ No newline at end of file diff --git a/adventure-composer/src/main/resources/projectTmpl/desktop/src/Applet b/adventure-composer/src/main/resources/projectTmpl/desktop/src/Applet deleted file mode 100644 index f03ddac43..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/desktop/src/Applet +++ /dev/null @@ -1,13 +0,0 @@ -package com.bladecoder.engine.desktop; - -import com.bladecoder.engine.BladeEngine; - -import com.badlogic.gdx.backends.lwjgl.LwjglApplet; - -public class Applet extends LwjglApplet { - private static final long serialVersionUID = 1L; - - public Applet() { - super(new BladeEngine()); - } -} diff --git a/adventure-composer/src/main/resources/projectTmpl/desktop/src/DesktopLauncher b/adventure-composer/src/main/resources/projectTmpl/desktop/src/DesktopLauncher deleted file mode 100644 index e38b66154..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/desktop/src/DesktopLauncher +++ /dev/null @@ -1,160 +0,0 @@ -package %PACKAGE%.desktop; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.IntBuffer; -import java.util.Properties; - -import com.bladecoder.engine.BladeEngine; -import com.bladecoder.engine.util.Config; -import org.lwjgl.BufferUtils; -import org.lwjgl.LWJGLException; -import org.lwjgl.input.Cursor; -import org.lwjgl.input.Mouse; - -import com.badlogic.gdx.Files.FileType; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.backends.lwjgl.LwjglApplication; -import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; - -public class DesktopLauncher extends BladeEngine { - - private boolean fullscreen = true; - private LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration(); - - DesktopLauncher() { - Properties p = new Properties(); - - try { - InputStream s = DesktopLauncher.class.getResourceAsStream(Config.PROPERTIES_FILENAME); - if(s!=null) - p.load(s); - } catch (IOException e) { - } - - cfg.title = p.getProperty(Config.TITLE_PROP, "Blade Engine Adventure"); -// cfg.useGL30 = true; - - // cfg.width = World.getInstance().getWidth(); - // cfg.height = World.getInstance().getHeight(); - - cfg.width = 1920 / 2; - cfg.height = 1080 / 2; - - cfg.resizable = true; - cfg.samples = 2; - } - - public void run() { - if(DesktopLauncher.class.getResource("/icons/icon128.png")!=null) - cfg.addIcon("icons/icon128.png", FileType.Internal); - - if(DesktopLauncher.class.getResource("/icons/icon32.png")!=null) - cfg.addIcon("icons/icon32.png", FileType.Internal); - - if(DesktopLauncher.class.getResource("/icons/icon16.png")!=null) - cfg.addIcon("icons/icon16.png", FileType.Internal); - - new LwjglApplication(this, cfg); - } - - public void parseParams(String[] args) { - for (int i = 0; i < args.length; i++) { - String s = args[i]; - if (s.equals("-t")) { - if (i + 1 < args.length) { - i++; - setTestMode(args[i]); - } - } else if (s.equals("-p")) { - if (i + 1 < args.length) { - i++; - setPlayMode(args[i]); - } - } else if (s.equals("-chapter")) { - if (i + 1 < args.length) { - i++; - setChapter(args[i]); - } - } else if (s.equals("-f")) { - fullscreen = true; - - //cfg.fullscreen = true; - } else if (s.equals("-d")) { - setDebugMode(); - } else if (s.equals("-r")) { - setRestart(); - } else if (s.equals("-res")) { - if (i + 1 < args.length) { - i++; - forceResolution(args[i]); - } - } else if (s.equals("-w")) { - fullscreen = false; - } else if (s.equals("-l")) { - if (i + 1 < args.length) { - i++; - loadGameState(args[i]); - } - } else if (s.equals("-h")) { - usage(); - } else { - if(i == 0 && !s.startsWith("-")) continue; // When embeded JRE the 0 parameter is the app name - System.out.println("Unrecognized parameter: " + s); - usage(); - } - } - } - - - public void usage() { - System.out.println( - "Usage:\n" + - "-chapter chapter\tLoads the selected chapter\n" + - "-t scene_name\tStart test mode for the scene\n" + - "-p record_name\tPlay previusly recorded games\n" + - "-f\tSet fullscreen mode\n" + - "-w\tSet windowed mode\n" + - "-d\tShow debug messages\n" + - "-res width\tForce the resolution width\n" + - "-l game_state\tLoad the previusly saved game state\n" + - "-r\tRun the game from the begining\n" - ); - - System.exit(0); - } - - @Override - public void create() { - // Gdx.input.setCursorCatched(false); - if (fullscreen) - Gdx.graphics.setDisplayMode(Gdx.graphics.getDesktopDisplayMode()); - - hideCursor(); - - super.create(); - } - - private void hideCursor() { - Cursor emptyCursor; - - int min = org.lwjgl.input.Cursor.getMinCursorSize(); - IntBuffer tmp = BufferUtils.createIntBuffer(min * min); - try { - emptyCursor = new org.lwjgl.input.Cursor(min, min, min / 2, - min / 2, 1, tmp, null); - - Mouse.setNativeCursor(emptyCursor); - } catch (LWJGLException e) { - e.printStackTrace(); - } - - } - - public static void main(String[] args) { - DesktopLauncher game = new DesktopLauncher(); - game.parseParams(args); - game.run(); - } -} diff --git a/adventure-composer/src/main/resources/projectTmpl/desktop/src/icons/icon128.png b/adventure-composer/src/main/resources/projectTmpl/desktop/src/icons/icon128.png deleted file mode 100644 index 47a2dc96f..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/desktop/src/icons/icon128.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/desktop/src/icons/icon16.png b/adventure-composer/src/main/resources/projectTmpl/desktop/src/icons/icon16.png deleted file mode 100644 index 348db53c4..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/desktop/src/icons/icon16.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/desktop/src/icons/icon32.png b/adventure-composer/src/main/resources/projectTmpl/desktop/src/icons/icon32.png deleted file mode 100644 index 831b74e84..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/desktop/src/icons/icon32.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/gradle.properties b/adventure-composer/src/main/resources/projectTmpl/gradle.properties deleted file mode 100644 index fa55fd1e1..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.gradle.daemon=true -org.gradle.jvmargs=-Xms128m -Xmx512m -org.gradle.configureondemand=true \ No newline at end of file diff --git a/adventure-composer/src/main/resources/projectTmpl/gradle/wrapper/gradle-wrapper.jar b/adventure-composer/src/main/resources/projectTmpl/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index b979729db..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/gradlew b/adventure-composer/src/main/resources/projectTmpl/gradlew deleted file mode 100644 index 91a7e269e..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/adventure-composer/src/main/resources/projectTmpl/html/GdxDefinition b/adventure-composer/src/main/resources/projectTmpl/html/GdxDefinition deleted file mode 100644 index 395cd5985..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/html/GdxDefinition +++ /dev/null @@ -1,9 +0,0 @@ - - - -%GWT_INHERITS% - - - - - diff --git a/adventure-composer/src/main/resources/projectTmpl/html/GdxDefinitionSuperdev b/adventure-composer/src/main/resources/projectTmpl/html/GdxDefinitionSuperdev deleted file mode 100644 index 08822d347..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/html/GdxDefinitionSuperdev +++ /dev/null @@ -1,13 +0,0 @@ - - - -%GWT_INHERITS% - - - - - - - - - diff --git a/adventure-composer/src/main/resources/projectTmpl/html/build.gradle b/adventure-composer/src/main/resources/projectTmpl/html/build.gradle deleted file mode 100644 index 1d2d64eb9..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/html/build.gradle +++ /dev/null @@ -1,70 +0,0 @@ -apply plugin: "java" -apply plugin: "jetty" - -gwt { - gwtVersion='%GWT_VERSION%' // Should match the gwt version used for building the gwt backend - maxHeapSize="1G" // Default 256m is not enough for gwt compiler. GWT is HUNGRY - minHeapSize="1G" - - src = files(file("src/")) // Needs to be in front of "modules" below. - modules '%PACKAGE%.GdxDefinition' - devModules '%PACKAGE%.GdxDefinitionSuperdev' - project.webAppDirName = 'webapp' - - compiler { - strict = true; - enableClosureCompiler = true; - disableCastChecking = true; - } -} - -task draftRun(type: JettyRunWar) { - dependsOn draftWar - dependsOn.remove('war') - webApp=draftWar.archivePath - daemon=true -} - -task superDev(type: de.richsource.gradle.plugins.gwt.GwtSuperDev) { - dependsOn draftRun - doFirst { - gwt.modules = gwt.devModules - } -} - -task dist(dependsOn: [clean, compileGwt]) { - doLast { - file("build/dist").mkdirs() - copy { - from "build/gwt/out" - into "build/dist" - } - copy { - from "webapp" - into "build/dist" - } - copy { - from "war" - into "build/dist" - } - } -} - -draftWar { - from "war" -} - -task addSource << { - sourceSets.main.compileClasspath += files(project(':core').sourceSets.main.allJava.srcDirs) -} - -tasks.compileGwt.dependsOn(addSource) -tasks.draftCompileGwt.dependsOn(addSource) - -sourceCompatibility = 1.6 -sourceSets.main.java.srcDirs = [ "src/" ] - - -eclipse.project { - name = appName + "-html" -} diff --git a/adventure-composer/src/main/resources/projectTmpl/html/src/HtmlLauncher b/adventure-composer/src/main/resources/projectTmpl/html/src/HtmlLauncher deleted file mode 100644 index a6d0c092e..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/html/src/HtmlLauncher +++ /dev/null @@ -1,19 +0,0 @@ -package %PACKAGE%.client; - -import com.badlogic.gdx.ApplicationListener; -import com.badlogic.gdx.backends.gwt.GwtApplication; -import com.badlogic.gdx.backends.gwt.GwtApplicationConfiguration; -import com.bladecoder.engine.BladeEngine; - -public class HtmlLauncher extends GwtApplication { - - @Override - public GwtApplicationConfiguration getConfig () { - return new GwtApplicationConfiguration(480, 320); - } - - @Override - public ApplicationListener getApplicationListener () { - return new BladeEngine(); - } -} \ No newline at end of file diff --git a/adventure-composer/src/main/resources/projectTmpl/html/war/WEB-INF/web.xml b/adventure-composer/src/main/resources/projectTmpl/html/war/WEB-INF/web.xml deleted file mode 100644 index 4301df248..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/html/war/WEB-INF/web.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/adventure-composer/src/main/resources/projectTmpl/html/war/index b/adventure-composer/src/main/resources/projectTmpl/html/war/index deleted file mode 100644 index f159de476..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/html/war/index +++ /dev/null @@ -1,32 +0,0 @@ - - - - %APP_NAME% - - - - - - - - SuperDev Refresh -
- - - - - \ No newline at end of file diff --git a/adventure-composer/src/main/resources/projectTmpl/html/war/refresh.png b/adventure-composer/src/main/resources/projectTmpl/html/war/refresh.png deleted file mode 100644 index 24a48f1cc..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/html/war/refresh.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/html/war/soundmanager2-jsmin.js b/adventure-composer/src/main/resources/projectTmpl/html/war/soundmanager2-jsmin.js deleted file mode 100644 index b6af93d80..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/html/war/soundmanager2-jsmin.js +++ /dev/null @@ -1,110 +0,0 @@ -/** @license - - - SoundManager 2: JavaScript Sound for the Web - ---------------------------------------------- - http://schillmania.com/projects/soundmanager2/ - - Copyright (c) 2007, Scott Schiller. All rights reserved. - Code provided under the BSD License: - http://schillmania.com/projects/soundmanager2/license.txt - - V2.97a.20130512 -*/ -(function(h,g){function fa(fa,wa){function ga(b){return c.preferFlash&&H&&!c.ignoreFlash&&c.flash[b]!==g&&c.flash[b]}function s(b){return function(d){var e=this._s;!e||!e._a?(e&&e.id?c._wD(e.id+": Ignoring "+d.type):c._wD(rb+"Ignoring "+d.type),d=null):d=b.call(this,d);return d}}this.setupOptions={url:fa||null,flashVersion:8,debugMode:!0,debugFlash:!1,useConsole:!0,consoleOnly:!0,waitForWindowLoad:!1,bgColor:"#ffffff",useHighPerformance:!1,flashPollingInterval:null,html5PollingInterval:null,flashLoadTimeout:1E3, -wmode:null,allowScriptAccess:"always",useFlashBlock:!1,useHTML5Audio:!0,html5Test:/^(probably|maybe)$/i,preferFlash:!0,noSWFCache:!1,idPrefix:"sound"};this.defaultOptions={autoLoad:!1,autoPlay:!1,from:null,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onposition:null,onstop:null,onfailure:null,onfinish:null,multiShot:!0,multiShotEvents:!1,position:null,pan:0,stream:!0,to:null,type:null,usePolicyFile:!1,volume:100};this.flash9Options={isMovieStar:null, -usePeakData:!1,useWaveformData:!1,useEQData:!1,onbufferchange:null,ondataerror:null};this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,duration:null};this.audioFormats={mp3:{type:['audio/mpeg; codecs\x3d"mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:!0},mp4:{related:["aac","m4a","m4b"],type:['audio/mp4; codecs\x3d"mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:!1},ogg:{type:["audio/ogg; codecs\x3dvorbis"],required:!1}, -opus:{type:["audio/ogg; codecs\x3dopus","audio/opus"],required:!1},wav:{type:['audio/wav; codecs\x3d"1"',"audio/wav","audio/wave","audio/x-wav"],required:!1}};this.movieID="sm2-container";this.id=wa||"sm2movie";this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.versionNumber="V2.97a.20130512";this.altURL=this.movieURL=this.version=null;this.enabled=this.swfLoaded=!1;this.oMC=null;this.sounds={};this.soundIDs=[];this.didFlashBlock=this.muted=!1;this.filePattern=null;this.filePatterns= -{flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.features={buffering:!1,peakData:!1,waveformData:!1,eqData:!1,movieStar:!1};this.sandbox={type:null,types:{remote:"remote (domain-based) rules",localWithFile:"local with file access (no internet access)",localWithNetwork:"local with network (internet access only, no local access)",localTrusted:"local, trusted (local+internet access)"},description:null,noRemote:null,noLocal:null};this.html5={usingFlash:null};this.flash={};this.ignoreFlash=this.html5Only= -!1;var Ua,c=this,Va=null,k=null,rb="HTML5::",A,t=navigator.userAgent,U=h.location.href.toString(),m=document,xa,Wa,ya,n,F=[],za=!0,C,V=!1,W=!1,q=!1,y=!1,ha=!1,p,sb=0,X,B,Aa,O,Ba,M,P,Q,Xa,Ca,ia,I,ja,Da,R,Ea,Y,ka,la,S,Ya,Fa,Za=["log","info","warn","error"],$a,Ga,ab,Z=null,Ha=null,r,Ia,T,bb,ma,na,J,v,$=!1,Ja=!1,cb,db,eb,oa=0,aa=null,pa,N=[],qa,u=null,fb,ra,ba,K,sa,Ka,gb,w,hb=Array.prototype.slice,E=!1,La,H,Ma,ib,G,jb,Na,ta,kb=0,ca=t.match(/(ipad|iphone|ipod)/i),lb=t.match(/android/i),L=t.match(/msie/i), -tb=t.match(/webkit/i),ua=t.match(/safari/i)&&!t.match(/chrome/i),Oa=t.match(/opera/i),ub=t.match(/firefox/i),Pa=t.match(/(mobile|pre\/|xoom)/i)||ca||lb,Qa=!U.match(/usehtml5audio/i)&&!U.match(/sm2\-ignorebadua/i)&&ua&&!t.match(/silk/i)&&t.match(/OS X 10_6_([3-7])/i),da=h.console!==g&&console.log!==g,Ra=m.hasFocus!==g?m.hasFocus():null,va=ua&&(m.hasFocus===g||!m.hasFocus()),mb=!va,nb=/(mp3|mp4|mpa|m4a|m4b)/i,ea=m.location?m.location.protocol.match(/http/i):null,ob=!ea?"http://":"",pb=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i, -qb="mpeg4 aac flv mov mp4 m4v f4v m4a m4b mp4v 3gp 3g2".split(" "),vb=RegExp("\\.("+qb.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.useAltURL=!ea;var Sa;try{Sa=Audio!==g&&(Oa&&opera!==g&&10>opera.version()?new Audio(null):new Audio).canPlayType!==g}catch(wb){Sa=!1}this.hasHTML5=Sa;this.setup=function(b){var d=!c.url;b!==g&&(q&&u&&c.ok()&&(b.flashVersion!==g||b.url!==g||b.html5Test!==g))&&J(r("setupLate"));Aa(b);b&&(d&&(Y&&b.url!==g)&&c.beginDelayedInit(), -!Y&&(b.url!==g&&"complete"===m.readyState)&&setTimeout(R,1));return c};this.supported=this.ok=function(){return u?q&&!y:c.useHTML5Audio&&c.hasHTML5};this.getMovie=function(c){return A(c)||m[c]||h[c]};this.createSound=function(b,d){function e(){f=ma(f);c.sounds[f.id]=new Ua(f);c.soundIDs.push(f.id);return c.sounds[f.id]}var a,f;a=null;a="soundManager.createSound(): "+r(!q?"notReady":"notOK");if(!q||!c.ok())return J(a),!1;d!==g&&(b={id:b,url:d});f=B(b);f.url=pa(f.url);void 0===f.id&&(f.id=c.setupOptions.idPrefix+ -kb++);f.id.toString().charAt(0).match(/^[0-9]$/)&&c._wD("soundManager.createSound(): "+r("badID",f.id),2);c._wD("soundManager.createSound(): "+f.id+(f.url?" ("+f.url+")":""),1);if(v(f.id,!0))return c._wD("soundManager.createSound(): "+f.id+" exists",1),c.sounds[f.id];if(ra(f))a=e(),c._wD(f.id+": Using HTML5"),a._setup_html5(f);else{if(c.html5Only)return c._wD(f.id+": No HTML5 support for this sound, and no Flash. Exiting."),e();if(c.html5.usingFlash&&f.url&&f.url.match(/data\:/i))return c._wD(f.id+ -": data: URIs not supported via Flash. Exiting."),e();8a.instanceCount?(m(),e=a._setup_html5(),a.setPosition(a._iO.position),e.play()):(c._wD(a.id+": Cloning Audio() for instance #"+a.instanceCount+"..."),l=new Audio(a._iO.url),z=function(){w.remove(l,"onended",z);a._onfinish(a);sa(l);l=null},h=function(){w.remove(l,"canplay",h);try{l.currentTime=a._iO.position/1E3}catch(c){J(a.id+": multiShot play() failed to apply position of "+a._iO.position/1E3)}l.play()},w.add(l,"ended",z),a._iO.position? -w.add(l,"canplay",h):l.play()):(x=k._start(a.id,a._iO.loops||1,9===n?a.position:a.position/1E3,a._iO.multiShot||!1),9===n&&!x&&(c._wD(e+"No sound hardware, or 32-sound ceiling hit",2),a._iO.onplayerror&&a._iO.onplayerror.apply(a)))}return a};this.stop=function(b){var d=a._iO;1===a.playState&&(c._wD(a.id+": stop()"),a._onbufferchange(0),a._resetOnPosition(0),a.paused=!1,a.isHTML5||(a.playState=0),Ta(),d.to&&a.clearOnPosition(d.to),a.isHTML5?a._a&&(b=a.position,a.setPosition(0),a.position=b,a._a.pause(), -a.playState=0,a._onTimer(),l()):(k._stop(a.id,b),d.serverURL&&a.unload()),a.instanceCount=0,a._iO={},d.onstop&&d.onstop.apply(a));return a};this.setAutoPlay=function(b){c._wD(a.id+": Autoplay turned "+(b?"on":"off"));a._iO.autoPlay=b;a.isHTML5||(k._setAutoPlay(a.id,b),b&&(!a.instanceCount&&1===a.readyState)&&(a.instanceCount++,c._wD(a.id+": Incremented instance count to "+a.instanceCount)))};this.getAutoPlay=function(){return a._iO.autoPlay};this.setPosition=function(b){b===g&&(b=0);var d=a.isHTML5? -Math.max(b,0):Math.min(a.duration||a._iO.duration,Math.max(b,0));a.position=d;b=a.position/1E3;a._resetOnPosition(a.position);a._iO.position=d;if(a.isHTML5){if(a._a){if(a._html5_canplay){if(a._a.currentTime!==b){c._wD(a.id+": setPosition("+b+")");try{a._a.currentTime=b,(0===a.playState||a.paused)&&a._a.pause()}catch(e){c._wD(a.id+": setPosition("+b+") failed: "+e.message,2)}}}else if(b)return c._wD(a.id+": setPosition("+b+"): Cannot seek yet, sound not ready",2),a;a.paused&&a._onTimer(!0)}}else b= -9===n?a.position:b,a.readyState&&2!==a.readyState&&k._setPosition(a.id,b,a.paused||!a.playState,a._iO.multiShot);return a};this.pause=function(b){if(a.paused||0===a.playState&&1!==a.readyState)return a;c._wD(a.id+": pause()");a.paused=!0;a.isHTML5?(a._setup_html5().pause(),l()):(b||b===g)&&k._pause(a.id,a._iO.multiShot);a._iO.onpause&&a._iO.onpause.apply(a);return a};this.resume=function(){var b=a._iO;if(!a.paused)return a;c._wD(a.id+": resume()");a.paused=!1;a.playState=1;a.isHTML5?(a._setup_html5().play(), -m()):(b.isMovieStar&&!b.serverURL&&a.setPosition(a.position),k._pause(a.id,b.multiShot));!s&&b.onplay?(b.onplay.apply(a),s=!0):b.onresume&&b.onresume.apply(a);return a};this.togglePause=function(){c._wD(a.id+": togglePause()");if(0===a.playState)return a.play({position:9===n&&!a.isHTML5?a.position:a.position/1E3}),a;a.paused?a.resume():a.pause();return a};this.setPan=function(b,c){b===g&&(b=0);c===g&&(c=!1);a.isHTML5||k._setPan(a.id,b);a._iO.pan=b;c||(a.pan=b,a.options.pan=b);return a};this.setVolume= -function(b,d){b===g&&(b=100);d===g&&(d=!1);a.isHTML5?a._a&&(a._a.volume=Math.max(0,Math.min(1,b/100))):k._setVolume(a.id,c.muted&&!a.muted||a.muted?0:b);a._iO.volume=b;d||(a.volume=b,a.options.volume=b);return a};this.mute=function(){a.muted=!0;a.isHTML5?a._a&&(a._a.muted=!0):k._setVolume(a.id,0);return a};this.unmute=function(){a.muted=!1;var b=a._iO.volume!==g;a.isHTML5?a._a&&(a._a.muted=!1):k._setVolume(a.id,b?a._iO.volume:a.options.volume);return a};this.toggleMute=function(){return a.muted?a.unmute(): -a.mute()};this.onposition=this.onPosition=function(b,c,d){D.push({position:parseInt(b,10),method:c,scope:d!==g?d:a,fired:!1});return a};this.clearOnPosition=function(a,b){var c;a=parseInt(a,10);if(isNaN(a))return!1;for(c=0;c=b)return!1;for(b-=1;0<=b;b--)c=D[b],!c.fired&&a.position>=c.position&&(c.fired=!0,t++,c.method.apply(c.scope,[c.position])); -return!0};this._resetOnPosition=function(a){var b,c;b=D.length;if(!b)return!1;for(b-=1;0<=b;b--)c=D[b],c.fired&&a<=c.position&&(c.fired=!1,t--);return!0};y=function(){var b=a._iO,d=b.from,e=b.to,f,g;g=function(){c._wD(a.id+': "To" time of '+e+" reached.");a.clearOnPosition(e,g);a.stop()};f=function(){c._wD(a.id+': Playing "from" '+d);if(null!==e&&!isNaN(e))a.onPosition(e,g)};null!==d&&!isNaN(d)&&(b.position=d,b.multiShot=!1,f());return b};q=function(){var b,c=a._iO.onposition;if(c)for(b in c)if(c.hasOwnProperty(b))a.onPosition(parseInt(b, -10),c[b])};Ta=function(){var b,c=a._iO.onposition;if(c)for(b in c)c.hasOwnProperty(b)&&a.clearOnPosition(parseInt(b,10))};m=function(){a.isHTML5&&cb(a)};l=function(){a.isHTML5&&db(a)};f=function(b){b||(D=[],t=0);s=!1;a._hasTimer=null;a._a=null;a._html5_canplay=!1;a.bytesLoaded=null;a.bytesTotal=null;a.duration=a._iO&&a._iO.duration?a._iO.duration:null;a.durationEstimate=null;a.buffered=[];a.eqData=[];a.eqData.left=[];a.eqData.right=[];a.failures=0;a.isBuffering=!1;a.instanceOptions={};a.instanceCount= -0;a.loaded=!1;a.metadata={};a.readyState=0;a.muted=!1;a.paused=!1;a.peakData={left:0,right:0};a.waveformData={left:[],right:[]};a.playState=0;a.position=null;a.id3={}};f();this._onTimer=function(b){var c,f=!1,g={};if(a._hasTimer||b){if(a._a&&(b||(0opera.version()?new Audio(null):new Audio,c=a._a,c._called_load=!1,E&&(Va=c);a.isHTML5=!0;a._a=c;c._s=a;h();a._apply_loop(c,b.loops);b.autoLoad||b.autoPlay?a.load():(c.autobuffer=!1,c.preload="auto");return c};h=function(){if(a._a._added_events)return!1;var b;a._a._added_events=!0;for(b in G)G.hasOwnProperty(b)&&a._a&&a._a.addEventListener(b,G[b],!1);return!0};z=function(){var b;c._wD(a.id+": Removing event listeners"); -a._a._added_events=!1;for(b in G)G.hasOwnProperty(b)&&a._a&&a._a.removeEventListener(b,G[b],!1)};this._onload=function(b){var d=!!b||!a.isHTML5&&8===n&&a.duration;b=a.id+": ";c._wD(b+(d?"onload()":"Failed to load / invalid sound?"+(!a.duration?" Zero-length duration reported.":" -")+" ("+a.url+")"),d?1:2);!d&&!a.isHTML5&&(!0===c.sandbox.noRemote&&c._wD(b+r("noNet"),1),!0===c.sandbox.noLocal&&c._wD(b+r("noLocal"),1));a.loaded=d;a.readyState=d?3:2;a._onbufferchange(0);a._iO.onload&&ta(a,function(){a._iO.onload.apply(a, -[d])});return!0};this._onbufferchange=function(b){if(0===a.playState||b&&a.isBuffering||!b&&!a.isBuffering)return!1;a.isBuffering=1===b;a._iO.onbufferchange&&(c._wD(a.id+": Buffer state change: "+b),a._iO.onbufferchange.apply(a));return!0};this._onsuspend=function(){a._iO.onsuspend&&(c._wD(a.id+": Playback suspended"),a._iO.onsuspend.apply(a));return!0};this._onfailure=function(b,d,e){a.failures++;c._wD(a.id+": Failures \x3d "+a.failures);if(a._iO.onfailure&&1===a.failures)a._iO.onfailure(a,b,d,e); -else c._wD(a.id+": Ignoring failure")};this._onfinish=function(){var b=a._iO.onfinish;a._onbufferchange(0);a._resetOnPosition(0);if(a.instanceCount&&(a.instanceCount--,a.instanceCount||(Ta(),a.playState=0,a.paused=!1,a.instanceCount=0,a.instanceOptions={},a._iO={},l(),a.isHTML5&&(a.position=0)),(!a.instanceCount||a._iO.multiShotEvents)&&b))c._wD(a.id+": onfinish()"),ta(a,function(){b.apply(a)})};this._whileloading=function(b,c,d,e){var f=a._iO;a.bytesLoaded=b;a.bytesTotal=c;a.duration=Math.floor(d); -a.bufferLength=e;a.durationEstimate=!a.isHTML5&&!f.isMovieStar?f.duration?a.duration>f.duration?a.duration:f.duration:parseInt(a.bytesTotal/a.bytesLoaded*a.duration,10):a.duration;a.isHTML5||(a.buffered=[{start:0,end:a.duration}]);(3!==a.readyState||a.isHTML5)&&f.whileloading&&f.whileloading.apply(a)};this._whileplaying=function(b,c,d,e,f){var l=a._iO;if(isNaN(b)||null===b)return!1;a.position=Math.max(0,b);a._processOnPosition();!a.isHTML5&&8opera.version()?new Audio(null):new Audio:null,e,a,f={},h;h=c.audioFormats;for(e in h)if(h.hasOwnProperty(e)&&(a="audio/"+e,f[e]=b(h[e].type),f[a]=f[e],e.match(nb)?(c.flash[e]=!0,c.flash[a]=!0):(c.flash[e]=!1,c.flash[a]=!1),h[e]&&h[e].related))for(a=h[e].related.length- -1;0<=a;a--)f["audio/"+h[e].related[a]]=f[e],c.html5[h[e].related[a]]=f[e],c.flash[h[e].related[a]]=f[e];f.canPlayType=d?b:null;c.html5=B(c.html5,f);c.html5.usingFlash=fb();u=c.html5.usingFlash;return!0};I={notReady:"Unavailable - wait until onready() has fired.",notOK:"Audio support is not available.",domError:"soundManagerexception caught while appending SWF to DOM.",spcWmode:"Removing wmode, preventing known SWF loading issue(s)",swf404:"soundManager: Verify that %s is a valid path.",tryDebug:"Try soundManager.debugFlash \x3d true for more security details (output goes to SWF.)", -checkSWF:"See SWF output for more debug info.",localFail:"soundManager: Non-HTTP page ("+m.location.protocol+" URL?) Review Flash player security settings for this special case:\nhttp://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html\nMay need to add/allow path, eg. c:/sm2/ or /users/me/sm2/",waitFocus:"soundManager: Special case: Waiting for SWF to load with window focus...",waitForever:"soundManager: Waiting indefinitely for Flash (will recover if unblocked)...", -waitSWF:"soundManager: Waiting for 100% SWF load...",needFunction:"soundManager: Function object expected for %s",badID:'Sound ID "%s" should be a string, starting with a non-numeric character',currentObj:"soundManager: _debug(): Current sound objects",waitOnload:"soundManager: Waiting for window.onload()",docLoaded:"soundManager: Document already loaded",onload:"soundManager: initComplete(): calling soundManager.onload()",onloadOK:"soundManager.onload() complete",didInit:"soundManager: init(): Already called?", -secNote:"Flash security note: Network/internet URLs will not load due to security restrictions. Access can be configured via Flash Player Global Security Settings Page: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html",badRemove:"soundManager: Failed to remove Flash node.",shutdown:"soundManager.disable(): Shutting down",queue:"soundManager: Queueing %s handler",smError:"SMSound.load(): Exception: JS-Flash communication failed, or JS error.",fbTimeout:"No flash response, applying .swf_timedout CSS...", -fbLoaded:"Flash loaded",fbHandler:"soundManager: flashBlockHandler()",manURL:"SMSound.load(): Using manually-assigned URL",onURL:"soundManager.load(): current URL already assigned.",badFV:'soundManager.flashVersion must be 8 or 9. "%s" is invalid. Reverting to %s.',as2loop:"Note: Setting stream:false so looping can work (flash 8 limitation)",noNSLoop:"Note: Looping not implemented for MovieStar formats",needfl9:"Note: Switching to flash 9, required for MP4 formats.",mfTimeout:"Setting flashLoadTimeout \x3d 0 (infinite) for off-screen, mobile flash case", -needFlash:"soundManager: Fatal error: Flash is needed to play some required formats, but is not available.",gotFocus:"soundManager: Got window focus.",policy:"Enabling usePolicyFile for data access",setup:"soundManager.setup(): allowed parameters: %s",setupError:'soundManager.setup(): "%s" cannot be assigned with this method.',setupUndef:'soundManager.setup(): Could not find option "%s"',setupLate:"soundManager.setup(): url, flashVersion and html5Test property changes will not take effect until reboot().", -noURL:"soundManager: Flash URL required. Call soundManager.setup({url:...}) to get started.",sm2Loaded:"SoundManager 2: Ready.",reset:"soundManager.reset(): Removing event callbacks",mobileUA:"Mobile UA detected, preferring HTML5 by default.",globalHTML5:"Using singleton HTML5 Audio() pattern for this device."};r=function(){var b=hb.call(arguments),c=b.shift(),c=I&&I[c]?I[c]:"",e,a;if(c&&b&&b.length){e=0;for(a=b.length;en)&&(c._wD(r("needfl9")),c.flashVersion=n=9);c.version=c.versionNumber+(c.html5Only?" (HTML5-only mode)": -9===n?" (AS3/Flash 9)":" (AS2/Flash 8)");8b&&(d= -!0));setTimeout(function(){b=c.getMoviePercent();if(d)return $=!1,c._wD(r("waitSWF")),h.setTimeout(Q,1),!1;q||(c._wD("soundManager: No Flash response within expected time. Likely causes: "+(0===b?"SWF load failed, ":"")+"Flash blocked or JS-Flash security error."+(c.debugFlash?" "+r("checkSWF"):""),2),!ea&&b&&(p("localFail",2),c.debugFlash||p("tryDebug",2)),0===b&&c._wD(r("swf404",c.url),1),C("flashtojs",!1,": Timed out"+ea?" (Check flash security or flash blockers)":" (No plugin/missing SWF?)")); -!q&&mb&&(null===b?c.useFlashBlock||0===c.flashLoadTimeout?(c.useFlashBlock&&Ia(),p("waitForever")):!c.useFlashBlock&&qa?h.setTimeout(function(){J("soundManager: useFlashBlock is false, 100% HTML5 mode is possible. Rebooting with preferFlash: false...");c.setup({preferFlash:!1}).reboot();c.didFlashBlock=!0;c.beginDelayedInit()},1):(p("waitForever"),M({type:"ontimeout",ignoreInit:!0})):0===c.flashLoadTimeout?p("waitForever"):Ga(!0))},c.flashLoadTimeout)};ia=function(){if(Ra||!va)return w.remove(h,"focus", -ia),!0;Ra=mb=!0;p("gotFocus");$=!1;Q();w.remove(h,"focus",ia);return!0};Na=function(){N.length&&(c._wD("SoundManager 2: "+N.join(" "),1),N=[])};jb=function(){Na();var b,d=[];if(c.useHTML5Audio&&c.hasHTML5){for(b in c.audioFormats)c.audioFormats.hasOwnProperty(b)&&d.push(b+" \x3d "+c.html5[b]+(!c.html5[b]&&u&&c.flash[b]?" (using flash)":c.preferFlash&&c.flash[b]&&u?" (preferring flash)":!c.html5[b]?" ("+(c.audioFormats[b].required?"required, ":"")+"and no flash support)":""));c._wD("SoundManager 2 HTML5 support: "+ -d.join(", "),1)}};X=function(b){if(q)return!1;if(c.html5Only)return p("sm2Loaded"),q=!0,P(),C("onload",!0),!0;var d=!0,e;if(!c.useFlashBlock||!c.flashLoadTimeout||c.getMoviePercent())q=!0,y&&(e={type:!H&&u?"NO_FLASH":"INIT_TIMEOUT"});c._wD("SoundManager 2 "+(y?"failed to load":"loaded")+" ("+(y?"Flash security/load error":"OK")+")",y?2:1);y||b?(c.useFlashBlock&&c.oMC&&(c.oMC.className=T()+" "+(null===c.getMoviePercent()?"swf_timedout":"swf_error")),M({type:"ontimeout",error:e,ignoreInit:!0}),C("onload", -!1),S(e),d=!1):C("onload",!0);y||(c.waitForWindowLoad&&!ha?(p("waitOnload"),w.add(h,"load",P)):(c.waitForWindowLoad&&ha&&p("docLoaded"),P()));return d};Wa=function(){var b,d=c.setupOptions;for(b in d)d.hasOwnProperty(b)&&(c[b]===g?c[b]=d[b]:c[b]!==d[b]&&(c.setupOptions[b]=c[b]))};ya=function(){if(q)return p("didInit"),!1;if(c.html5Only)return q||(w.remove(h,"load",c.beginDelayedInit),c.enabled=!0,X()),!0;ja();try{k._externalInterfaceTest(!1),Ya(!0,c.flashPollingInterval||(c.useHighPerformance?10: -50)),c.debugMode||k._disableDebug(),c.enabled=!0,C("jstoflash",!0),c.html5Only||w.add(h,"unload",xa)}catch(b){return c._wD("js/flash exception: "+b.toString()),C("jstoflash",!1),S({type:"JS_TO_FLASH_EXCEPTION",fatal:!0}),Ga(!0),X(),!1}X();w.remove(h,"load",c.beginDelayedInit);return!0};R=function(){if(Y)return!1;Y=!0;Wa();Fa();var b=null,b=null,d=U.toLowerCase();-1!==d.indexOf("sm2-usehtml5audio\x3d")&&(b="1"===d.charAt(d.indexOf("sm2-usehtml5audio\x3d")+18),da&&console.log((b?"Enabling ":"Disabling ")+ -"useHTML5Audio via URL parameter"),c.setup({useHTML5Audio:b}));-1!==d.indexOf("sm2-preferflash\x3d")&&(b="1"===d.charAt(d.indexOf("sm2-preferflash\x3d")+16),da&&console.log((b?"Enabling ":"Disabling ")+"preferFlash via URL parameter"),c.setup({preferFlash:b}));!H&&c.hasHTML5&&(c._wD("SoundManager: No Flash detected"+(!c.useHTML5Audio?", enabling HTML5.":". Trying HTML5-only mode."),1),c.setup({useHTML5Audio:!0,preferFlash:!1}));gb();!H&&u&&(N.push(I.needFlash),c.setup({flashLoadTimeout:1}));m.removeEventListener&& -m.removeEventListener("DOMContentLoaded",R,!1);ja();return!0};Ka=function(){"complete"===m.readyState&&(R(),m.detachEvent("onreadystatechange",Ka));return!0};Ea=function(){ha=!0;w.remove(h,"load",Ea)};Da=function(){if(Pa&&((!c.setupOptions.useHTML5Audio||c.setupOptions.preferFlash)&&N.push(I.mobileUA),c.setupOptions.useHTML5Audio=!0,c.setupOptions.preferFlash=!1,ca||lb&&!t.match(/android\s2\.3/i)))N.push(I.globalHTML5),ca&&(c.ignoreFlash=!0),E=!0};Da();Ma();w.add(h,"focus",ia);w.add(h,"load",Q);w.add(h, -"load",Ea);m.addEventListener?m.addEventListener("DOMContentLoaded",R,!1):m.attachEvent?m.attachEvent("onreadystatechange",Ka):(C("onload",!1),S({type:"NO_DOM2_EVENTS",fatal:!0}))}var wa=null;if(void 0===h.SM2_DEFER||!SM2_DEFER)wa=new fa;h.SoundManager=fa;h.soundManager=wa})(window); \ No newline at end of file diff --git a/adventure-composer/src/main/resources/projectTmpl/html/war/soundmanager2-setup.js b/adventure-composer/src/main/resources/projectTmpl/html/war/soundmanager2-setup.js deleted file mode 100644 index 4d0ac6630..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/html/war/soundmanager2-setup.js +++ /dev/null @@ -1 +0,0 @@ -window.SM2_DEFER = true; \ No newline at end of file diff --git a/adventure-composer/src/main/resources/projectTmpl/html/war/styles.css b/adventure-composer/src/main/resources/projectTmpl/html/war/styles.css deleted file mode 100644 index f823a7a98..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/html/war/styles.css +++ /dev/null @@ -1,91 +0,0 @@ -canvas { - cursor: default; - outline: none; -} - -body { - background-color: #ffffff; -} - -.superdev { - background-color:#3bb3e0; - font-family: 'Open Sans', sans-serif; - font-size:12px; - text-decoration:none; - color:#fff; - position:relative; - padding:10px 20px; - padding-right:50px; - background-image: linear-gradient(bottom, rgb(44,160,202) 0%, rgb(62,184,229) 100%); - background-image: -o-linear-gradient(bottom, rgb(44,160,202) 0%, rgb(62,184,229) 100%); - background-image: -moz-linear-gradient(bottom, rgb(44,160,202) 0%, rgb(62,184,229) 100%); - background-image: -webkit-linear-gradient(bottom, rgb(44,160,202) 0%, rgb(62,184,229) 100%); - background-image: -ms-linear-gradient(bottom, rgb(44,160,202) 0%, rgb(62,184,229) 100%); - background-image: -webkit-gradient( - linear, - left bottom, - left top, - color-stop(0, rgb(44,160,202)), - color-stop(1, rgb(62,184,229)) - ); - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - -o-border-radius: 5px; - border-radius: 5px; - -webkit-box-shadow: inset 0px 1px 0px #2ab7ec, 0px 5px 0px 0px #156785, 0px 10px 5px #999; - -moz-box-shadow: inset 0px 1px 0px #2ab7ec, 0px 5px 0px 0px #156785, 0px 10px 5px #999; - -o-box-shadow: inset 0px 1px 0px #2ab7ec, 0px 5px 0px 0px #156785, 0px 10px 5px #999; - box-shadow: inset 0px 1px 0px #2ab7ec, 0px 5px 0px 0px #156785, 0px 10px 5px #999; -} - -.superdev:active { - top:3px; - background-image: linear-gradient(bottom, rgb(62,184,229) 0%, rgb(44,160,202) 100%); - background-image: -o-linear-gradient(bottom, rgb(62,184,229) 0%, rgb(44,160,202) 100%); - background-image: -moz-linear-gradient(bottom, rgb(62,184,229) 0%, rgb(44,160,202) 100%); - background-image: -webkit-linear-gradient(bottom, rgb(62,184,229) 0%, rgb(44,160,202) 100%); - background-image: -ms-linear-gradient(bottom, rgb(62,184,229) 0%, rgb(44,160,202) 100%); - background-image: -webkit-gradient( - linear, - left bottom, - left top, - color-stop(0, rgb(62,184,229)), - color-stop(1, rgb(44,160,202)) - ); - -webkit-box-shadow: inset 0px 1px 0px #2ab7ec, 0px 2px 0px 0px #156785, 0px 5px 3px #999; - -moz-box-shadow: inset 0px 1px 0px #2ab7ec, 0px 2px 0px 0px #156785, 0px 5px 3px #999; - -o-box-shadow: inset 0px 1px 0px #2ab7ec, 0px 2px 0px 0px #156785, 0px 5px 3px #999; - box-shadow: inset 0px 1px 0px #2ab7ec, 0px 2px 0px 0px #156785, 0px 5px 3px #999; -} - -.superdev::before { - background-color:#2591b4; - background-image:url(refresh.png); - background-size: 12px; - background-repeat:no-repeat; - background-position:center center; - content:""; - width:20px; - height:20px; - position:absolute; - right:15px; - top:50%; - margin-top:-9px; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - -o-border-radius: 50%; - border-radius: 50%; - -webkit-box-shadow: inset 0px 1px 0px #052756, 0px 1px 0px #60c9f0; - -moz-box-shadow: inset 0px 1px 0px #052756, 0px 1px 0px #60c9f0; - -o-box-shadow: inset 0px 1px 0px #052756, 0px 1px 0px #60c9f0; - box-shadow: inset 0px 1px 0px #052756, 0px 1px 0px #60c9f0; -} - -.superdev:active::before { - top:50%; - margin-top:-12px; - -webkit-box-shadow: inset 0px 1px 0px #60c9f0, 0px 3px 0px #0e3871, 0px 6px 3px #1a80a6; - -moz-box-shadow: inset 0px 1px 0px #60c9f0, 0px 3px 0px #0e3871, 0px 6px 3px #1a80a6; - -o-box-shadow: inset 0px 1px 0px #60c9f0, 0px 3px 0px #0e3871, 0px 6px 3px #1a80a6; - box-shadow: inset 0px 1px 0px #60c9f0, 0px 3px 0px #0e3871, 0px 6px 3px #1a80a6; -} \ No newline at end of file diff --git a/adventure-composer/src/main/resources/projectTmpl/ios/Info.plist.xml b/adventure-composer/src/main/resources/projectTmpl/ios/Info.plist.xml deleted file mode 100644 index 407bec75c..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/ios/Info.plist.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - ${app.name} - CFBundleExecutable - ${app.executable} - CFBundleIdentifier - ${app.id} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${app.name} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${app.version} - CFBundleSignature - ???? - CFBundleVersion - ${app.build} - LSRequiresIPhoneOS - - UIViewControllerBasedStatusBarAppearance - - UIStatusBarHidden - - UIDeviceFamily - - 1 - 2 - - UIRequiredDeviceCapabilities - - armv7 - opengles-2 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - CFBundleIcons - - CFBundlePrimaryIcon - - CFBundleIconFiles - - Icon - Icon-72 - - - - - diff --git a/adventure-composer/src/main/resources/projectTmpl/ios/build.gradle b/adventure-composer/src/main/resources/projectTmpl/ios/build.gradle deleted file mode 100644 index 8261aec35..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/ios/build.gradle +++ /dev/null @@ -1,65 +0,0 @@ -sourceSets.main.java.srcDirs = [ "src/" ] - -sourceCompatibility = '1.7' -[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' - -ext { - mainClassName = "%PACKAGE%.ios.IOSLauncher" -} - -// Extracts native libs (*.a) from the native-ios.jar and places them -// under build/libs/ios/. -task copyNatives << { - file("build/libs/ios/").mkdirs(); - configurations.natives.files.each { jar -> - def outputDir = null - if (jar.name.endsWith("natives-ios.jar")) outputDir = file("build/libs/ios") - if (outputDir != null) { - copy { - from zipTree(jar) - into outputDir - include "*.a" - } - } - } -} - -// Updates a robovm.xml file. -task updateRoboVMXML << { - def xml = file('robovm.xml') - - if (!xml.exists()) { - return - } - - // Find all native (*.a) libraries beneath libs - def libtree = fileTree(dir: 'build/libs', include: '**/*.a') - - def config = new groovy.util.XmlParser().parse(xml) - config.libs.each {libs -> - libs.children().clear() - libtree.each { File file -> - libs.appendNode('lib', 'build/libs/ios/' + file.getName()) - } - } - - def writer = new FileWriter(xml) - def printer = new XmlNodePrinter(new PrintWriter(writer)) - printer.setPreserveWhitespace true - printer.print(config) -} - -updateRoboVMXML.dependsOn copyNatives -build.dependsOn updateRoboVMXML -tasks.eclipse.dependsOn updateRoboVMXML - -launchIPhoneSimulator.dependsOn build -launchIPadSimulator.dependsOn build -launchIOSDevice.dependsOn build -createIPA.dependsOn build - - -eclipse.project { - name = appName + "-ios" - natures 'org.robovm.eclipse.RoboVMNature' -} \ No newline at end of file diff --git a/adventure-composer/src/main/resources/projectTmpl/ios/data/Default-568h@2x.png b/adventure-composer/src/main/resources/projectTmpl/ios/data/Default-568h@2x.png deleted file mode 100644 index 101752fe7..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/ios/data/Default-568h@2x.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/ios/data/Default.png b/adventure-composer/src/main/resources/projectTmpl/ios/data/Default.png deleted file mode 100644 index f1a5582a0..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/ios/data/Default.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/ios/data/Default@2x.png b/adventure-composer/src/main/resources/projectTmpl/ios/data/Default@2x.png deleted file mode 100644 index ca32f62fc..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/ios/data/Default@2x.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/ios/data/Default@2x~ipad.png b/adventure-composer/src/main/resources/projectTmpl/ios/data/Default@2x~ipad.png deleted file mode 100644 index bb77ef073..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/ios/data/Default@2x~ipad.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/ios/data/Default~ipad.png b/adventure-composer/src/main/resources/projectTmpl/ios/data/Default~ipad.png deleted file mode 100644 index 855e4f2ad..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/ios/data/Default~ipad.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/ios/data/Icon-72.png b/adventure-composer/src/main/resources/projectTmpl/ios/data/Icon-72.png deleted file mode 100644 index 09d798646..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/ios/data/Icon-72.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/ios/data/Icon-72@2x.png b/adventure-composer/src/main/resources/projectTmpl/ios/data/Icon-72@2x.png deleted file mode 100644 index 055c737ad..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/ios/data/Icon-72@2x.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/ios/data/Icon.png b/adventure-composer/src/main/resources/projectTmpl/ios/data/Icon.png deleted file mode 100644 index 7f4bf3635..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/ios/data/Icon.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/ios/data/Icon@2x.png b/adventure-composer/src/main/resources/projectTmpl/ios/data/Icon@2x.png deleted file mode 100644 index eddc17c57..000000000 Binary files a/adventure-composer/src/main/resources/projectTmpl/ios/data/Icon@2x.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/projectTmpl/ios/robovm.xml b/adventure-composer/src/main/resources/projectTmpl/ios/robovm.xml deleted file mode 100644 index a38af629c..000000000 --- a/adventure-composer/src/main/resources/projectTmpl/ios/robovm.xml +++ /dev/null @@ -1,46 +0,0 @@ - - ${app.executable} - ${app.mainclass} - ios - thumbv7 - ios - Info.plist.xml - - - ../%ASSET_PATH% - - ** - - true - - - data - - - - com.badlogic.gdx.scenes.scene2d.ui.* - com.badlogic.gdx.physics.bullet.** - com.android.okhttp.HttpHandler - com.android.okhttp.HttpsHandler - com.android.org.conscrypt.** - com.android.org.bouncycastle.jce.provider.BouncyCastleProvider - com.android.org.bouncycastle.jcajce.provider.keystore.BC$Mappings - com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi - com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$Std - com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi - com.android.org.bouncycastle.crypto.digests.AndroidDigestFactoryOpenSSL - org.apache.harmony.security.provider.cert.DRLCertFactory - org.apache.harmony.security.provider.crypto.CryptoProvider - - - - - UIKit - OpenGLES - QuartzCore - CoreGraphics - OpenAL - AudioToolbox - AVFoundation - - diff --git a/adventure-composer/src/main/resources/skin/BladeSkin/BladeSkin-ldpi.png b/adventure-composer/src/main/resources/skin/BladeSkin/BladeSkin-ldpi.png deleted file mode 100644 index 9b234d4ed..000000000 Binary files a/adventure-composer/src/main/resources/skin/BladeSkin/BladeSkin-ldpi.png and /dev/null differ diff --git a/adventure-composer/src/main/resources/skin/BladeSkin/ubuntu-light-12.fnt b/adventure-composer/src/main/resources/skin/BladeSkin/ubuntu-light-12.fnt deleted file mode 100644 index d8d22087e..000000000 --- a/adventure-composer/src/main/resources/skin/BladeSkin/ubuntu-light-12.fnt +++ /dev/null @@ -1,267 +0,0 @@ -info face=Ubuntu Light size=12 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=0 aa=1 padding=0,0,0,0 spacing=1,1 -common lineHeight=15 base=12 scaleW=1024 scaleH=1024 pages=1 packed=0 -page id=0 file=ubuntu-light-12_00.png -chars count=190 -char id=33 x=890 y=0 width=4 height=11 xoffset=-1 yoffset=2 xadvance=3 page=0 chnl=0 -char id=34 x=602 y=12 width=4 height=5 xoffset=0 yoffset=1 xadvance=5 page=0 chnl=0 -char id=35 x=943 y=0 width=9 height=10 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=0 -char id=36 x=229 y=0 width=7 height=13 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=37 x=516 y=0 width=11 height=11 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 -char id=38 x=610 y=0 width=9 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=39 x=590 y=12 width=2 height=5 xoffset=0 yoffset=1 xadvance=3 page=0 chnl=0 -char id=40 x=104 y=0 width=4 height=14 xoffset=0 yoffset=1 xadvance=4 page=0 chnl=0 -char id=41 x=109 y=0 width=4 height=14 xoffset=-1 yoffset=1 xadvance=4 page=0 chnl=0 -char id=42 x=682 y=12 width=7 height=7 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=0 -char id=43 x=771 y=12 width=8 height=8 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=44 x=593 y=12 width=3 height=5 xoffset=-1 yoffset=9 xadvance=3 page=0 chnl=0 -char id=45 x=533 y=12 width=5 height=2 xoffset=-1 yoffset=7 xadvance=5 page=0 chnl=0 -char id=46 x=570 y=12 width=4 height=4 xoffset=-1 yoffset=9 xadvance=3 page=0 chnl=0 -char id=47 x=60 y=0 width=7 height=14 xoffset=-2 yoffset=1 xadvance=4 page=0 chnl=0 -char id=48 x=640 y=0 width=8 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=49 x=904 y=11 width=5 height=10 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=0 -char id=50 x=963 y=11 width=7 height=10 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=51 x=703 y=0 width=7 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=52 x=973 y=0 width=8 height=10 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=53 x=711 y=0 width=7 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=54 x=649 y=0 width=8 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=55 x=955 y=11 width=7 height=10 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=56 x=719 y=0 width=7 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=57 x=727 y=0 width=7 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=58 x=803 y=12 width=4 height=9 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 -char id=59 x=893 y=12 width=4 height=10 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 -char id=60 x=762 y=12 width=8 height=8 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=61 x=629 y=12 width=8 height=6 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=0 -char id=62 x=753 y=12 width=8 height=8 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=63 x=823 y=0 width=6 height=11 xoffset=-1 yoffset=2 xadvance=5 page=0 chnl=0 -char id=64 x=291 y=0 width=12 height=12 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 -char id=65 x=953 y=0 width=9 height=10 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=66 x=735 y=0 width=7 height=11 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=0 -char id=67 x=658 y=0 width=8 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=68 x=667 y=0 width=8 height=11 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=0 -char id=69 x=947 y=11 width=7 height=10 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=0 -char id=70 x=924 y=11 width=6 height=10 xoffset=0 yoffset=2 xadvance=6 page=0 chnl=0 -char id=71 x=620 y=0 width=9 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=72 x=982 y=0 width=8 height=10 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=0 -char id=73 x=886 y=12 width=2 height=10 xoffset=0 yoffset=2 xadvance=3 page=0 chnl=0 -char id=74 x=830 y=0 width=6 height=11 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=0 -char id=75 x=991 y=0 width=8 height=10 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=0 -char id=76 x=917 y=11 width=6 height=10 xoffset=0 yoffset=2 xadvance=6 page=0 chnl=0 -char id=77 x=931 y=0 width=11 height=10 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 -char id=78 x=1000 y=0 width=8 height=10 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=0 -char id=79 x=588 y=0 width=10 height=11 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=0 -char id=80 x=939 y=11 width=7 height=10 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=0 -char id=81 x=130 y=0 width=10 height=13 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=0 -char id=82 x=1009 y=0 width=8 height=10 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=0 -char id=83 x=743 y=0 width=7 height=11 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=0 -char id=84 x=1016 y=11 width=8 height=10 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=0 -char id=85 x=676 y=0 width=8 height=11 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=0 -char id=86 x=963 y=0 width=9 height=10 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=0 -char id=87 x=905 y=0 width=12 height=10 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=0 -char id=88 x=1007 y=11 width=8 height=10 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=89 x=998 y=11 width=8 height=10 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=0 -char id=90 x=989 y=11 width=8 height=10 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=91 x=114 y=0 width=4 height=14 xoffset=0 yoffset=1 xadvance=4 page=0 chnl=0 -char id=92 x=68 y=0 width=7 height=14 xoffset=-2 yoffset=1 xadvance=4 page=0 chnl=0 -char id=93 x=119 y=0 width=4 height=14 xoffset=-1 yoffset=1 xadvance=4 page=0 chnl=0 -char id=94 x=699 y=12 width=8 height=7 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=95 x=551 y=12 width=8 height=3 xoffset=-2 yoffset=12 xadvance=6 page=0 chnl=0 -char id=96 x=575 y=12 width=5 height=4 xoffset=-1 yoffset=1 xadvance=5 page=0 chnl=0 -char id=97 x=839 y=12 width=7 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 -char id=98 x=379 y=0 width=7 height=12 xoffset=0 yoffset=1 xadvance=7 page=0 chnl=0 -char id=99 x=831 y=12 width=7 height=9 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 -char id=100 x=387 y=0 width=7 height=12 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=101 x=823 y=12 width=7 height=9 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=102 x=872 y=0 width=5 height=11 xoffset=0 yoffset=1 xadvance=5 page=0 chnl=0 -char id=103 x=751 y=0 width=7 height=11 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=104 x=837 y=0 width=6 height=11 xoffset=0 yoffset=1 xadvance=7 page=0 chnl=0 -char id=105 x=889 y=12 width=3 height=10 xoffset=-1 yoffset=2 xadvance=3 page=0 chnl=0 -char id=106 x=281 y=0 width=4 height=13 xoffset=-2 yoffset=2 xadvance=3 page=0 chnl=0 -char id=107 x=844 y=0 width=6 height=11 xoffset=0 yoffset=1 xadvance=6 page=0 chnl=0 -char id=108 x=512 y=0 width=3 height=12 xoffset=0 yoffset=1 xadvance=4 page=0 chnl=0 -char id=109 x=780 y=12 width=10 height=8 xoffset=0 yoffset=4 xadvance=11 page=0 chnl=0 -char id=110 x=721 y=12 width=6 height=8 xoffset=0 yoffset=4 xadvance=7 page=0 chnl=0 -char id=111 x=865 y=12 width=8 height=9 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=112 x=759 y=0 width=7 height=11 xoffset=0 yoffset=4 xadvance=7 page=0 chnl=0 -char id=113 x=767 y=0 width=7 height=11 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=114 x=708 y=12 width=5 height=8 xoffset=0 yoffset=4 xadvance=5 page=0 chnl=0 -char id=115 x=808 y=12 width=6 height=9 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=0 -char id=116 x=851 y=0 width=6 height=11 xoffset=-1 yoffset=2 xadvance=5 page=0 chnl=0 -char id=117 x=815 y=12 width=7 height=9 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=118 x=736 y=12 width=7 height=8 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=119 x=791 y=12 width=11 height=8 xoffset=-1 yoffset=4 xadvance=11 page=0 chnl=0 -char id=120 x=728 y=12 width=7 height=8 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=121 x=775 y=0 width=7 height=11 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=122 x=714 y=12 width=6 height=8 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=0 -char id=123 x=92 y=0 width=5 height=14 xoffset=-1 yoffset=1 xadvance=4 page=0 chnl=0 -char id=124 x=124 y=0 width=2 height=14 xoffset=0 yoffset=1 xadvance=3 page=0 chnl=0 -char id=125 x=98 y=0 width=5 height=14 xoffset=-1 yoffset=1 xadvance=4 page=0 chnl=0 -char id=126 x=581 y=12 width=8 height=4 xoffset=-1 yoffset=6 xadvance=7 page=0 chnl=0 -char id=160 x=525 y=12 width=1 height=1 xoffset=-1 yoffset=11 xadvance=3 page=0 chnl=0 -char id=161 x=895 y=0 width=4 height=11 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=0 -char id=162 x=499 y=0 width=6 height=12 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=0 -char id=163 x=980 y=11 width=8 height=10 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=164 x=690 y=12 width=8 height=7 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 -char id=165 x=971 y=11 width=8 height=10 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=166 x=127 y=0 width=2 height=14 xoffset=0 yoffset=1 xadvance=3 page=0 chnl=0 -char id=167 x=395 y=0 width=7 height=12 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=0 -char id=168 x=545 y=12 width=5 height=3 xoffset=-1 yoffset=2 xadvance=5 page=0 chnl=0 -char id=169 x=528 y=0 width=11 height=11 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=0 -char id=170 x=655 y=12 width=5 height=7 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=0 -char id=171 x=675 y=12 width=6 height=7 xoffset=-1 yoffset=5 xadvance=5 page=0 chnl=0 -char id=172 x=620 y=12 width=8 height=6 xoffset=-1 yoffset=6 xadvance=7 page=0 chnl=0 -char id=173 x=527 y=12 width=5 height=2 xoffset=-1 yoffset=7 xadvance=5 page=0 chnl=0 -char id=174 x=540 y=0 width=11 height=11 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=0 -char id=175 x=539 y=12 width=5 height=3 xoffset=-1 yoffset=2 xadvance=5 page=0 chnl=0 -char id=176 x=607 y=12 width=5 height=5 xoffset=-1 yoffset=1 xadvance=3 page=0 chnl=0 -char id=177 x=856 y=12 width=8 height=9 xoffset=-1 yoffset=3 xadvance=7 page=0 chnl=0 -char id=178 x=649 y=12 width=5 height=7 xoffset=-1 yoffset=2 xadvance=4 page=0 chnl=0 -char id=179 x=643 y=12 width=5 height=7 xoffset=-1 yoffset=2 xadvance=4 page=0 chnl=0 -char id=180 x=565 y=12 width=4 height=4 xoffset=0 yoffset=1 xadvance=5 page=0 chnl=0 -char id=181 x=858 y=0 width=6 height=11 xoffset=0 yoffset=4 xadvance=7 page=0 chnl=0 -char id=182 x=193 y=0 width=8 height=13 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=183 x=560 y=12 width=4 height=4 xoffset=-1 yoffset=6 xadvance=3 page=0 chnl=0 -char id=184 x=597 y=12 width=4 height=5 xoffset=0 yoffset=10 xadvance=5 page=0 chnl=0 -char id=185 x=638 y=12 width=4 height=7 xoffset=-1 yoffset=2 xadvance=4 page=0 chnl=0 -char id=186 x=668 y=12 width=6 height=7 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=187 x=661 y=12 width=6 height=7 xoffset=-1 yoffset=5 xadvance=5 page=0 chnl=0 -char id=188 x=552 y=0 width=11 height=11 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 -char id=189 x=564 y=0 width=11 height=11 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 -char id=190 x=576 y=0 width=11 height=11 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 -char id=191 x=865 y=0 width=6 height=11 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=0 -char id=192 x=163 y=0 width=9 height=13 xoffset=-1 yoffset=-1 xadvance=7 page=0 chnl=0 -char id=193 x=173 y=0 width=9 height=13 xoffset=-1 yoffset=-1 xadvance=7 page=0 chnl=0 -char id=194 x=183 y=0 width=9 height=13 xoffset=-1 yoffset=-1 xadvance=7 page=0 chnl=0 -char id=195 x=304 y=0 width=9 height=12 xoffset=-1 yoffset=0 xadvance=7 page=0 chnl=0 -char id=196 x=314 y=0 width=9 height=12 xoffset=-1 yoffset=0 xadvance=7 page=0 chnl=0 -char id=197 x=324 y=0 width=9 height=12 xoffset=-1 yoffset=0 xadvance=7 page=0 chnl=0 -char id=198 x=918 y=0 width=12 height=10 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 -char id=199 x=202 y=0 width=8 height=13 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=200 x=237 y=0 width=7 height=13 xoffset=0 yoffset=-1 xadvance=7 page=0 chnl=0 -char id=201 x=245 y=0 width=7 height=13 xoffset=0 yoffset=-1 xadvance=7 page=0 chnl=0 -char id=202 x=253 y=0 width=7 height=13 xoffset=0 yoffset=-1 xadvance=7 page=0 chnl=0 -char id=203 x=403 y=0 width=7 height=12 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=0 -char id=204 x=269 y=0 width=5 height=13 xoffset=-2 yoffset=-1 xadvance=3 page=0 chnl=0 -char id=205 x=286 y=0 width=4 height=13 xoffset=-1 yoffset=-1 xadvance=3 page=0 chnl=0 -char id=206 x=275 y=0 width=5 height=13 xoffset=-2 yoffset=-1 xadvance=3 page=0 chnl=0 -char id=207 x=506 y=0 width=5 height=12 xoffset=-2 yoffset=0 xadvance=3 page=0 chnl=0 -char id=208 x=630 y=0 width=9 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=209 x=334 y=0 width=8 height=12 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=0 -char id=210 x=0 y=0 width=10 height=14 xoffset=-1 yoffset=-1 xadvance=9 page=0 chnl=0 -char id=211 x=11 y=0 width=10 height=14 xoffset=-1 yoffset=-1 xadvance=9 page=0 chnl=0 -char id=212 x=22 y=0 width=10 height=14 xoffset=-1 yoffset=-1 xadvance=9 page=0 chnl=0 -char id=213 x=141 y=0 width=10 height=13 xoffset=-1 yoffset=0 xadvance=9 page=0 chnl=0 -char id=214 x=152 y=0 width=10 height=13 xoffset=-1 yoffset=0 xadvance=9 page=0 chnl=0 -char id=215 x=613 y=12 width=6 height=6 xoffset=0 yoffset=5 xadvance=7 page=0 chnl=0 -char id=216 x=599 y=0 width=10 height=11 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=0 -char id=217 x=33 y=0 width=8 height=14 xoffset=0 yoffset=-1 xadvance=8 page=0 chnl=0 -char id=218 x=42 y=0 width=8 height=14 xoffset=0 yoffset=-1 xadvance=8 page=0 chnl=0 -char id=219 x=51 y=0 width=8 height=14 xoffset=0 yoffset=-1 xadvance=8 page=0 chnl=0 -char id=220 x=211 y=0 width=8 height=13 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=0 -char id=221 x=220 y=0 width=8 height=13 xoffset=-1 yoffset=-1 xadvance=9 page=0 chnl=0 -char id=222 x=931 y=11 width=7 height=10 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=0 -char id=223 x=411 y=0 width=7 height=12 xoffset=0 yoffset=1 xadvance=7 page=0 chnl=0 -char id=224 x=419 y=0 width=7 height=12 xoffset=-1 yoffset=1 xadvance=6 page=0 chnl=0 -char id=225 x=427 y=0 width=7 height=12 xoffset=-1 yoffset=1 xadvance=6 page=0 chnl=0 -char id=226 x=435 y=0 width=7 height=12 xoffset=-1 yoffset=1 xadvance=6 page=0 chnl=0 -char id=227 x=783 y=0 width=7 height=11 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=0 -char id=228 x=791 y=0 width=7 height=11 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=0 -char id=229 x=443 y=0 width=7 height=12 xoffset=-1 yoffset=1 xadvance=6 page=0 chnl=0 -char id=230 x=874 y=12 width=11 height=9 xoffset=-1 yoffset=4 xadvance=10 page=0 chnl=0 -char id=231 x=799 y=0 width=7 height=11 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 -char id=232 x=451 y=0 width=7 height=12 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=233 x=459 y=0 width=7 height=12 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=234 x=467 y=0 width=7 height=12 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=235 x=807 y=0 width=7 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=236 x=878 y=0 width=5 height=11 xoffset=-2 yoffset=1 xadvance=3 page=0 chnl=0 -char id=237 x=900 y=0 width=4 height=11 xoffset=-1 yoffset=1 xadvance=3 page=0 chnl=0 -char id=238 x=884 y=0 width=5 height=11 xoffset=-2 yoffset=1 xadvance=3 page=0 chnl=0 -char id=239 x=898 y=12 width=5 height=10 xoffset=-2 yoffset=2 xadvance=3 page=0 chnl=0 -char id=240 x=343 y=0 width=8 height=12 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=241 x=910 y=11 width=6 height=10 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=0 -char id=242 x=352 y=0 width=8 height=12 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=243 x=361 y=0 width=8 height=12 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=244 x=370 y=0 width=8 height=12 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=245 x=685 y=0 width=8 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=246 x=694 y=0 width=8 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=247 x=744 y=12 width=8 height=8 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=248 x=847 y=12 width=8 height=9 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=249 x=475 y=0 width=7 height=12 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=250 x=483 y=0 width=7 height=12 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=251 x=491 y=0 width=7 height=12 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=252 x=815 y=0 width=7 height=11 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=253 x=76 y=0 width=7 height=14 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=254 x=84 y=0 width=7 height=14 xoffset=0 yoffset=1 xadvance=7 page=0 chnl=0 -char id=255 x=261 y=0 width=7 height=13 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -kernings count=72 -kerning first=39 second=65 amount=-1 -kerning first=39 second=74 amount=-1 -kerning first=39 second=198 amount=-1 -kerning first=42 second=65 amount=-1 -kerning first=42 second=74 amount=-1 -kerning first=42 second=90 amount=-1 -kerning first=42 second=198 amount=-1 -kerning first=46 second=84 amount=-1 -kerning first=46 second=86 amount=-1 -kerning first=46 second=89 amount=-1 -kerning first=47 second=74 amount=-1 -kerning first=47 second=198 amount=-1 -kerning first=58 second=84 amount=-1 -kerning first=64 second=89 amount=-1 -kerning first=65 second=39 amount=-1 -kerning first=65 second=42 amount=-1 -kerning first=65 second=84 amount=-1 -kerning first=65 second=86 amount=-1 -kerning first=65 second=89 amount=-1 -kerning first=70 second=46 amount=-1 -kerning first=70 second=47 amount=-1 -kerning first=70 second=74 amount=-1 -kerning first=70 second=198 amount=-1 -kerning first=76 second=39 amount=-1 -kerning first=76 second=42 amount=-2 -kerning first=76 second=45 amount=-1 -kerning first=76 second=84 amount=-1 -kerning first=76 second=86 amount=-1 -kerning first=76 second=89 amount=-1 -kerning first=80 second=46 amount=-1 -kerning first=80 second=47 amount=-1 -kerning first=80 second=74 amount=-1 -kerning first=80 second=198 amount=-1 -kerning first=84 second=46 amount=-1 -kerning first=84 second=47 amount=-1 -kerning first=84 second=58 amount=-1 -kerning first=84 second=65 amount=-1 -kerning first=84 second=74 amount=-1 -kerning first=84 second=99 amount=-1 -kerning first=84 second=100 amount=-1 -kerning first=84 second=101 amount=-1 -kerning first=84 second=103 amount=-1 -kerning first=84 second=111 amount=-1 -kerning first=84 second=113 amount=-1 -kerning first=84 second=119 amount=-1 -kerning first=84 second=198 amount=-1 -kerning first=84 second=240 amount=-1 -kerning first=86 second=46 amount=-1 -kerning first=86 second=47 amount=-1 -kerning first=86 second=65 amount=-1 -kerning first=86 second=74 amount=-1 -kerning first=86 second=198 amount=-1 -kerning first=87 second=74 amount=-1 -kerning first=89 second=46 amount=-1 -kerning first=89 second=47 amount=-1 -kerning first=89 second=64 amount=-1 -kerning first=89 second=65 amount=-1 -kerning first=89 second=74 amount=-1 -kerning first=89 second=198 amount=-1 -kerning first=89 second=240 amount=-1 -kerning first=90 second=45 amount=-1 -kerning first=91 second=93 amount=1 -kerning first=114 second=46 amount=-1 -kerning first=161 second=84 amount=-1 -kerning first=191 second=74 amount=-1 -kerning first=191 second=84 amount=-1 -kerning first=191 second=88 amount=-1 -kerning first=191 second=89 amount=-1 -kerning first=191 second=90 amount=-1 -kerning first=191 second=198 amount=-1 -kerning first=222 second=46 amount=-1 -kerning first=222 second=74 amount=-1 diff --git a/adventure-composer/src/main/resources/skin/BladeSkin/ubuntu-medium-14.fnt b/adventure-composer/src/main/resources/skin/BladeSkin/ubuntu-medium-14.fnt deleted file mode 100644 index 979f0e83f..000000000 --- a/adventure-composer/src/main/resources/skin/BladeSkin/ubuntu-medium-14.fnt +++ /dev/null @@ -1,195 +0,0 @@ -info face=Ubuntu Medium,Bold size=14 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=0 aa=1 padding=0,0,0,0 spacing=1,1 -common lineHeight=16 base=13 scaleW=1024 scaleH=1024 pages=1 packed=0 -page id=0 file=ubuntu-medium-14_00.png -chars count=190 -char id=33 x=1013 y=13 width=4 height=12 xoffset=0 yoffset=2 xadvance=4 page=0 chnl=0 -char id=34 x=362 y=15 width=7 height=6 xoffset=-1 yoffset=1 xadvance=6 page=0 chnl=0 -char id=35 x=877 y=13 width=10 height=11 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=0 -char id=36 x=382 y=0 width=9 height=14 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=0 -char id=37 x=692 y=0 width=13 height=12 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=0 -char id=38 x=745 y=0 width=11 height=12 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=0 -char id=39 x=350 y=15 width=4 height=6 xoffset=-1 yoffset=1 xadvance=4 page=0 chnl=0 -char id=40 x=223 y=0 width=5 height=15 xoffset=0 yoffset=1 xadvance=5 page=0 chnl=0 -char id=41 x=229 y=0 width=5 height=15 xoffset=-1 yoffset=1 xadvance=5 page=0 chnl=0 -char id=42 x=405 y=15 width=8 height=7 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=43 x=555 y=14 width=9 height=9 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 -char id=44 x=345 y=15 width=4 height=6 xoffset=-1 yoffset=10 xadvance=4 page=0 chnl=0 -char id=45 x=276 y=15 width=6 height=3 xoffset=-1 yoffset=7 xadvance=4 page=0 chnl=0 -char id=46 x=312 y=15 width=4 height=5 xoffset=-1 yoffset=9 xadvance=4 page=0 chnl=0 -char id=47 x=142 y=0 width=9 height=15 xoffset=-2 yoffset=1 xadvance=6 page=0 chnl=0 -char id=48 x=813 y=0 width=9 height=12 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=49 x=689 y=14 width=6 height=11 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=0 -char id=50 x=823 y=13 width=9 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=51 x=823 y=0 width=9 height=12 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=52 x=813 y=13 width=9 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=53 x=833 y=0 width=9 height=12 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=54 x=843 y=0 width=9 height=12 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=55 x=803 y=13 width=9 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=56 x=853 y=0 width=9 height=12 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=57 x=863 y=0 width=9 height=12 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=58 x=591 y=14 width=4 height=10 xoffset=-1 yoffset=4 xadvance=4 page=0 chnl=0 -char id=59 x=1008 y=13 width=4 height=12 xoffset=-1 yoffset=4 xadvance=4 page=0 chnl=0 -char id=60 x=545 y=14 width=9 height=9 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 -char id=61 x=434 y=15 width=9 height=7 xoffset=-1 yoffset=5 xadvance=8 page=0 chnl=0 -char id=62 x=535 y=14 width=9 height=9 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 -char id=63 x=986 y=0 width=7 height=12 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=0 -char id=64 x=273 y=0 width=14 height=14 xoffset=-1 yoffset=2 xadvance=14 page=0 chnl=0 -char id=65 x=900 y=13 width=11 height=11 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=0 -char id=66 x=873 y=0 width=9 height=12 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=0 -char id=67 x=769 y=0 width=10 height=12 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=0 -char id=68 x=780 y=0 width=10 height=12 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=0 -char id=69 x=714 y=13 width=8 height=11 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=0 -char id=70 x=705 y=13 width=8 height=11 xoffset=0 yoffset=2 xadvance=8 page=0 chnl=0 -char id=71 x=791 y=0 width=10 height=12 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=0 -char id=72 x=793 y=13 width=9 height=11 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=0 -char id=73 x=685 y=14 width=3 height=11 xoffset=0 yoffset=2 xadvance=4 page=0 chnl=0 -char id=74 x=923 y=0 width=8 height=12 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=75 x=866 y=13 width=10 height=11 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=0 -char id=76 x=696 y=13 width=8 height=11 xoffset=0 yoffset=2 xadvance=7 page=0 chnl=0 -char id=77 x=954 y=13 width=13 height=11 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=0 -char id=78 x=855 y=13 width=10 height=11 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=0 -char id=79 x=706 y=0 width=12 height=12 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 -char id=80 x=783 y=13 width=9 height=11 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=0 -char id=81 x=288 y=0 width=12 height=14 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 -char id=82 x=773 y=13 width=9 height=11 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=0 -char id=83 x=883 y=0 width=9 height=12 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=84 x=763 y=13 width=9 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=85 x=893 y=0 width=9 height=12 xoffset=0 yoffset=2 xadvance=10 page=0 chnl=0 -char id=86 x=888 y=13 width=11 height=11 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=0 -char id=87 x=983 y=13 width=14 height=11 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=0 -char id=88 x=844 y=13 width=10 height=11 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=0 -char id=89 x=833 y=13 width=10 height=11 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=0 -char id=90 x=753 y=13 width=9 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=91 x=235 y=0 width=5 height=15 xoffset=0 yoffset=1 xadvance=5 page=0 chnl=0 -char id=92 x=152 y=0 width=9 height=15 xoffset=-2 yoffset=1 xadvance=6 page=0 chnl=0 -char id=93 x=241 y=0 width=5 height=15 xoffset=-1 yoffset=1 xadvance=5 page=0 chnl=0 -char id=94 x=424 y=15 width=9 height=7 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=95 x=283 y=15 width=8 height=3 xoffset=-1 yoffset=13 xadvance=7 page=0 chnl=0 -char id=96 x=329 y=15 width=5 height=5 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=0 -char id=97 x=622 y=14 width=8 height=10 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=98 x=603 y=0 width=8 height=13 xoffset=0 yoffset=1 xadvance=8 page=0 chnl=0 -char id=99 x=613 y=14 width=8 height=10 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=100 x=523 y=0 width=9 height=13 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=0 -char id=101 x=661 y=14 width=9 height=10 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 -char id=102 x=1010 y=0 width=6 height=12 xoffset=0 yoffset=1 xadvance=6 page=0 chnl=0 -char id=103 x=903 y=0 width=9 height=12 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 -char id=104 x=932 y=0 width=8 height=12 xoffset=0 yoffset=1 xadvance=8 page=0 chnl=0 -char id=105 x=1003 y=13 width=4 height=12 xoffset=-1 yoffset=1 xadvance=3 page=0 chnl=0 -char id=106 x=247 y=0 width=5 height=15 xoffset=-2 yoffset=1 xadvance=4 page=0 chnl=0 -char id=107 x=941 y=0 width=8 height=12 xoffset=0 yoffset=1 xadvance=8 page=0 chnl=0 -char id=108 x=687 y=0 width=4 height=13 xoffset=0 yoffset=1 xadvance=4 page=0 chnl=0 -char id=109 x=578 y=14 width=12 height=9 xoffset=0 yoffset=4 xadvance=11 page=0 chnl=0 -char id=110 x=486 y=15 width=8 height=9 xoffset=0 yoffset=4 xadvance=8 page=0 chnl=0 -char id=111 x=651 y=14 width=9 height=10 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 -char id=112 x=950 y=0 width=8 height=12 xoffset=0 yoffset=4 xadvance=8 page=0 chnl=0 -char id=113 x=913 y=0 width=9 height=12 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 -char id=114 x=452 y=15 width=6 height=9 xoffset=0 yoffset=4 xadvance=6 page=0 chnl=0 -char id=115 x=596 y=14 width=7 height=10 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 -char id=116 x=1017 y=0 width=6 height=12 xoffset=0 yoffset=2 xadvance=6 page=0 chnl=0 -char id=117 x=604 y=14 width=8 height=10 xoffset=0 yoffset=4 xadvance=8 page=0 chnl=0 -char id=118 x=525 y=14 width=9 height=9 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=119 x=565 y=14 width=12 height=9 xoffset=-1 yoffset=4 xadvance=11 page=0 chnl=0 -char id=120 x=515 y=14 width=9 height=9 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=121 x=802 y=0 width=10 height=12 xoffset=-2 yoffset=4 xadvance=7 page=0 chnl=0 -char id=122 x=477 y=15 width=8 height=9 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=123 x=209 y=0 width=6 height=15 xoffset=-1 yoffset=1 xadvance=5 page=0 chnl=0 -char id=124 x=265 y=0 width=3 height=15 xoffset=0 yoffset=1 xadvance=4 page=0 chnl=0 -char id=125 x=216 y=0 width=6 height=15 xoffset=-1 yoffset=1 xadvance=5 page=0 chnl=0 -char id=126 x=335 y=15 width=9 height=5 xoffset=-1 yoffset=6 xadvance=8 page=0 chnl=0 -char id=160 x=267 y=16 width=1 height=1 xoffset=-1 yoffset=12 xadvance=3 page=0 chnl=0 -char id=161 x=998 y=13 width=4 height=12 xoffset=0 yoffset=4 xadvance=4 page=0 chnl=0 -char id=162 x=612 y=0 width=8 height=13 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=163 x=743 y=13 width=9 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=164 x=505 y=15 width=9 height=9 xoffset=-1 yoffset=3 xadvance=8 page=0 chnl=0 -char id=165 x=733 y=13 width=9 height=11 xoffset=-1 yoffset=2 xadvance=8 page=0 chnl=0 -char id=166 x=269 y=0 width=3 height=15 xoffset=0 yoffset=1 xadvance=4 page=0 chnl=0 -char id=167 x=621 y=0 width=8 height=13 xoffset=-1 yoffset=2 xadvance=7 page=0 chnl=0 -char id=168 x=299 y=15 width=7 height=4 xoffset=-1 yoffset=1 xadvance=6 page=0 chnl=0 -char id=169 x=719 y=0 width=12 height=12 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 -char id=170 x=390 y=15 width=6 height=7 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=0 -char id=171 x=468 y=15 width=8 height=9 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 -char id=172 x=414 y=15 width=9 height=7 xoffset=-1 yoffset=6 xadvance=8 page=0 chnl=0 -char id=173 x=269 y=16 width=6 height=3 xoffset=-1 yoffset=7 xadvance=4 page=0 chnl=0 -char id=174 x=732 y=0 width=12 height=12 xoffset=-1 yoffset=2 xadvance=11 page=0 chnl=0 -char id=175 x=292 y=15 width=6 height=4 xoffset=-1 yoffset=1 xadvance=5 page=0 chnl=0 -char id=176 x=355 y=15 width=6 height=6 xoffset=-1 yoffset=1 xadvance=5 page=0 chnl=0 -char id=177 x=641 y=14 width=9 height=10 xoffset=-1 yoffset=3 xadvance=8 page=0 chnl=0 -char id=178 x=383 y=15 width=6 height=7 xoffset=-1 yoffset=2 xadvance=5 page=0 chnl=0 -char id=179 x=376 y=15 width=6 height=7 xoffset=-1 yoffset=2 xadvance=5 page=0 chnl=0 -char id=180 x=323 y=15 width=5 height=5 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=0 -char id=181 x=959 y=0 width=8 height=12 xoffset=0 yoffset=4 xadvance=8 page=0 chnl=0 -char id=182 x=349 y=0 width=10 height=14 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=0 -char id=183 x=307 y=15 width=4 height=5 xoffset=-1 yoffset=6 xadvance=3 page=0 chnl=0 -char id=184 x=317 y=15 width=5 height=5 xoffset=-1 yoffset=11 xadvance=5 page=0 chnl=0 -char id=185 x=370 y=15 width=5 height=7 xoffset=-1 yoffset=2 xadvance=5 page=0 chnl=0 -char id=186 x=397 y=15 width=7 height=7 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=0 -char id=187 x=459 y=15 width=8 height=9 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 -char id=188 x=940 y=13 width=13 height=11 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=0 -char id=189 x=926 y=13 width=13 height=11 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=0 -char id=190 x=912 y=13 width=13 height=11 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=0 -char id=191 x=994 y=0 width=7 height=12 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=0 -char id=192 x=96 y=0 width=11 height=15 xoffset=-1 yoffset=-2 xadvance=10 page=0 chnl=0 -char id=193 x=108 y=0 width=11 height=15 xoffset=-1 yoffset=-2 xadvance=10 page=0 chnl=0 -char id=194 x=301 y=0 width=11 height=14 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=0 -char id=195 x=313 y=0 width=11 height=14 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=0 -char id=196 x=325 y=0 width=11 height=14 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=0 -char id=197 x=337 y=0 width=11 height=14 xoffset=-1 yoffset=-1 xadvance=10 page=0 chnl=0 -char id=198 x=968 y=13 width=14 height=11 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=0 -char id=199 x=360 y=0 width=10 height=14 xoffset=-1 yoffset=2 xadvance=9 page=0 chnl=0 -char id=200 x=182 y=0 width=8 height=15 xoffset=0 yoffset=-2 xadvance=8 page=0 chnl=0 -char id=201 x=191 y=0 width=8 height=15 xoffset=0 yoffset=-2 xadvance=8 page=0 chnl=0 -char id=202 x=432 y=0 width=8 height=14 xoffset=0 yoffset=-1 xadvance=8 page=0 chnl=0 -char id=203 x=441 y=0 width=8 height=14 xoffset=0 yoffset=-1 xadvance=8 page=0 chnl=0 -char id=204 x=253 y=0 width=5 height=15 xoffset=-1 yoffset=-2 xadvance=4 page=0 chnl=0 -char id=205 x=259 y=0 width=5 height=15 xoffset=0 yoffset=-2 xadvance=4 page=0 chnl=0 -char id=206 x=503 y=0 width=6 height=14 xoffset=-2 yoffset=-1 xadvance=4 page=0 chnl=0 -char id=207 x=495 y=0 width=7 height=14 xoffset=-2 yoffset=-1 xadvance=4 page=0 chnl=0 -char id=208 x=757 y=0 width=11 height=12 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=0 -char id=209 x=371 y=0 width=10 height=14 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=0 -char id=210 x=0 y=0 width=12 height=16 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=0 -char id=211 x=13 y=0 width=12 height=16 xoffset=-1 yoffset=-2 xadvance=11 page=0 chnl=0 -char id=212 x=57 y=0 width=12 height=15 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=0 -char id=213 x=70 y=0 width=12 height=15 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=0 -char id=214 x=83 y=0 width=12 height=15 xoffset=-1 yoffset=-1 xadvance=11 page=0 chnl=0 -char id=215 x=444 y=15 width=7 height=8 xoffset=0 yoffset=4 xadvance=8 page=0 chnl=0 -char id=216 x=510 y=0 width=12 height=13 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=0 -char id=217 x=37 y=0 width=9 height=16 xoffset=0 yoffset=-2 xadvance=10 page=0 chnl=0 -char id=218 x=47 y=0 width=9 height=16 xoffset=0 yoffset=-2 xadvance=10 page=0 chnl=0 -char id=219 x=162 y=0 width=9 height=15 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=0 -char id=220 x=172 y=0 width=9 height=15 xoffset=0 yoffset=-1 xadvance=10 page=0 chnl=0 -char id=221 x=120 y=0 width=10 height=15 xoffset=-1 yoffset=-2 xadvance=9 page=0 chnl=0 -char id=222 x=723 y=13 width=9 height=11 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=0 -char id=223 x=533 y=0 width=9 height=13 xoffset=0 yoffset=1 xadvance=9 page=0 chnl=0 -char id=224 x=450 y=0 width=8 height=14 xoffset=-1 yoffset=0 xadvance=7 page=0 chnl=0 -char id=225 x=459 y=0 width=8 height=14 xoffset=-1 yoffset=0 xadvance=7 page=0 chnl=0 -char id=226 x=630 y=0 width=8 height=13 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=227 x=639 y=0 width=8 height=13 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=228 x=648 y=0 width=8 height=13 xoffset=-1 yoffset=1 xadvance=7 page=0 chnl=0 -char id=229 x=468 y=0 width=8 height=14 xoffset=-1 yoffset=0 xadvance=7 page=0 chnl=0 -char id=230 x=671 y=14 width=13 height=10 xoffset=-1 yoffset=4 xadvance=12 page=0 chnl=0 -char id=231 x=968 y=0 width=8 height=12 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=0 -char id=232 x=392 y=0 width=9 height=14 xoffset=-1 yoffset=0 xadvance=8 page=0 chnl=0 -char id=233 x=402 y=0 width=9 height=14 xoffset=-1 yoffset=0 xadvance=8 page=0 chnl=0 -char id=234 x=543 y=0 width=9 height=13 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=0 -char id=235 x=553 y=0 width=9 height=13 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=0 -char id=236 x=675 y=0 width=5 height=13 xoffset=-1 yoffset=0 xadvance=3 page=0 chnl=0 -char id=237 x=681 y=0 width=5 height=13 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=0 -char id=238 x=1018 y=13 width=6 height=12 xoffset=-2 yoffset=1 xadvance=3 page=0 chnl=0 -char id=239 x=1002 y=0 width=7 height=12 xoffset=-2 yoffset=1 xadvance=3 page=0 chnl=0 -char id=240 x=563 y=0 width=9 height=13 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=0 -char id=241 x=977 y=0 width=8 height=12 xoffset=0 yoffset=1 xadvance=8 page=0 chnl=0 -char id=242 x=412 y=0 width=9 height=14 xoffset=-1 yoffset=0 xadvance=8 page=0 chnl=0 -char id=243 x=422 y=0 width=9 height=14 xoffset=-1 yoffset=0 xadvance=8 page=0 chnl=0 -char id=244 x=573 y=0 width=9 height=13 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=0 -char id=245 x=583 y=0 width=9 height=13 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=0 -char id=246 x=593 y=0 width=9 height=13 xoffset=-1 yoffset=1 xadvance=8 page=0 chnl=0 -char id=247 x=495 y=15 width=9 height=9 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 -char id=248 x=631 y=14 width=9 height=10 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=0 -char id=249 x=477 y=0 width=8 height=14 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=0 -char id=250 x=486 y=0 width=8 height=14 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=0 -char id=251 x=657 y=0 width=8 height=13 xoffset=0 yoffset=1 xadvance=8 page=0 chnl=0 -char id=252 x=666 y=0 width=8 height=13 xoffset=0 yoffset=1 xadvance=8 page=0 chnl=0 -char id=253 x=26 y=0 width=10 height=16 xoffset=-2 yoffset=0 xadvance=7 page=0 chnl=0 -char id=254 x=200 y=0 width=8 height=15 xoffset=0 yoffset=1 xadvance=8 page=0 chnl=0 -char id=255 x=131 y=0 width=10 height=15 xoffset=-2 yoffset=1 xadvance=7 page=0 chnl=0 -kernings count=0 diff --git a/adventure-composer/src/main/resources/versions.properties b/adventure-composer/src/main/resources/versions.properties deleted file mode 100644 index 5349a4cb1..000000000 --- a/adventure-composer/src/main/resources/versions.properties +++ /dev/null @@ -1,6 +0,0 @@ -version=0.5.0 -libgdxVersion=1.4.1 -roboVMVersion=1.0.0-alpha-04 -buildToolsVersion=20.0.0 -androidAPILevel=20 -gwtVersion=2.6.0 diff --git a/adventure-composer/.gitignore b/adventure-editor/.gitignore similarity index 100% rename from adventure-composer/.gitignore rename to adventure-editor/.gitignore diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_check_off.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_check_off.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_check_off.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_check_off.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_check_on.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_check_on.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_check_on.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_check_on.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_check_on_focused.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_check_on_focused.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_check_on_focused.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_check_on_focused.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_default_disabled.9.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_default_disabled.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_default_disabled.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_default_disabled.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_default_focused.9.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_default_focused.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_default_focused.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_default_focused.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_default_normal.9.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_default_normal.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_default_normal.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_default_normal.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_default_pressed.9.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_default_pressed.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_default_pressed.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_default_pressed.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_radio_off.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_radio_off.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_radio_off.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_radio_off.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_radio_on.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_radio_on.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_radio_on.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_radio_on.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_radio_on_focused.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_radio_on_focused.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_radio_on_focused.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_radio_on_focused.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_toggle_off_disabled.9.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_toggle_off_disabled.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_toggle_off_disabled.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_toggle_off_disabled.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_toggle_off_focused.9.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_toggle_off_focused.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_toggle_off_focused.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_toggle_off_focused.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_toggle_off_normal.9.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_toggle_off_normal.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_toggle_off_normal.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_toggle_off_normal.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_toggle_on_focused.9.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_toggle_on_focused.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_toggle_on_focused.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_toggle_on_focused.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_toggle_on_normal.9.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_toggle_on_normal.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_toggle_on_normal.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_toggle_on_normal.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_toggle_on_pressed.9.png b/adventure-editor/assets-raw/editor/BladeSkin/btn_toggle_on_pressed.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/btn_toggle_on_pressed.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/btn_toggle_on_pressed.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/gen.sh b/adventure-editor/assets-raw/editor/BladeSkin/gen.sh similarity index 90% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/gen.sh rename to adventure-editor/assets-raw/editor/BladeSkin/gen.sh index 27ce09cd7..a4ed603f2 100755 --- a/adventure-composer/assets-raw/editor/BladeSkin-atlas/gen.sh +++ b/adventure-editor/assets-raw/editor/BladeSkin/gen.sh @@ -1,7 +1,7 @@ #!/bin/sh -VERSION=1.3.1 +VERSION=1.11.0 LIBGDX_BASE_PATH=~/.gradle/caches/modules-2/files-2.1/com.badlogicgames.gdx/ GDX_PATH=`find $LIBGDX_BASE_PATH -name gdx-$VERSION.jar` GDX_TOOLS_PATH=`find $LIBGDX_BASE_PATH -name gdx-tools-$VERSION.jar` -java -cp $GDX_PATH:$GDX_TOOLS_PATH com.badlogic.gdx.tools.texturepacker.TexturePacker images ../../../src/main/resources/skin/BladeSkin BladeSkin-ldpi +java -cp $GDX_PATH:$GDX_TOOLS_PATH com.badlogic.gdx.tools.texturepacker.TexturePacker images ../../../src/main/resources/skin/BladeSkin blade-skin diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/icon-blitz.png b/adventure-editor/assets-raw/editor/BladeSkin/icon-blitz.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/icon-blitz.png rename to adventure-editor/assets-raw/editor/BladeSkin/icon-blitz.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/icon-blitz_pressed.png b/adventure-editor/assets-raw/editor/BladeSkin/icon-blitz_pressed.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/icon-blitz_pressed.png rename to adventure-editor/assets-raw/editor/BladeSkin/icon-blitz_pressed.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/pack.json b/adventure-editor/assets-raw/editor/BladeSkin/pack.json similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/pack.json rename to adventure-editor/assets-raw/editor/BladeSkin/pack.json diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll.9.png b/adventure-editor/assets-raw/editor/BladeSkin/scroll.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/scroll.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll_corner.9.png b/adventure-editor/assets-raw/editor/BladeSkin/scroll_corner.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll_corner.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/scroll_corner.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll_horizontal.9.png b/adventure-editor/assets-raw/editor/BladeSkin/scroll_horizontal.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll_horizontal.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/scroll_horizontal.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll_horizontal_knob.9.png b/adventure-editor/assets-raw/editor/BladeSkin/scroll_horizontal_knob.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll_horizontal_knob.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/scroll_horizontal_knob.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll_opaque.9.png b/adventure-editor/assets-raw/editor/BladeSkin/scroll_opaque.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll_opaque.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/scroll_opaque.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll_vertical.9.png b/adventure-editor/assets-raw/editor/BladeSkin/scroll_vertical.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll_vertical.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/scroll_vertical.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll_vertical_knob.9.png b/adventure-editor/assets-raw/editor/BladeSkin/scroll_vertical_knob.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scroll_vertical_knob.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/scroll_vertical_knob.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_control_normal.png b/adventure-editor/assets-raw/editor/BladeSkin/scrubber_control_normal.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_control_normal.png rename to adventure-editor/assets-raw/editor/BladeSkin/scrubber_control_normal.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_primary.9.png b/adventure-editor/assets-raw/editor/BladeSkin/scrubber_primary.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_primary.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/scrubber_primary.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_secondary.9.png b/adventure-editor/assets-raw/editor/BladeSkin/scrubber_secondary.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_secondary.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/scrubber_secondary.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_track.9.png b/adventure-editor/assets-raw/editor/BladeSkin/scrubber_track.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_track.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/scrubber_track.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_vertical_primary.9.png b/adventure-editor/assets-raw/editor/BladeSkin/scrubber_vertical_primary.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_vertical_primary.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/scrubber_vertical_primary.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_vertical_secondary.9.png b/adventure-editor/assets-raw/editor/BladeSkin/scrubber_vertical_secondary.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_vertical_secondary.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/scrubber_vertical_secondary.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_vertical_track.9.png b/adventure-editor/assets-raw/editor/BladeSkin/scrubber_vertical_track.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/scrubber_vertical_track.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/scrubber_vertical_track.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/spinner_default.9.png b/adventure-editor/assets-raw/editor/BladeSkin/spinner_default.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/spinner_default.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/spinner_default.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/spinner_focused.9.png b/adventure-editor/assets-raw/editor/BladeSkin/spinner_focused.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/spinner_focused.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/spinner_focused.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/spinner_pressed.9.png b/adventure-editor/assets-raw/editor/BladeSkin/spinner_pressed.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/spinner_pressed.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/spinner_pressed.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/splitpane_horizontal.9.png b/adventure-editor/assets-raw/editor/BladeSkin/splitpane_horizontal.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/splitpane_horizontal.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/splitpane_horizontal.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/splitpane_vertical.9.png b/adventure-editor/assets-raw/editor/BladeSkin/splitpane_vertical.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/splitpane_vertical.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/splitpane_vertical.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/text.9.png b/adventure-editor/assets-raw/editor/BladeSkin/text.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/text.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/text.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/text_focused.9.png b/adventure-editor/assets-raw/editor/BladeSkin/text_focused.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/text_focused.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/text_focused.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/text_focused_opaque.9.png b/adventure-editor/assets-raw/editor/BladeSkin/text_focused_opaque.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/text_focused_opaque.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/text_focused_opaque.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/text_opaque.9.png b/adventure-editor/assets-raw/editor/BladeSkin/text_opaque.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/text_opaque.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/text_opaque.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/text_selected.9.png b/adventure-editor/assets-raw/editor/BladeSkin/text_selected.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/text_selected.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/text_selected.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/text_selected_opaque.9.png b/adventure-editor/assets-raw/editor/BladeSkin/text_selected_opaque.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/text_selected_opaque.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/text_selected_opaque.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/textfield_cursor.9.png b/adventure-editor/assets-raw/editor/BladeSkin/textfield_cursor.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/textfield_cursor.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/textfield_cursor.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/textfield_default.9.png b/adventure-editor/assets-raw/editor/BladeSkin/textfield_default.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/textfield_default.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/textfield_default.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/textfield_disabled.9.png b/adventure-editor/assets-raw/editor/BladeSkin/textfield_disabled.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/textfield_disabled.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/textfield_disabled.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/textfield_focused.9.png b/adventure-editor/assets-raw/editor/BladeSkin/textfield_focused.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/textfield_focused.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/textfield_focused.9.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/textfield_selection.png b/adventure-editor/assets-raw/editor/BladeSkin/textfield_selection.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/textfield_selection.png rename to adventure-editor/assets-raw/editor/BladeSkin/textfield_selection.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/tree_minus.png b/adventure-editor/assets-raw/editor/BladeSkin/tree_minus.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/tree_minus.png rename to adventure-editor/assets-raw/editor/BladeSkin/tree_minus.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/tree_plus.png b/adventure-editor/assets-raw/editor/BladeSkin/tree_plus.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/tree_plus.png rename to adventure-editor/assets-raw/editor/BladeSkin/tree_plus.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/white_pixel.png b/adventure-editor/assets-raw/editor/BladeSkin/white_pixel.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/white_pixel.png rename to adventure-editor/assets-raw/editor/BladeSkin/white_pixel.png diff --git a/adventure-composer/assets-raw/editor/BladeSkin-atlas/images/window.9.png b/adventure-editor/assets-raw/editor/BladeSkin/window.9.png similarity index 100% rename from adventure-composer/assets-raw/editor/BladeSkin-atlas/images/window.9.png rename to adventure-editor/assets-raw/editor/BladeSkin/window.9.png diff --git a/adventure-composer/assets-raw/editor/editor-icon.svg b/adventure-editor/assets-raw/editor/editor-icon.svg similarity index 94% rename from adventure-composer/assets-raw/editor/editor-icon.svg rename to adventure-editor/assets-raw/editor/editor-icon.svg index 04fc0b027..34bc16e43 100644 --- a/adventure-composer/assets-raw/editor/editor-icon.svg +++ b/adventure-editor/assets-raw/editor/editor-icon.svg @@ -7,33 +7,19 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="128" id="svg2" version="1.1" - inkscape:version="0.48+devel r" - sodipodi:docname="ic_app.svg" + inkscape:version="0.92.4 (5da689c313, 2019-01-14)" + sodipodi:docname="editor-icon.svg" inkscape:export-filename="ic_app16.png" inkscape:export-xdpi="11.25" inkscape:export-ydpi="11.25"> - - - - + id="defs4" /> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + SCENE + + + + + + + + + + + + + + x,y + + + + + + + + + + + + + + animation + repeat + pickup + lookup + talk + use + init + test + leave + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + yoyo + + + + + custom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + P + + + + + + ON + + + + + OFF + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Assets + + + + + + + + + + + + Assets + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Atlas + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + enter + exit + + + + + + + + + + + + + + + + + + + +   + + + + + + + + + + + F + + + + + + + + + + T + + + + + + + + + + + + + + + + + + + + + + + + + + + Atlas + + + + + + + + + + + VERBS + ANIMATION TYPES + ACTORTYPES + PROJECT TOOLBAR + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + P + + + + + + + P + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + x,y + + + + + + + + + + + + + + x,y + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/adventure-editor/assets-raw/editor/icons/eye.png b/adventure-editor/assets-raw/editor/icons/eye.png new file mode 100644 index 000000000..3788e2cfa Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/eye.png differ diff --git a/adventure-editor/assets-raw/editor/icons/eye_disabled.png b/adventure-editor/assets-raw/editor/icons/eye_disabled.png new file mode 100644 index 000000000..5a767cf59 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/eye_disabled.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_3d.png b/adventure-editor/assets-raw/editor/icons/ic_3d.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_3d.png rename to adventure-editor/assets-raw/editor/icons/ic_3d.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_add.png b/adventure-editor/assets-raw/editor/icons/ic_add.png new file mode 100644 index 000000000..e4227c9b4 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_add.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_add_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_add_disabled.png new file mode 100644 index 000000000..3522aef0d Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_add_disabled.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_anchor.png b/adventure-editor/assets-raw/editor/icons/ic_anchor.png new file mode 100644 index 000000000..409e0ca7b Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_anchor.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_animation.png b/adventure-editor/assets-raw/editor/icons/ic_animation.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_animation.png rename to adventure-editor/assets-raw/editor/icons/ic_animation.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_assets.png b/adventure-editor/assets-raw/editor/icons/ic_assets.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_assets.png rename to adventure-editor/assets-raw/editor/icons/ic_assets.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_assets_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_assets_disabled.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_assets_disabled.png rename to adventure-editor/assets-raw/editor/icons/ic_assets_disabled.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_atlases.png b/adventure-editor/assets-raw/editor/icons/ic_atlases.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_atlases.png rename to adventure-editor/assets-raw/editor/icons/ic_atlases.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_atlases_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_atlases_disabled.png new file mode 100644 index 000000000..8a9a72c52 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_atlases_disabled.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_base_actor.png b/adventure-editor/assets-raw/editor/icons/ic_base_actor.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_base_actor.png rename to adventure-editor/assets-raw/editor/icons/ic_base_actor.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_character_actor.png b/adventure-editor/assets-raw/editor/icons/ic_character_actor.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_character_actor.png rename to adventure-editor/assets-raw/editor/icons/ic_character_actor.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_check.png b/adventure-editor/assets-raw/editor/icons/ic_check.png new file mode 100644 index 000000000..e3b55df09 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_check.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_check_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_check_disabled.png new file mode 100644 index 000000000..d8b7c607e Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_check_disabled.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_closed.png b/adventure-editor/assets-raw/editor/icons/ic_closed.png new file mode 100644 index 000000000..d69bf25c2 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_closed.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_closed_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_closed_disabled.png new file mode 100644 index 000000000..bf6efd453 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_closed_disabled.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_copy.png b/adventure-editor/assets-raw/editor/icons/ic_copy.png new file mode 100644 index 000000000..8aa3f88ac Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_copy.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_copy_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_copy_disabled.png new file mode 100644 index 000000000..373512bc7 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_copy_disabled.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_create_all.png b/adventure-editor/assets-raw/editor/icons/ic_create_all.png new file mode 100644 index 000000000..9d5e6eb04 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_create_all.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_create_all_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_create_all_disabled.png new file mode 100644 index 000000000..dafc0ba1c Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_create_all_disabled.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_custom.png b/adventure-editor/assets-raw/editor/icons/ic_custom.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_custom.png rename to adventure-editor/assets-raw/editor/icons/ic_custom.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_delete.png b/adventure-editor/assets-raw/editor/icons/ic_delete.png new file mode 100644 index 000000000..3724bda37 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_delete.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_delete_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_delete_disabled.png new file mode 100644 index 000000000..ad3310af2 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_delete_disabled.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_dialog.png b/adventure-editor/assets-raw/editor/icons/ic_dialog.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_dialog.png rename to adventure-editor/assets-raw/editor/icons/ic_dialog.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_down.png b/adventure-editor/assets-raw/editor/icons/ic_down.png new file mode 100644 index 000000000..7daa95fea Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_down.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_down_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_down_disabled.png new file mode 100644 index 000000000..a8bc9e19d Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_down_disabled.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_edit.png b/adventure-editor/assets-raw/editor/icons/ic_edit.png new file mode 100644 index 000000000..b94aa073c Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_edit.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_edit_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_edit_disabled.png new file mode 100644 index 000000000..ceb402586 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_edit_disabled.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_enter.png b/adventure-editor/assets-raw/editor/icons/ic_enter.png new file mode 100644 index 000000000..3741e759d Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_enter.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_exit.png b/adventure-editor/assets-raw/editor/icons/ic_exit.png new file mode 100644 index 000000000..a7a4f0af5 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_exit.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_eye.png b/adventure-editor/assets-raw/editor/icons/ic_eye.png new file mode 100644 index 000000000..1b9761c60 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_eye.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_eye_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_eye_disabled.png new file mode 100644 index 000000000..484e08716 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_eye_disabled.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_fg_actor.png b/adventure-editor/assets-raw/editor/icons/ic_fg_actor.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_fg_actor.png rename to adventure-editor/assets-raw/editor/icons/ic_fg_actor.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_flip.png b/adventure-editor/assets-raw/editor/icons/ic_flip.png new file mode 100644 index 000000000..b28cb4b3a Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_flip.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_goto.png b/adventure-editor/assets-raw/editor/icons/ic_goto.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_goto.png rename to adventure-editor/assets-raw/editor/icons/ic_goto.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_init.png b/adventure-editor/assets-raw/editor/icons/ic_init.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_init.png rename to adventure-editor/assets-raw/editor/icons/ic_init.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_leave.png b/adventure-editor/assets-raw/editor/icons/ic_leave.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_leave.png rename to adventure-editor/assets-raw/editor/icons/ic_leave.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_left.png b/adventure-editor/assets-raw/editor/icons/ic_left.png new file mode 100644 index 000000000..c5262d377 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_left.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_left_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_left_disabled.png new file mode 100644 index 000000000..d1b432d70 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_left_disabled.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_load.png b/adventure-editor/assets-raw/editor/icons/ic_load.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_load.png rename to adventure-editor/assets-raw/editor/icons/ic_load.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_lookat.png b/adventure-editor/assets-raw/editor/icons/ic_lookat.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_lookat.png rename to adventure-editor/assets-raw/editor/icons/ic_lookat.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_new.png b/adventure-editor/assets-raw/editor/icons/ic_new.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_new.png rename to adventure-editor/assets-raw/editor/icons/ic_new.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_no_scene.png b/adventure-editor/assets-raw/editor/icons/ic_no_scene.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_no_scene.png rename to adventure-editor/assets-raw/editor/icons/ic_no_scene.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_obstacle_actor.png b/adventure-editor/assets-raw/editor/icons/ic_obstacle_actor.png new file mode 100644 index 000000000..0a6a0b957 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_obstacle_actor.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_open.png b/adventure-editor/assets-raw/editor/icons/ic_open.png new file mode 100644 index 000000000..881f0c6c4 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_open.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_open_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_open_disabled.png new file mode 100644 index 000000000..89d4b8003 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_open_disabled.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_package.png b/adventure-editor/assets-raw/editor/icons/ic_package.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_package.png rename to adventure-editor/assets-raw/editor/icons/ic_package.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_package_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_package_disabled.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_package_disabled.png rename to adventure-editor/assets-raw/editor/icons/ic_package_disabled.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_particles.png b/adventure-editor/assets-raw/editor/icons/ic_particles.png new file mode 100644 index 000000000..7f93c9a7f Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_particles.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_paste.png b/adventure-editor/assets-raw/editor/icons/ic_paste.png new file mode 100644 index 000000000..bd6e27d6a Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_paste.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_paste_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_paste_disabled.png new file mode 100644 index 000000000..9dcc0eebe Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_paste_disabled.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_pickup.png b/adventure-editor/assets-raw/editor/icons/ic_pickup.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_pickup.png rename to adventure-editor/assets-raw/editor/icons/ic_pickup.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_play.png b/adventure-editor/assets-raw/editor/icons/ic_play.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_play.png rename to adventure-editor/assets-raw/editor/icons/ic_play.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_play_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_play_disabled.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_play_disabled.png rename to adventure-editor/assets-raw/editor/icons/ic_play_disabled.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_player.png b/adventure-editor/assets-raw/editor/icons/ic_player.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_player.png rename to adventure-editor/assets-raw/editor/icons/ic_player.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_player_small.png b/adventure-editor/assets-raw/editor/icons/ic_player_small.png new file mode 100644 index 000000000..3eae793a6 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_player_small.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_player_small_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_player_small_disabled.png new file mode 100644 index 000000000..1892eb9da Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_player_small_disabled.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_exit.png b/adventure-editor/assets-raw/editor/icons/ic_quit.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_exit.png rename to adventure-editor/assets-raw/editor/icons/ic_quit.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_reload_small.png b/adventure-editor/assets-raw/editor/icons/ic_reload_small.png new file mode 100644 index 000000000..549a03cc2 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_reload_small.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_reload_small_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_reload_small_disabled.png new file mode 100644 index 000000000..f88e20a35 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_reload_small_disabled.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_repeat.png b/adventure-editor/assets-raw/editor/icons/ic_repeat.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_repeat.png rename to adventure-editor/assets-raw/editor/icons/ic_repeat.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_right.png b/adventure-editor/assets-raw/editor/icons/ic_right.png new file mode 100644 index 000000000..6f74a1c6d Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_right.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_right_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_right_disabled.png new file mode 100644 index 000000000..4c2a3e80a Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_right_disabled.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_save.png b/adventure-editor/assets-raw/editor/icons/ic_save.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_save.png rename to adventure-editor/assets-raw/editor/icons/ic_save.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_save_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_save_disabled.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_save_disabled.png rename to adventure-editor/assets-raw/editor/icons/ic_save_disabled.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_spine.png b/adventure-editor/assets-raw/editor/icons/ic_spine.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_spine.png rename to adventure-editor/assets-raw/editor/icons/ic_spine.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_sprite_actor.png b/adventure-editor/assets-raw/editor/icons/ic_sprite_actor.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_sprite_actor.png rename to adventure-editor/assets-raw/editor/icons/ic_sprite_actor.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_talkto.png b/adventure-editor/assets-raw/editor/icons/ic_talkto.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_talkto.png rename to adventure-editor/assets-raw/editor/icons/ic_talkto.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_test.png b/adventure-editor/assets-raw/editor/icons/ic_test.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_test.png rename to adventure-editor/assets-raw/editor/icons/ic_test.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_text.png b/adventure-editor/assets-raw/editor/icons/ic_text.png new file mode 100644 index 000000000..05bc004f2 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_text.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_up.png b/adventure-editor/assets-raw/editor/icons/ic_up.png new file mode 100644 index 000000000..ca3f36283 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_up.png differ diff --git a/adventure-editor/assets-raw/editor/icons/ic_up_disabled.png b/adventure-editor/assets-raw/editor/icons/ic_up_disabled.png new file mode 100644 index 000000000..0c6dfc8ec Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_up_disabled.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_use.png b/adventure-editor/assets-raw/editor/icons/ic_use.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_use.png rename to adventure-editor/assets-raw/editor/icons/ic_use.png diff --git a/adventure-editor/assets-raw/editor/icons/ic_walkzone.png b/adventure-editor/assets-raw/editor/icons/ic_walkzone.png new file mode 100644 index 000000000..f28824b4f Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/ic_walkzone.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/ic_yoyo.png b/adventure-editor/assets-raw/editor/icons/ic_yoyo.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/ic_yoyo.png rename to adventure-editor/assets-raw/editor/icons/ic_yoyo.png diff --git a/adventure-editor/assets-raw/editor/icons/scn_character.png b/adventure-editor/assets-raw/editor/icons/scn_character.png new file mode 100644 index 000000000..63b983c1a Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/scn_character.png differ diff --git a/adventure-editor/assets-raw/editor/icons/scn_move.png b/adventure-editor/assets-raw/editor/icons/scn_move.png new file mode 100644 index 000000000..17e46d95f Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/scn_move.png differ diff --git a/adventure-editor/assets-raw/editor/icons/scn_rotate.png b/adventure-editor/assets-raw/editor/icons/scn_rotate.png new file mode 100644 index 000000000..f2df06e98 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/scn_rotate.png differ diff --git a/adventure-editor/assets-raw/editor/icons/scn_scale.png b/adventure-editor/assets-raw/editor/icons/scn_scale.png new file mode 100644 index 000000000..de76062e2 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/scn_scale.png differ diff --git a/adventure-editor/assets-raw/editor/icons/scn_scale_lock.png b/adventure-editor/assets-raw/editor/icons/scn_scale_lock.png new file mode 100644 index 000000000..ddcbf81d3 Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/scn_scale_lock.png differ diff --git a/adventure-editor/assets-raw/editor/icons/scn_sprite.png b/adventure-editor/assets-raw/editor/icons/scn_sprite.png new file mode 100644 index 000000000..21662dfec Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/scn_sprite.png differ diff --git a/adventure-editor/assets-raw/editor/icons/title.png b/adventure-editor/assets-raw/editor/icons/title.png new file mode 100644 index 000000000..604d3e59b Binary files /dev/null and b/adventure-editor/assets-raw/editor/icons/title.png differ diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/transparent-dark.png b/adventure-editor/assets-raw/editor/icons/transparent-dark.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/transparent-dark.png rename to adventure-editor/assets-raw/editor/icons/transparent-dark.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/images/transparent-light.png b/adventure-editor/assets-raw/editor/icons/transparent-light.png similarity index 100% rename from adventure-composer/assets-raw/editor/icons-atlas/images/transparent-light.png rename to adventure-editor/assets-raw/editor/icons/transparent-light.png diff --git a/adventure-composer/assets-raw/editor/icons-atlas/gen.sh b/adventure-editor/assets-raw/editor/pack_icons.sh similarity index 50% rename from adventure-composer/assets-raw/editor/icons-atlas/gen.sh rename to adventure-editor/assets-raw/editor/pack_icons.sh index a17f2fcae..7523e59d1 100755 --- a/adventure-composer/assets-raw/editor/icons-atlas/gen.sh +++ b/adventure-editor/assets-raw/editor/pack_icons.sh @@ -1,7 +1,10 @@ #!/bin/sh -VERSION=1.3.1 -LIBGDX_BASE_PATH=~/.gradle/caches/modules-2/files-2.1/com.badlogicgames.gdx/ +VERSION=1.9.9 +LIBGDX_BASE_PATH=$HOME/.gradle/caches/modules-2/files-2.1/com.badlogicgames.gdx/ GDX_PATH=`find $LIBGDX_BASE_PATH -name gdx-$VERSION.jar` GDX_TOOLS_PATH=`find $LIBGDX_BASE_PATH -name gdx-tools-$VERSION.jar` +OUT_DIR=../../src/main/resources/images + +cp pack.json $target +java -cp $GDX_PATH:$GDX_TOOLS_PATH com.badlogic.gdx.tools.texturepacker.TexturePacker icons $OUT_DIR icons -java -cp $GDX_PATH:$GDX_TOOLS_PATH com.badlogic.gdx.tools.texturepacker.TexturePacker images ../../../src/main/resources/images icons diff --git a/adventure-editor/assets-raw/editor/title.svg b/adventure-editor/assets-raw/editor/title.svg new file mode 100644 index 000000000..b639747cb --- /dev/null +++ b/adventure-editor/assets-raw/editor/title.svg @@ -0,0 +1,155 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + AdventureEDITOR + + AdventureCOMPOSER + + + Adventure EDITOR + + + + diff --git a/adventure-composer/assets-raw/engine/engine-default-icon.svg b/adventure-editor/assets-raw/engine/engine-default-icon.svg similarity index 100% rename from adventure-composer/assets-raw/engine/engine-default-icon.svg rename to adventure-editor/assets-raw/engine/engine-default-icon.svg diff --git a/adventure-editor/assets-raw/engine/gen-default-icons.sh b/adventure-editor/assets-raw/engine/gen-default-icons.sh new file mode 100755 index 000000000..e4c7f2478 --- /dev/null +++ b/adventure-editor/assets-raw/engine/gen-default-icons.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +#ANDROID ICONS +inkscape -w 192 -h 192 --export-area-page --export-png=../../src/main/resources/projectTmpl/android/res/drawable-xxxhdpi/ic_launcher.png engine-default-icon.svg; +inkscape -w 144 -h 144 --export-area-page --export-png=../../src/main/resources/projectTmpl/android/res/drawable-xxhdpi/ic_launcher.png engine-default-icon.svg; +inkscape -w 96 -h 96 --export-area-page --export-png=../../src/main/resources/projectTmpl/android/res/drawable-xhdpi/ic_launcher.png engine-default-icon.svg; +inkscape -w 72 -h 72 --export-area-page --export-png=../../src/main/resources/projectTmpl/android/res/drawable-hdpi/ic_launcher.png engine-default-icon.svg; +inkscape -w 48 -h 48 --export-area-page --export-png=../../src/main/resources/projectTmpl/android/res/drawable-mdpi/ic_launcher.png engine-default-icon.svg; + +inkscape -w 512 -h 512 --export-area-page --export-png=../../src/main/resources/projectTmpl/android/ic_launcher-web.png engine-default-icon.svg; + + +#DESKTOP +inkscape -w 16 -h 16 --export-area-page --export-png=../../src/main/resources/projectTmpl/desktop/src/icons/icon16.png engine-default-icon.svg; +inkscape -w 32 -h 32 --export-area-page --export-png=../../src/main/resources/projectTmpl/desktop/src/icons/icon32.png engine-default-icon.svg; +inkscape -w 128 -h 128 --export-area-page --export-png=../../src/main/resources/projectTmpl/desktop/src/icons/icon128.png engine-default-icon.svg; + +#IOS +inkscape -w 1024 -h 1024 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/app-store-icon-1024@1x.png engine-default-icon.svg; +inkscape -w 76 -h 76 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/ipad-app-icon-76@1x.png engine-default-icon.svg; +inkscape -w 152 -h 152 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/ipad-app-icon-76@2x.png engine-default-icon.svg; +inkscape -w 20 -h 20 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/ipad-notifications-icon-20@1x.png engine-default-icon.svg; +inkscape -w 40 -h 40 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/ipad-notifications-icon-20@2x.png engine-default-icon.svg; +inkscape -w 167 -h 167 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/ipad-pro-app-icon-83.5@2x.png engine-default-icon.svg; +inkscape -w 29 -h 29 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/ipad-settings-icon-29@1x.png engine-default-icon.svg; +inkscape -w 58 -h 58 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/ipad-settings-icon-29@2x.png engine-default-icon.svg; +inkscape -w 40 -h 40 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/ipad-spotlight-icon-40@1x.png engine-default-icon.svg; +inkscape -w 80 -h 80 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/ipad-spotlight-icon-40@2x.png engine-default-icon.svg; +inkscape -w 120 -h 120 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/iphone-app-icon-60@2x.png engine-default-icon.svg; +inkscape -w 180 -h 180 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/iphone-app-icon-60@3x.png engine-default-icon.svg; +inkscape -w 40 -h 40 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/iphone-notification-icon-20@2x.png engine-default-icon.svg; +inkscape -w 60 -h 60 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/iphone-notification-icon-20@3x.png engine-default-icon.svg; +inkscape -w 80 -h 80 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-icon-40@2x.png engine-default-icon.svg; +inkscape -w 120 -h 120 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-icon-40@3x.png engine-default-icon.svg; +inkscape -w 58 -h 58 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-settings-icon-29@2x.png engine-default-icon.svg; +inkscape -w 87 -h 87 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-settings-icon-29@3x.png engine-default-icon.svg; + +# IOS LAUNCH IMAGES +inkscape -w 750 -h 1334 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Default-375w-667h@2x.png ios-default-images.svg; +inkscape -w 1242 -h 2208 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Default-414w-736h@3x.png ios-default-images.svg; +inkscape -w 640 -h 1136 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Default-568h@2x.png ios-default-images.svg; + +inkscape -w 320 -h 480 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Default.png ios-default-images.svg; +inkscape -w 640 -h 960 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Default@2x.png ios-default-images.svg; +inkscape -w 1536 -h 2008 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Default@2x~ipad.png ios-default-images.svg; +inkscape -w 768 -h 1004 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Default~ipad.png ios-default-images.svg; +inkscape -w 2048 -h 2732 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Default-1024w-1366h@2x~ipad.png ios-default-images.svg; + +# IPhone X +inkscape -w 1125 -h 2436 --export-area-page --export-png=../../src/main/resources/projectTmpl/ios/data/Default-375w-812h@3x.png ios-default-images.svg; + diff --git a/adventure-composer/assets-raw/engine/ui-atlas/gen.sh b/adventure-editor/assets-raw/engine/gen-ui-atlas.sh similarity index 96% rename from adventure-composer/assets-raw/engine/ui-atlas/gen.sh rename to adventure-editor/assets-raw/engine/gen-ui-atlas.sh index a034ac61a..0c5f08623 100755 --- a/adventure-composer/assets-raw/engine/ui-atlas/gen.sh +++ b/adventure-editor/assets-raw/engine/gen-ui-atlas.sh @@ -1,5 +1,5 @@ #!/bin/sh -VERSION=1.3.1 +VERSION=1.6.5 LIBGDX_BASE_PATH=~/.gradle/caches/modules-2/files-2.1/com.badlogicgames.gdx/ GDX_PATH=`find $LIBGDX_BASE_PATH -name gdx-$VERSION.jar` GDX_TOOLS_PATH=`find $LIBGDX_BASE_PATH -name gdx-tools-$VERSION.jar` diff --git a/adventure-editor/assets-raw/engine/help/genhelp b/adventure-editor/assets-raw/engine/help/genhelp new file mode 100755 index 000000000..d97f563db --- /dev/null +++ b/adventure-editor/assets-raw/engine/help/genhelp @@ -0,0 +1,9 @@ +#!/bin/sh + +TARGET_DIR=../../../src/main/resources/projectTmpl/android/assets/ui/1 + +#GENERATE 1920_1080 +inkscape -w 1920 -h 1080 --export-area-page --export-png=$TARGET_DIR/helpDesktop_es.png helpDesktop_es.svg; +inkscape -w 1920 -h 1080 --export-area-page --export-png=$TARGET_DIR/helpDesktop.png helpDesktop_en.svg; +inkscape -w 1920 -h 1080 --export-area-page --export-png=$TARGET_DIR/helpPie_es.png helpPie_es.svg; +inkscape -w 1920 -h 1080 --export-area-page --export-png=$TARGET_DIR/helpPie.png helpPie_en.svg; diff --git a/adventure-editor/assets-raw/engine/help/helpDesktop_en.svg b/adventure-editor/assets-raw/engine/help/helpDesktop_en.svg new file mode 100644 index 000000000..05052412d --- /dev/null +++ b/adventure-editor/assets-raw/engine/help/helpDesktop_en.svg @@ -0,0 +1,340 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + INVENTORY + INTERACTION + + + + + + + + + + + 1. Some objects in the scene can be taken. The player has an inventory of the items he owns.2. The inventory items can be examined and manipulated. 3. You can also use / combine an inventory item with another object in the scene or inventory dragging over the object you want to use. + + + + + + + + action + + examine + + inventory + + diff --git a/adventure-editor/assets-raw/engine/help/helpDesktop_es.svg b/adventure-editor/assets-raw/engine/help/helpDesktop_es.svg new file mode 100644 index 000000000..fb995f21c --- /dev/null +++ b/adventure-editor/assets-raw/engine/help/helpDesktop_es.svg @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + INVENTARIO + INTERACCIÓN + + + + + + + + + + + 1. Algunos objetos de la escena se podrán coger. El jugador dispone de un inventario con los objetos que posee.2. Los objetos del inventario, al igual que los objetos de la escena, se pueden examinar y manipular.3. También se puede usar/combinar un objeto del inventario con otro objeto de la escena o del mismo inventario arrastrándolo sobre el objeto con el que se quiera usar. + + + + + + + + acción + + examinar + + inventario + + diff --git a/adventure-editor/assets-raw/engine/help/helpPie_en.svg b/adventure-editor/assets-raw/engine/help/helpPie_en.svg new file mode 100644 index 000000000..8a7d3e002 --- /dev/null +++ b/adventure-editor/assets-raw/engine/help/helpPie_en.svg @@ -0,0 +1,380 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + INVENTORY + 1. When you hover over an interactive object, its name shows. 2. When you tap on an object or character, a menu will show to select the action to perform. INTERACTION + + + + + + + + + + + 1. Some objects in the scene can be taken. The player has an inventory of the items he owns.2. The inventory items can be examined and manipulated. 3. You can also use / combine an inventory item with another object in the scene or inventory dragging over the object you want to use. + + + + + + + action + + examine + + + + diff --git a/adventure-editor/assets-raw/engine/help/helpPie_es.svg b/adventure-editor/assets-raw/engine/help/helpPie_es.svg new file mode 100644 index 000000000..ea5a2a5ca --- /dev/null +++ b/adventure-editor/assets-raw/engine/help/helpPie_es.svg @@ -0,0 +1,405 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + INVENTARIO + 1. Cuando se pasa sobre un objeto con el que se puede interactuar aparece su nombre. 2. Al pulsar sobre un objeto o personaje, aparecerá un menú para seleccionar la acción a realiza.r. INTERACCIÓN + + + + + + + + + + + 1. Algunos objetos de la escena se podrán coger. El jugador dispone de un inventario con los objetos que posee.2. Al igual que los objetos de la escena, los objetos del inventario se pueden examinar y manipular. 3. También se puede usar/combinar un objeto del inventario con otro objeto de la escena o del mismo inventario arrastrándolo sobre el objeto con el que se quiere usar. + acción + + examinar + + + + + + + + + + diff --git a/adventure-editor/assets-raw/engine/ios-default-images.svg b/adventure-editor/assets-raw/engine/ios-default-images.svg new file mode 100644 index 000000000..824f9d447 --- /dev/null +++ b/adventure-editor/assets-raw/engine/ios-default-images.svg @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + BLADE ENGINE + + A D V E N T U R E + + + diff --git a/adventure-editor/assets-raw/engine/logo/blade_logo3.svg b/adventure-editor/assets-raw/engine/logo/blade_logo3.svg new file mode 100644 index 000000000..809f2efa9 --- /dev/null +++ b/adventure-editor/assets-raw/engine/logo/blade_logo3.svg @@ -0,0 +1,515 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + BLADE ENGINE + + + + + + N + E + W + S + + + + + + N + E + W + S + + + BLADE ENGINE + + A D V E N T U R E + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/adventure-editor/assets-raw/engine/logo/genlogo b/adventure-editor/assets-raw/engine/logo/genlogo new file mode 100644 index 000000000..ba824aab8 --- /dev/null +++ b/adventure-editor/assets-raw/engine/logo/genlogo @@ -0,0 +1,6 @@ +#!/bin/sh + +TARGET_DIR=../../../src/main/resources/projectTmpl/android/assets/ui/1 + +inkscape -d 60 --export-area-page --export-png=$TARGET_DIR/blade_logo.png blade_logo3.svg; + diff --git a/adventure-editor/assets-raw/engine/ui-atlas/back.png b/adventure-editor/assets-raw/engine/ui-atlas/back.png new file mode 100644 index 000000000..840b894df Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/back.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/border_rect.9.png b/adventure-editor/assets-raw/engine/ui-atlas/border_rect.9.png new file mode 100644 index 000000000..4e8dce1fe Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/border_rect.9.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/bubblepointer.png b/adventure-editor/assets-raw/engine/ui-atlas/bubblepointer.png new file mode 100644 index 000000000..20b37d3ec Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/bubblepointer.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/credits.png b/adventure-editor/assets-raw/engine/ui-atlas/credits.png new file mode 100644 index 000000000..83aaa4bca Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/credits.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/debug.png b/adventure-editor/assets-raw/engine/ui-atlas/debug.png new file mode 100644 index 000000000..c77b3649c Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/debug.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/delete.png b/adventure-editor/assets-raw/engine/ui-atlas/delete.png new file mode 100644 index 000000000..f3f26b75a Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/delete.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/dialog_down.png b/adventure-editor/assets-raw/engine/ui-atlas/dialog_down.png new file mode 100644 index 000000000..05fb0fcf5 Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/dialog_down.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/dialog_up.png b/adventure-editor/assets-raw/engine/ui-atlas/dialog_up.png new file mode 100644 index 000000000..5fdf8ac81 Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/dialog_up.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/help.png b/adventure-editor/assets-raw/engine/ui-atlas/help.png new file mode 100644 index 000000000..00cf2fbee Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/help.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/hotspot.png b/adventure-editor/assets-raw/engine/ui-atlas/hotspot.png new file mode 100644 index 000000000..10fed4441 Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/hotspot.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/hotspotpointer.png b/adventure-editor/assets-raw/engine/ui-atlas/hotspotpointer.png new file mode 100644 index 000000000..2d68e479c Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/hotspotpointer.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/inv_down.png b/adventure-editor/assets-raw/engine/ui-atlas/inv_down.png new file mode 100644 index 000000000..9d28436b8 Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/inv_down.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/inv_up.png b/adventure-editor/assets-raw/engine/ui-atlas/inv_up.png new file mode 100644 index 000000000..466c02783 Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/inv_up.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/inventory.png b/adventure-editor/assets-raw/engine/ui-atlas/inventory.png new file mode 100644 index 000000000..abb245869 Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/inventory.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/leave.png b/adventure-editor/assets-raw/engine/ui-atlas/leave.png new file mode 100644 index 000000000..3bc38d948 Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/leave.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/lookat.png b/adventure-editor/assets-raw/engine/ui-atlas/lookat.png new file mode 100644 index 000000000..ce795bc42 Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/lookat.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/menu.png b/adventure-editor/assets-raw/engine/ui-atlas/menu.png new file mode 100644 index 000000000..c3ad50826 Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/menu.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/pack.json b/adventure-editor/assets-raw/engine/ui-atlas/pack.json new file mode 100644 index 000000000..5887d455c --- /dev/null +++ b/adventure-editor/assets-raw/engine/ui-atlas/pack.json @@ -0,0 +1,26 @@ +{ + pot: false, + paddingX: 2, + paddingY: 2, + duplicatePadding: true, + edgePadding: true, + rotation: false, + minWidth: 16, + minHeight: 16, + maxWidth: 4096, + maxHeight: 4096, + stripWhitespaceX: true, + stripWhitespaceY: true, + alphaThreshold: 0, + filterMin: Linear, + filterMag: Linear, + wrapX: ClampToEdge, + wrapY: ClampToEdge, + format: RGBA8888, + alias: true, + outputFormat: png, + jpegQuality: 0.9, + ignoreBlankImages: true, + fast: false, + debug: false, +} diff --git a/adventure-editor/assets-raw/engine/ui-atlas/pickup.png b/adventure-editor/assets-raw/engine/ui-atlas/pickup.png new file mode 100644 index 000000000..394b103b0 Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/pickup.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/plus.png b/adventure-editor/assets-raw/engine/ui-atlas/plus.png new file mode 100644 index 000000000..334b5a5c0 Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/plus.png differ diff --git a/adventure-editor/assets-raw/engine/ui-atlas/pointer.png b/adventure-editor/assets-raw/engine/ui-atlas/pointer.png new file mode 100644 index 000000000..9178819f8 Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/pointer.png differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/border_black_rect4.9.png b/adventure-editor/assets-raw/engine/ui-atlas/rect.9.png similarity index 100% rename from adventure-composer/assets-raw/engine/ui-atlas/images/border_black_rect4.9.png rename to adventure-editor/assets-raw/engine/ui-atlas/rect.9.png diff --git a/adventure-editor/assets-raw/engine/ui-atlas/talkto.png b/adventure-editor/assets-raw/engine/ui-atlas/talkto.png new file mode 100644 index 000000000..7cc7beb6a Binary files /dev/null and b/adventure-editor/assets-raw/engine/ui-atlas/talkto.png differ diff --git a/adventure-composer/assets-raw/engine/ui-atlas/images/white_pixel.png b/adventure-editor/assets-raw/engine/ui-atlas/white_pixel.png similarity index 100% rename from adventure-composer/assets-raw/engine/ui-atlas/images/white_pixel.png rename to adventure-editor/assets-raw/engine/ui-atlas/white_pixel.png diff --git a/adventure-editor/assets-raw/engine/ui.svg b/adventure-editor/assets-raw/engine/ui.svg new file mode 100644 index 000000000..e0c41219b --- /dev/null +++ b/adventure-editor/assets-raw/engine/ui.svg @@ -0,0 +1,1347 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + POINTERS + + MAIN MENU SCREEN + + PIE MENU + + LOAD/SAVE SCREEN + + SCENE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ? + + + + + + + + + + + + + + + + + + + + diff --git a/adventure-editor/build.gradle b/adventure-editor/build.gradle new file mode 100644 index 000000000..980c998d7 --- /dev/null +++ b/adventure-editor/build.gradle @@ -0,0 +1,128 @@ +buildscript { + repositories { + mavenCentral() + } + + dependencies { + classpath "com.badlogicgames.gdx:gdx-tools:1.10.0" + } +} + +apply plugin: "java" +apply plugin: 'application' + +group = 'com.bladecoder.engineeditor' +mainClassName = 'com.bladecoder.engineeditor.Main' + +// java +sourceCompatibility = 1.8 +targetCompatibility = 1.8 +[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' + +applicationDefaultJvmArgs = ['-Djava.awt.headless=true'] + +jar { + manifest.attributes += [ + 'github' : 'https://github.com/bladecoder/bladecoder-adventure-engine/', + 'license' : 'Apache-2.0', + 'group' : project.group, + 'version' : project.version, + 'libgdx' : libgdxVersion, + 'java' : targetCompatibility, + 'timestamp': System.currentTimeMillis() + ] +} + +javadoc { + title = "Adventure Editor" + options { + memberLevel = JavadocMemberLevel.PUBLIC + author true + setUse true + encoding "UTF-8" + } +} + +dependencies { + implementation "com.badlogicgames.gdx:gdx:$libgdxVersion" + implementation "com.badlogicgames.gdx:gdx-freetype:$libgdxVersion" + implementation("com.badlogicgames.gdx:gdx-tools:1.10.0") { + exclude group: 'com.badlogicgames.gdx', module: 'gdx-backend-lwjgl' + } + implementation fileTree(dir: 'libs', include: '*.jar') + implementation "com.badlogicgames.gdx:gdx-backend-lwjgl3:$libgdxVersion" + implementation "com.badlogicgames.gdx:gdx-lwjgl3-angle:$libgdxVersion" + + implementation "com.badlogicgames.gdx:gdx-platform:$libgdxVersion:natives-desktop" + implementation "com.badlogicgames.gdx:gdx-freetype-platform:$libgdxVersion:natives-desktop" + implementation("org.apache.commons:commons-compress:1.21") + implementation "commons-io:commons-io:2.1" + implementation "com.bladecoder.packr:packr:4.1.0" + implementation "eu.infomas:annotation-detector:3.0.5" + implementation "com.strongjoshua:libgdx-inGameConsole:0.9.0" + implementation "com.kotcrab.vis:vis-ui:1.5.2" + implementation "com.bladecoder.ink:blade-ink:$bladeInkVersion" + implementation "com.badlogicgames.gdx-controllers:gdx-controllers-core:$gdxControllersVersion" + implementation "com.badlogicgames.gdx-controllers:gdx-controllers-desktop:$gdxControllersVersion" + + implementation project(":blade-engine") + implementation project(":blade-engine-spine-plugin") +} + +task setVersion(type: WriteProperties) { + + def props = new Properties() + def propFile = project.file("./src/main/resources/versions.properties"); + props.load(new FileReader(propFile)) + + props."version" = version + props."libgdxVersion" = libgdxVersion + props."roboVMVersion" = roboVMVersion + props."androidAPILevel" = androidAPILevel + props."androidGradlePluginVersion" = androidGradlePluginVersion + props."bladeInkVersion" = bladeInkVersion + + setProperties(props); + setOutputFile(propFile); + + doLast { + println "Set version info in versions.properties" + } +} + +processResources.dependsOn 'setVersion' + +// Run `gradle pack` task to generate editor atlases +import com.badlogic.gdx.tools.texturepacker.TexturePacker + +task pack { + + doLast { + TexturePacker.process( + 'adventure-editor/assets-raw/editor/BladeSkin', // Raw assets path. + 'adventure-editor/src/main/resources/skin/BladeSkin', // Output directory. + 'blade-skin' // Name of the generated atlas (without extension). + ) + + TexturePacker.process( + 'adventure-editor/assets-raw/editor/icons', + 'adventure-editor/src/main/resources/images', + 'icons' + ) + + TexturePacker.process( + 'adventure-editor/assets-raw/engine/ui-atlas', + 'adventure-editor/src/main/resources/projectTmpl/assets/ui/1', + 'ui' + ) + } +} + +// include flatpack files in .zip +distZip { + into(project.name + '-' + project.version) { + from '.' + // include desktop and thirdparty folders + include('desktop/*', 'thirdparty/*') + } +} diff --git a/adventure-editor/desktop/com.bladecoder.adventure-editor.appdata.xml b/adventure-editor/desktop/com.bladecoder.adventure-editor.appdata.xml new file mode 100644 index 000000000..007bb829e --- /dev/null +++ b/adventure-editor/desktop/com.bladecoder.adventure-editor.appdata.xml @@ -0,0 +1,54 @@ + + + com.bladecoder.adventure-editor.desktop + adventure-editor + Apache-2.0 + CC0-1.0 + Rafael García Moreno + Classic point and click adventure game engine and editor + https://github.com/bladecoder/bladecoder-adventure-engine + +

+ The Bladecoder Adventure Engine is a set of tools to create interactive graphic adventures (classical point and click games). +

+
+ + + https://cloud.githubusercontent.com/assets/6229260/4420346/1d3a1b8a-4578-11e4-8eec-415f5e27c005.png + + + + + + danigm@wadobo.com + + + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + none + +
diff --git a/adventure-editor/desktop/com.bladecoder.adventure-editor.desktop b/adventure-editor/desktop/com.bladecoder.adventure-editor.desktop new file mode 100644 index 000000000..010c92b6f --- /dev/null +++ b/adventure-editor/desktop/com.bladecoder.adventure-editor.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=adventure-editor +Comment=Classic point and click adventure game engine and editor +GenericName=Bladecoder Adventure Editor +Exec=adventure-editor +Icon=com.bladecoder.adventure-editor +Type=Application +StartupNotify=true +Categories=Development; +Keywords=;bladecoder; diff --git a/adventure-editor/desktop/com.bladecoder.adventure-editor.png b/adventure-editor/desktop/com.bladecoder.adventure-editor.png new file mode 100644 index 000000000..02548298c Binary files /dev/null and b/adventure-editor/desktop/com.bladecoder.adventure-editor.png differ diff --git a/adventure-editor/desktop/com.bladecoder.adventure-editor.svg b/adventure-editor/desktop/com.bladecoder.adventure-editor.svg new file mode 100644 index 000000000..d423aaf8c --- /dev/null +++ b/adventure-editor/desktop/com.bladecoder.adventure-editor.svg @@ -0,0 +1,76 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/adventure-composer/src/dist/LICENSE b/adventure-editor/src/dist/LICENSE similarity index 100% rename from adventure-composer/src/dist/LICENSE rename to adventure-editor/src/dist/LICENSE diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/Ctx.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/Ctx.java similarity index 92% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/Ctx.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/Ctx.java index 87e246728..732f3d06a 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/Ctx.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/Ctx.java @@ -16,10 +16,8 @@ package com.bladecoder.engineeditor; import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.utils.Message; public class Ctx { public static Project project; - public static Message msg; public static EditorAssetManager assetManager; } diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/Editor.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/Editor.java new file mode 100644 index 000000000..84f828456 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/Editor.java @@ -0,0 +1,207 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor; + +import com.badlogic.gdx.ApplicationListener; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input.Keys; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.Scaling; +import com.badlogic.gdx.utils.viewport.ScreenViewport; +import com.bladecoder.engine.ui.BladeSkin; +import com.bladecoder.engine.util.EngineLogger; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.EditorUtils; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.scneditor.ScnEditor; +import com.bladecoder.engineeditor.ui.ActorPanel; +import com.bladecoder.engineeditor.ui.ProjectPanel; +import com.bladecoder.engineeditor.ui.ProjectToolbar; +import com.bladecoder.engineeditor.ui.ScenePanel; +import com.kotcrab.vis.ui.VisUI; +import com.kotcrab.vis.ui.widget.file.FileChooser; +import com.strongjoshua.console.GUIConsole; + +import java.io.File; +import java.io.IOException; + +//TODO: Set TITLE in window bar. Set '*' in the title when modified + +public class Editor implements ApplicationListener { + public static final String SKIN = "skin/BladeSkin/blade-skin.json"; + + Stage stage; + ScnEditor scnEditor; + Skin skin; + + @Override + public void create() { + + if (EditorLogger.debugMode()) { + EngineLogger.setDebug(); + } + + skin = new BladeSkin(Gdx.files.internal(SKIN)); + VisUI.load(); + FileChooser.setDefaultPrefsName("com.bladecoder.engineeditor.filechooser"); + + /* STAGE SETUP */ + stage = new Stage(new ScreenViewport()); + Gdx.input.setInputProcessor(stage); + + setCtx(); + + Message.init(skin); + + scnEditor = new ScnEditor(skin); + scnEditor.setBackground("background"); + skin.getFont("default-font").getData().markupEnabled = true; + + // RIGHT PANEL + ScenePanel scenePanel = new ScenePanel(skin); + ActorPanel actorPanel = new ActorPanel(skin); + + Table rightPanel = new Table(skin); + rightPanel.top().left(); + rightPanel.add(actorPanel).expand().fill().left(); + rightPanel.setBackground("background"); + + SplitPane splitPaneRight = new SplitPane(scnEditor, rightPanel, false, skin); + + splitPaneRight.setSplitAmount(0.75f); + + // LEFT PANEL + ProjectPanel projectPanel = new ProjectPanel(skin); + Image img = new Image(Ctx.assetManager.getIcon("title")); + img.setScaling(Scaling.none); + img.setAlign(Align.left); + + Table leftPanel = new Table(skin); + leftPanel.top().left().padLeft(10); + leftPanel.add(img).expand().fill().padBottom(20).padTop(20).padLeft(0).left(); + leftPanel.row(); + leftPanel.add(new ProjectToolbar(skin)).expandX().fill().left(); + leftPanel.row(); + leftPanel.add(projectPanel).expand().fill().left(); + leftPanel.row(); + leftPanel.add(scenePanel).expand().fill().left(); + leftPanel.setBackground("background"); + + SplitPane splitPaneLeft = new SplitPane(leftPanel, splitPaneRight, false, skin); + splitPaneLeft.setFillParent(true); + splitPaneLeft.setSplitAmount(0.25f); + stage.addActor(splitPaneLeft); + + // LOAD LAST OPEN PROJECT + String lastProject = Ctx.project.getEditorConfig().getProperty(Project.LAST_PROJECT_PROP, ""); + final File lastProjectFile = new File(lastProject); + + if (!lastProject.isEmpty() && lastProjectFile.exists()) { + EditorLogger.debug("Loading previous project: " + lastProject); + + try { + EditorUtils.checkVersionAndLoadProject(lastProjectFile, stage, skin); + } catch (Exception e) { + EditorLogger.error("Error loading previous project.", e); + Ctx.project.closeProject(); + } + } + + stage.setScrollFocus(scnEditor.getScnWidget()); + stage.setKeyboardFocus(scnEditor.getScnWidget()); + + // TooltipManager.getInstance().instant(); + TooltipManager.getInstance().initialTime = 0.2f; + TooltipManager.getInstance().hideAll(); + TooltipManager.getInstance().subsequentTime = 0.2f; + } + + private void setCtx() { + Ctx.project = new Project(); + Ctx.assetManager = new EditorAssetManager(); + + EditorLogger.setConsole(new GUIConsole()); + } + + @Override + public void render() { + Gdx.gl.glClearColor(0, 0, 0, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); + + stage.draw(); + + EditorLogger.drawConsole(); + } + + @Override + public void resize(int width, int height) { + stage.getViewport().update(width, height, true); + EditorLogger.console.refresh(); + } + + @Override + public void pause() { + + } + + @Override + public void resume() { + + } + + @Override + public void dispose() { + scnEditor.dispose(); + stage.dispose(); + EditorLogger.console.dispose(); + VisUI.dispose(); + + Ctx.project.saveConfig(); + } + + public void exit() { + if (Ctx.project.isLoaded() && Ctx.project.isModified()) { + new Dialog("Save Project", skin) { + protected void result(Object object) { + if (((Boolean) object).booleanValue()) { + try { + Ctx.project.saveProject(); + } catch (IOException e1) { + String msg = "Something went wrong while saving the actor.\n\n" + + e1.getClass().getSimpleName() + " - " + e1.getMessage(); + Message.showMsgDialog(getStage(), "Error", msg); + + EditorLogger.printStackTrace(e1); + } + } + + ((Main) Gdx.app).exitSaved(); + } + }.text("Save changes to project?").button("Yes", true).button("No", false).key(Keys.ENTER, true) + .key(Keys.ESCAPE, false).show(stage); + + } else { + ((Main) Gdx.app).exitSaved(); + } + + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/EditorAssetManager.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/EditorAssetManager.java similarity index 92% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/EditorAssetManager.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/EditorAssetManager.java index 05588185e..f3ab3b84d 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/EditorAssetManager.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/EditorAssetManager.java @@ -19,7 +19,7 @@ import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion; import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.bladecoder.engine.util.EngineLogger; +import com.bladecoder.engineeditor.common.EditorLogger; public class EditorAssetManager extends AssetManager { public static final String ICON_ATLAS = "images/icons.atlas"; @@ -38,7 +38,7 @@ public TextureRegion getIcon(String name) { AtlasRegion region = a.findRegion(name); if (region == null) { - EngineLogger.error("Region " + name + " not found in icon atlas "); + EditorLogger.error("Region " + name + " not found in icon atlas "); } return region; diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/Main.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/Main.java new file mode 100644 index 000000000..416d7795d --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/Main.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor; + +import com.badlogic.gdx.Files.FileType; +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application; +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration; +import com.badlogic.gdx.utils.SharedLibraryLoader; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.EditorLogger.Levels; +import com.bladecoder.engineeditor.common.Versions; +import org.lwjgl.glfw.GLFW; +import org.lwjgl.glfw.GLFWVidMode; +import org.lwjgl.system.Configuration; +import org.lwjgl.system.macosx.LibC; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor; +import static org.lwjgl.glfw.GLFW.glfwGetVideoMode; + +public class Main extends Lwjgl3Application { + + private final static Lwjgl3ApplicationConfiguration cfg = new Lwjgl3ApplicationConfiguration(); + + public static void main(final String[] args) { + + if (SharedLibraryLoader.isMac && !"1".equals(System.getenv("JAVA_STARTED_ON_FIRST_THREAD_" + LibC.getpid()))) { + System.out.println("MacOs detected. Running in async mode."); + Configuration.GLFW_LIBRARY_NAME.set("glfw_async"); + } + + cfg.setTitle("Adventure Editor v" + Versions.getVersion()); + + cfg.setResizable(true); + cfg.useVsync(true); + + List iconList = new ArrayList<>(); + + if (Main.class.getResource("/images/ic_app64.png") != null) + iconList.add("images/ic_app64.png"); + + if (Main.class.getResource("/images/ic_app32.png") != null) + iconList.add("images/ic_app32.png"); + + if (Main.class.getResource("/images/ic_app16.png") != null) + iconList.add("images/ic_app16.png"); + + cfg.setWindowIcon(FileType.Internal, iconList.toArray(new String[0])); + cfg.setOpenGLEmulation(Lwjgl3ApplicationConfiguration.GLEmulation.GL20, 0, 0); + + GLFW.glfwInit(); + GLFWVidMode glfwGetVideoMode = glfwGetVideoMode(glfwGetPrimaryMonitor()); + cfg.setWindowedMode(Math.max((int) (glfwGetVideoMode.width() * 0.9), 1920 / 2), + Math.max((int) (glfwGetVideoMode.height() * 0.9), 1080 / 2)); + + parseArgs(args); + + new Main(new Editor(), cfg); + } + + private static void parseArgs(String[] args) { + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-f") && i < args.length - 1) { + try { + File file = new File(args[i + 1]).getCanonicalFile(); + Ctx.project.loadProject(file); + } catch (Exception ex) { + EditorLogger.printStackTrace(ex); + } + } else if (args[i].equals("-d")) { + EditorLogger.setDebugLevel(Levels.DEBUG); + } else if (args[i].equals("-opengl")) { + cfg.setOpenGLEmulation(Lwjgl3ApplicationConfiguration.GLEmulation.GL20, 0, 0); + } else if (args[i].equals("-angle")) { + System.out.println("Activating OpenGL emulation through ANGLE."); + cfg.setOpenGLEmulation(Lwjgl3ApplicationConfiguration.GLEmulation.ANGLE_GLES20, 0, 0); + } + } + } + + public Main(Editor editor, Lwjgl3ApplicationConfiguration cfg) { + super(editor, cfg); + } + + @Override + public void exit() { + ((Editor) getApplicationListener()).exit(); + } + + public void exitSaved() { + super.exit(); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ActionDetector.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ActionDetector.java new file mode 100644 index 000000000..651c7742b --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ActionDetector.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.common; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Hashtable; + +import com.badlogic.gdx.utils.reflect.ClassReflection; +import com.badlogic.gdx.utils.reflect.ReflectionException; +import com.bladecoder.engine.actions.Action; +import com.bladecoder.engine.actions.ActionDescription; +import com.bladecoder.engine.actions.ActionFactory; +import com.bladecoder.engine.actions.DisableActionAction; +import com.bladecoder.engine.actions.EndAction; +import com.bladecoder.engine.util.ActionUtils; + +import eu.infomas.annotation.AnnotationDetector; +import eu.infomas.annotation.AnnotationDetector.TypeReporter; + +public class ActionDetector { + + private static HashMap> actions = null; + + public static void detect() { + + actions = new HashMap>(); + + final TypeReporter reporter = new TypeReporter() { + + @SuppressWarnings("unchecked") + @Override + public Class[] annotations() { + return new Class[] { ActionDescription.class }; + } + + @SuppressWarnings("unchecked") + @Override + public void reportTypeAnnotation(Class annotation, String className) { + Class c = null; + + try { + c = ClassReflection.forName(className); + } catch (ReflectionException e) { + EditorLogger.printStackTrace(e); + } + + String name = ActionUtils.getName(c); + + if ( !c.isAssignableFrom(EndAction.class) && + !c.isAssignableFrom(DisableActionAction.class )) + actions.put(name, c); + } + + }; + + final AnnotationDetector cf = new AnnotationDetector(reporter); + + try { + cf.detect(); + } catch (IOException e) { + EditorLogger.printStackTrace(e); + } + } + + public static String[] getActionNames() { + if (actions == null) { + detect(); + } + + ArrayList names = new ArrayList(); + names.addAll(actions.keySet()); + + addCustomActions(names); + + return names.toArray(new String[names.size()]); + } + + public static Action create(String name, HashMap params) { + Class c = actions.get(name); + + if(c == null) { + // Search in custom actions + c = getCustomActionByName(name); + } + + if (c == null) { + EditorLogger.error("Action with name '" + name + "' not found."); + + return null; + } + + try { + return ActionFactory.create(c.getName(), params); + } catch (ClassNotFoundException | ReflectionException e) { + EditorLogger.error("Action with name '" + name + "' not found."); + + return null; + } + } + + private static void addCustomActions(ArrayList names) { + Hashtable> coreClasses = ((FolderClassLoader) ActionFactory.getActionClassLoader()) + .getClasses(); + + for (Class c : coreClasses.values()) { + if (c.getAnnotation(ActionDescription.class) != null) { + names.add(ActionUtils.getName(c)); + } + } + } + + private static Class getCustomActionByName(String name) { + Hashtable> coreClasses = ((FolderClassLoader) ActionFactory.getActionClassLoader()) + .getClasses(); + + for (Class c : coreClasses.values()) { + if (c.getAnnotation(ActionDescription.class) != null) { + if(name.equals(ActionUtils.getName(c))) + return c; + } + } + + return null; + } + +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/AlignUtils.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/AlignUtils.java new file mode 100644 index 000000000..195e6fdc4 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/AlignUtils.java @@ -0,0 +1,54 @@ +package com.bladecoder.engineeditor.common; + +import com.badlogic.gdx.utils.Align; + +public class AlignUtils { + + public static String getAlign(int align) { + switch (align) { + case Align.bottomRight: + return "bottom-right"; + case Align.bottomLeft: + return "bottom-left"; + case Align.topRight: + return "top-right"; + case Align.topLeft: + return "top-left"; + case Align.right: + return "right"; + case Align.left: + return "left"; + case Align.bottom: + return "bottom"; + case Align.top: + return "top"; + case Align.center: + return "center"; + } + + return ""; + } + + public static int getAlign(String s) { + if ("bottom-right".equals(s)) + return Align.bottomRight; + else if ("bottom-left".equals(s)) + return Align.bottomLeft; + else if ("top-right".equals(s)) + return Align.topRight; + else if ("top-left".equals(s)) + return Align.topLeft; + else if ("right".equals(s)) + return Align.right; + else if ("left".equals(s)) + return Align.left; + else if ("bottom".equals(s)) + return Align.bottom; + else if ("top".equals(s)) + return Align.top; + else if ("center".equals(s)) + return Align.center; + + return 0; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/CustomTextureUnpacker.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/CustomTextureUnpacker.java new file mode 100644 index 000000000..b6b95eabc --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/CustomTextureUnpacker.java @@ -0,0 +1,175 @@ +package com.bladecoder.engineeditor.common; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.image.AffineTransformOp; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import com.badlogic.gdx.graphics.g2d.TextureAtlas.TextureAtlasData; +import com.badlogic.gdx.graphics.g2d.TextureAtlas.TextureAtlasData.Page; +import com.badlogic.gdx.graphics.g2d.TextureAtlas.TextureAtlasData.Region; + +/** + * The libgdx TextureUnpacker doesn't support atlases with animation frames. + * + * @author rgarcia + */ +public class CustomTextureUnpacker { + private static final int NINEPATCH_PADDING = 1; + private static final String OUTPUT_TYPE = "png"; + + /** Splits an atlas into seperate image and ninepatch files. */ + public void splitAtlas(TextureAtlasData atlas, String outputDir) { + // create the output directory if it did not exist yet + File outputDirFile = new File(outputDir); + if (!outputDirFile.exists()) { + outputDirFile.mkdirs(); + EditorLogger.debug(String.format("Creating directory: %s", outputDirFile.getPath())); + } + + for (Page page : atlas.getPages()) { + // load the image file belonging to this page as a Buffered Image + BufferedImage img = null; + try { + img = ImageIO.read(page.textureFile.file()); + } catch (IOException e) { + printExceptionAndExit(e); + } + for (Region region : atlas.getRegions()) { + EditorLogger.debug( + String.format("Processing image for %s(%s): x[%s] y[%s] w[%s] h[%s], rotate[%s]", region.name, + region.index, region.left, region.top, region.width, region.height, region.rotate)); + + // check if the page this region is in is currently loaded in a + // Buffered Image + if (region.page == page) { + BufferedImage splitImage = null; + String extension = null; + + // check if the region is a ninepatch or a normal image and + // delegate accordingly + if (region.findValue("split") == null) { + splitImage = extractImage(img, region, outputDirFile, 0); + extension = OUTPUT_TYPE; + } else { + splitImage = extractNinePatch(img, region, outputDirFile); + extension = String.format("9.%s", OUTPUT_TYPE); + } + + // check if the parent directories of this image file exist + // and create them if not + File imgOutput = new File(outputDirFile, String.format("%s.%s", + region.index == -1 ? region.name : region.name + "_" + region.index, extension)); + File imgDir = imgOutput.getParentFile(); + if (!imgDir.exists()) { + System.out.println(String.format("Creating directory: %s", imgDir.getPath())); + imgDir.mkdirs(); + } + + // save the image + try { + ImageIO.write(splitImage, OUTPUT_TYPE, imgOutput); + } catch (IOException e) { + printExceptionAndExit(e); + } + } + } + } + } + + /** + * Extract an image from a texture atlas. + * + * @param page The image file related to the page the region is in + * @param region The region to extract + * @param outputDirFile The output directory + * @param padding padding (in pixels) to apply to the image + * @return The extracted image + */ + private BufferedImage extractImage(BufferedImage page, Region region, File outputDirFile, int padding) { + BufferedImage splitImage = null; + + // get the needed part of the page and rotate if needed + if (region.rotate) { + BufferedImage srcImage = page.getSubimage(region.left, region.top, region.height, region.width); + splitImage = new BufferedImage(region.width, region.height, page.getType()); + + AffineTransform transform = new AffineTransform(); + transform.rotate(Math.toRadians(90.0)); + transform.translate(0, -region.width); + AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR); + op.filter(srcImage, splitImage); + } else { + splitImage = page.getSubimage(region.left, region.top, region.width, region.height); + } + + // draw the image to a bigger one if padding is needed + if (padding > 0) { + BufferedImage paddedImage = new BufferedImage(splitImage.getWidth() + padding * 2, + splitImage.getHeight() + padding * 2, page.getType()); + Graphics2D g2 = paddedImage.createGraphics(); + g2.drawImage(splitImage, padding, padding, null); + g2.dispose(); + return paddedImage; + } else if (region.originalWidth != region.width || region.originalHeight != region.height) { + BufferedImage paddedImage = new BufferedImage(region.originalWidth, region.originalHeight, page.getType()); + Graphics2D g2 = paddedImage.createGraphics(); +// g2.drawImage(splitImage, (int)region.offsetX, region.originalHeight - region.height, null); + g2.drawImage(splitImage, (int) region.offsetX, region.originalHeight - region.height - (int) region.offsetY, + null); + g2.dispose(); + return paddedImage; + } else { + return splitImage; + } + } + + /** + * Extract a ninepatch from a texture atlas, according to the android + * specification. + * + * @see ninepatch + * specification + * @param page The image file related to the page the region is in + * @param region The region to extract + */ + private BufferedImage extractNinePatch(BufferedImage page, Region region, File outputDirFile) { + BufferedImage splitImage = extractImage(page, region, outputDirFile, NINEPATCH_PADDING); + Graphics2D g2 = splitImage.createGraphics(); + g2.setColor(Color.BLACK); + + // Draw the four lines to save the ninepatch's padding and splits + int[] splits = region.findValue("split"); + int startX = splits[0] + NINEPATCH_PADDING; + int endX = region.width - splits[1] + NINEPATCH_PADDING - 1; + int startY = splits[2] + NINEPATCH_PADDING; + int endY = region.height - splits[3] + NINEPATCH_PADDING - 1; + if (endX >= startX) + g2.drawLine(startX, 0, endX, 0); + if (endY >= startY) + g2.drawLine(0, startY, 0, endY); + int[] pads = region.findValue("pad"); + if (pads != null) { + int padStartX = pads[0] + NINEPATCH_PADDING; + int padEndX = region.width - pads[1] + NINEPATCH_PADDING - 1; + int padStartY = pads[2] + NINEPATCH_PADDING; + int padEndY = region.height - pads[3] + NINEPATCH_PADDING - 1; + g2.drawLine(padStartX, splitImage.getHeight() - 1, padEndX, splitImage.getHeight() - 1); + g2.drawLine(splitImage.getWidth() - 1, padStartY, splitImage.getWidth() - 1, padEndY); + } + g2.dispose(); + + return splitImage; + } + + private void printExceptionAndExit(Exception e) { + e.printStackTrace(); + System.exit(1); + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/DesktopUtils.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/DesktopUtils.java similarity index 87% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/DesktopUtils.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/common/DesktopUtils.java index 8d8d8689b..7a727d7cb 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/DesktopUtils.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/DesktopUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ -package com.bladecoder.engineeditor.utils; +package com.bladecoder.engineeditor.common; import java.awt.Component; import java.awt.Desktop; @@ -34,8 +34,7 @@ public class DesktopUtils { public static void browse(Component parent, String uri) { boolean error = false; - if (Desktop.isDesktopSupported() - && Desktop.getDesktop().isSupported(Action.BROWSE)) { + if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Action.BROWSE)) { try { Desktop.getDesktop().browse(new URI(uri)); } catch (URISyntaxException ex) { @@ -68,8 +67,13 @@ public static void removeDir(String dir) throws IOException { File files[] = f.listFiles(); if (files != null) - for (File f2 : files) - Files.delete(f2.toPath()); + for (File f2 : files) { + if (f2.isDirectory()) { + removeDir(f2.getAbsolutePath()); + } else { + Files.delete(f2.toPath()); + } + } Files.deleteIfExists(f.toPath()); } diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/DinamicClassPath.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/DinamicClassPath.java similarity index 97% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/DinamicClassPath.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/common/DinamicClassPath.java index da3c6c34c..b0cb51774 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/DinamicClassPath.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/DinamicClassPath.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ -package com.bladecoder.engineeditor.utils; +package com.bladecoder.engineeditor.common; import java.io.File; import java.io.IOException; diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/EditorCommandExecutor.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/EditorCommandExecutor.java new file mode 100644 index 000000000..10a7dfeb7 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/EditorCommandExecutor.java @@ -0,0 +1,119 @@ +package com.bladecoder.engineeditor.common; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; + +import com.bladecoder.engine.assets.EngineAssetManager; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger.Levels; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.qa.QA; +import com.strongjoshua.console.CommandExecutor; + +public class EditorCommandExecutor extends CommandExecutor { + public void qa() { + QA qa = new QA(); + qa.run(Ctx.project.getWorld()); + } + + public void checkI18NMissingKeys() { + try { + ModelTools.checkI18NMissingKeys(); + EditorLogger.msg("PROCCESS FINISHED: checkI18NMissingKeys."); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + EditorLogger.printStackTrace(e); + } + } + + public void debug(boolean value) { + if (!value) { + EditorLogger.setDebugLevel(Levels.ERROR); + console.setLoggingToSystem(false); + } else { + EditorLogger.setDebugLevel(Levels.DEBUG); + console.setLoggingToSystem(true); + } + } + + public void extractDialogs() { + ModelTools.extractDialogs(); + EditorLogger.msg("ExtractDialogs FINISHED."); + } + + public void cleanI18N() { + Ctx.project.getI18N().cleanI18N(); + EditorLogger.msg("CleanI18N FINISHED."); + } + + public void printUnusedSounds() { + ModelTools.printUnusedSounds(); + EditorLogger.msg("PROCCESS FINISHED."); + } + + public void checkI18N() { + try { + EditorLogger.msg("Check for MODEL missing keys in default translation file for current chapter."); + ModelTools.checkI18NMissingKeys(); + + EditorLogger.msg("Compare translation files with the base file:"); + String[] files = new File(Ctx.project.getAssetPath() + Project.MODEL_PATH).list(new FilenameFilter() { + @Override + public boolean accept(File arg0, String arg1) { + + if (arg1.contains("_") && arg1.endsWith(".properties")) + return true; + + return false; + } + }); + + for (String f : files) { + int idx = f.indexOf('_'); + String base = f.substring(0, idx); + String lang = f.substring(idx + 1, idx + 3); + EditorLogger.msg("Checking " + base + " LANG: " + lang); + I18NUtils.compare(Ctx.project.getAssetPath() + Project.MODEL_PATH, base, null, lang); + } + } catch (Exception e) { + EditorLogger.printStackTrace(e); + } + + EditorLogger.msg("PROCCESS FINISHED."); + } + + public void extractInkTexts(String story, String lang) { + try { + ModelTools.extractInkTexts(Ctx.project.getModelPath() + "/" + story + EngineAssetManager.INK_EXT, lang); + } catch (Exception e) { + EditorLogger.printStackTrace(e); + } + + EditorLogger.msg("PROCCESS FINISHED."); + } + + public void importInkTSV(String tsvFile, String storyName) { + try { + I18NUtils.importTSV(Ctx.project.getAssetPath() + Project.MODEL_PATH, tsvFile, storyName + "-ink", + "default"); + + EditorLogger.msg(tsvFile + " imported sucessfully."); + + } catch (IOException e) { + EditorLogger.error("There was a problem importing the .tsv file."); + EditorLogger.printStackTrace(e); + } + + EditorLogger.msg("PROCCESS FINISHED."); + } + + public void readableInkDialogs(String story, String lang) { + try { + ModelTools.readableInkDialogs(story, lang); + } catch (Exception e) { + EditorLogger.printStackTrace(e); + } + + EditorLogger.msg("PROCCESS FINISHED."); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/EditorLogger.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/EditorLogger.java new file mode 100644 index 000000000..3fe7f0ae1 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/EditorLogger.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.common; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; + +import com.badlogic.gdx.Input.Keys; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.InputListener; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.bladecoder.engine.util.EngineLogger; +import com.strongjoshua.console.Console; +import com.strongjoshua.console.LogLevel; + +public class EditorLogger { + public static enum Levels { + DEBUG, ERROR + }; + + public static Levels level = Levels.ERROR; + + public static Console console; + + private final static List threadedMessages = new ArrayList<>(); + + public static void debug(String message) { + if (level == Levels.DEBUG) { + console.log(message, LogLevel.DEFAULT); + } + } + + public static void msg(String message) { + console.log(message, LogLevel.SUCCESS); + } + + public static synchronized void msgThreaded(String message) { + threadedMessages.add(message); + } + + public static synchronized void drawConsole() { + + if (threadedMessages.size() > 0) { + for (String msg : threadedMessages) + msg(msg); + + threadedMessages.clear(); + } + + console.draw(); + + } + + public static void error(String message) { + console.log(message, LogLevel.ERROR); + } + + public static void error(String message, Exception e) { + console.log(message + " Exception: " + e.getMessage(), LogLevel.ERROR); + + printStackTrace(e); + } + + public static void printStackTrace(Exception e) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + console.log(sw.toString(), LogLevel.ERROR); + e.printStackTrace(); + } + + public static void toggle() { + if (level == Levels.DEBUG) { + level = Levels.ERROR; + console.setLoggingToSystem(false); + } else { + level = Levels.DEBUG; + console.setLoggingToSystem(true); + } + } + + public static boolean debugMode() { + if (level == Levels.DEBUG) + return true; + + return false; + } + + public static Levels getDebugLevel() { + return level; + } + + public static void setDebugLevel(Levels l) { + level = l; + } + + public static void setDebug() { + level = Levels.DEBUG; + EngineLogger.setDebug(); + console.setLoggingToSystem(true); + } + + public static void setConsole(Console console) { + EditorLogger.console = console; + EditorLogger.console.setDisplayKeyID(Keys.F1); + console.setMaxEntries(1000); + + final Stage s = (Stage) console.getInputProcessor(); + final Actor actor = s.getActors().items[0]; + actor.addListener(new InputListener() { + @Override + public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) { + + if (toActor == null) { + s.setScrollFocus(null); + } + } + }); + + console.setCommandExecutor(new EditorCommandExecutor()); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/EditorUtils.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/EditorUtils.java new file mode 100644 index 000000000..4a231184f --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/EditorUtils.java @@ -0,0 +1,91 @@ +package com.bladecoder.engineeditor.common; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import com.badlogic.gdx.Input.Keys; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Dialog; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.utils.Timer; +import com.badlogic.gdx.utils.Timer.Task; +import com.bladecoder.engineeditor.Ctx; + +public final class EditorUtils { + public static void checkVersionAndLoadProject(final File projectToLoad, final Stage stage, Skin skin) + throws FileNotFoundException, IOException { + + if (!Ctx.project.checkVersion(projectToLoad)) { + new Dialog("Update Engine", skin) { + protected void result(Object object) { + if (((Boolean) object).booleanValue()) { + try { + Ctx.project.updateEngineVersion(projectToLoad); + } catch (IOException e) { + String msg = "Something went wrong while updating the engine.\n\n" + + e.getClass().getSimpleName() + " - " + e.getMessage(); + Message.showMsgDialog(getStage(), "Error", msg); + + EditorLogger.error(msg, e); + } + } + + loadProjectWithCustomClasses(projectToLoad, stage); + } + }.text("Your game uses an old (" + Ctx.project.getProjectBladeEngineVersion(projectToLoad) + + ") Engine version. Do you want to update the engine?").button("Yes", true).button("No", false) + .key(Keys.ENTER, true).key(Keys.ESCAPE, false).show(stage); + } else { + loadProjectWithCustomClasses(projectToLoad, stage); + } + } + + public static void loadProjectWithCustomClasses(final File projectToLoad, final Stage stage) { + Message.showMsg(stage, "Loading project...", true); + + Timer.schedule(new Task() { + + @Override + public void run() { + try { + Ctx.project.loadProject(projectToLoad); + Message.hideMsg(); + } catch (Exception ex) { + if (ex.getCause() != null && ex.getCause().getCause() != null + && ex.getCause().getCause() instanceof ClassNotFoundException) { + String msg = "The game have custom actions that can not be loaded. Probably the game needs to be compiled. Trying 'gradlew compile'..."; + Message.showMsg(stage, msg, true); + Timer.post(new Task() { + @Override + public void run() { + if (RunProccess.runGradle(Ctx.project.getProjectDir(), "desktop:compileJava")) { + try { + Ctx.project.loadProject(projectToLoad); + Message.showMsg(stage, "Project loaded Successfully", 3); + } catch (IOException e) { + String msg = e.getClass().getSimpleName() + " - " + e.getMessage(); + Message.hideMsg(); + Message.showMsgDialog(stage, "Error loading project", msg); + } + } else { + Message.hideMsg(); + Message.showMsgDialog(stage, "Error loading project", + "error running 'gradlew desktop:compileJava'"); + } + } + }); + } else { + + String msg = ex.getClass().getSimpleName() + " - " + ex.getMessage(); + Message.hideMsg(); + Message.showMsgDialog(stage, "Error loading project", msg); + } + + EditorLogger.printStackTrace(ex); + } + } + }, 0.05f); + + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ElementUtils.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ElementUtils.java new file mode 100644 index 000000000..087e58d21 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ElementUtils.java @@ -0,0 +1,64 @@ +package com.bladecoder.engineeditor.common; + +import java.io.StringWriter; + +import com.badlogic.gdx.utils.Json; +import com.badlogic.gdx.utils.JsonReader; +import com.badlogic.gdx.utils.JsonValue; +import com.bladecoder.engine.actions.Action; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.serialization.BladeJson; +import com.bladecoder.engine.serialization.BladeJson.Mode; +import com.bladecoder.engine.util.ActionUtils; +import com.bladecoder.engineeditor.Ctx; + +public class ElementUtils { + public static String getCheckedId(String id, String[] values) { + boolean checked = false; + int i = 1; + + String idChecked = id; + + String[] nl = values; + + while (!checked) { + checked = true; + + for (int j = 0; j < nl.length; j++) { + String id2 = nl[j]; + + if (id2.equals(idChecked)) { + i++; + idChecked = id + i; + checked = false; + break; + } + } + } + + return idChecked; + } + + public static Object cloneElement(Object e) { + Json json = new BladeJson(Ctx.project.getWorld(), Mode.MODEL); + + if (e instanceof Action) { + StringWriter buffer = new StringWriter(); + json.setWriter(buffer); + ActionUtils.writeJson((Action) e, json); + String str = buffer.toString(); + EditorLogger.debug(str); + JsonValue root = new JsonReader().parse(str); + return ActionUtils.readJson(Ctx.project.getWorld(), json, root); + } else if (e instanceof Scene) { + String str = json.toJson(e, (Class) null); + Scene s = new Scene(((Scene)e).getWorld()); + JsonValue root = new JsonReader().parse(str); + s.read(json, root); + return s; + } else { + String str = json.toJson(e, (Class) null); + return json.fromJson(e.getClass(), str); + } + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/FolderClassLoader.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/FolderClassLoader.java new file mode 100644 index 000000000..26200dc26 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/FolderClassLoader.java @@ -0,0 +1,113 @@ +package com.bladecoder.engineeditor.common; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Hashtable; + +public class FolderClassLoader extends ClassLoader { + + private String dirName = null; // Path to the .class folder + private Hashtable> classes = new Hashtable>(); // used + // to + // cache + // already + + // defined classes + public FolderClassLoader(String dir) throws IOException { + super(FolderClassLoader.class.getClassLoader()); // calls the parent + // class + // loader's + // constructor + + this.dirName = dir; + + loadClassesInFolder(new File(dirName), null); + } + + public void reload() throws IOException { + loadClassesInFolder(new File(dirName), null); + } + + @Override + public Class loadClass(String className) throws ClassNotFoundException { + return findClass(className); + } + + @Override + public Class findClass(String className) { + Class result = null; + + result = (Class) classes.get(className); // checks in cached classes + if (result != null) { + return result; + } + + try { + return findSystemClass(className); + } catch (Exception e) { + return null; + } + } + + private void loadClassesInFolder(File folder, String classPackage) throws IOException, NoClassDefFoundError { + byte classByte[]; + + File[] list = folder.listFiles(); + + if (list != null) { + + for (File f : list) { + if (f.isDirectory()) { + + String pkg = classPackage; + + if (pkg != null) { + pkg += "."; + pkg += f.getName(); + } else { + pkg = f.getName(); + } + + loadClassesInFolder(f, pkg); + } else if (f.getName().endsWith(".class")) { + InputStream is = null; + + try { + + is = new FileInputStream(f); + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + int nextValue = is.read(); + while (-1 != nextValue) { + byteStream.write(nextValue); + nextValue = is.read(); + } + + classByte = byteStream.toByteArray(); + String className = classPackage + "." + f.getName().substring(0, f.getName().length() - 6); + EditorLogger.debug(">>>>>>>>>> LOADING CLASS: " + className); + + if (classes.get(className) == null) { + + Class result = defineClass(className, classByte, 0, classByte.length, null); + + classes.put(className, result); + } + } catch (NoClassDefFoundError e) { + EditorLogger.error("ERROR - Could not load class: " + e.getMessage()); + } catch (IOException e) { + throw e; + } finally { + is.close(); + } + } + } + } + } + + public Hashtable> getClasses() { + return classes; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/HttpUtils.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/HttpUtils.java new file mode 100644 index 000000000..4aaba2db4 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/HttpUtils.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.common; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; + +/** + * @author Aurelien Ribon | http://www.aurelienribon.com/ + */ +public class HttpUtils { + public static DownloadTask downloadAsync(URL input, OutputStream output, Callback callback) { + final DownloadTask task = new DownloadTask(input, output, callback); + + new Thread(new Runnable() { + @Override + public void run() { + task.download(); + } + }).start(); + + return task; + } + + public interface Callback { + void completed(); + + void canceled(); + + void error(IOException ex); + + void updated(int length, int totalLength); + } + + public static class DownloadTask { + private final URL input; + private final OutputStream output; + private final Callback callback; + private boolean run = true; + + public DownloadTask(URL input, OutputStream output, Callback callback) { + this.input = input; + this.output = output; + this.callback = callback; + } + + public void stop() { + run = false; + } + + public URL getInput() { + return input; + } + + private void download() { + OutputStream os = null; + InputStream is = null; + IOException ex = null; + + try { + HttpURLConnection connection = (HttpURLConnection) input.openConnection(); + connection.setDoInput(true); + connection.setDoOutput(false); + connection.setUseCaches(true); + connection.setConnectTimeout(3000); + connection.connect(); + + is = new BufferedInputStream(connection.getInputStream(), 4096); + os = output; + + byte[] data = new byte[4096]; + int length = connection.getContentLength(); + int total = 0; + + int count; + while (run && (count = is.read(data)) != -1) { + total += count; + os.write(data, 0, count); + if (callback != null) + callback.updated(total, length); + } + + } catch (IOException ex1) { + ex = ex1; + + } finally { + if (os != null) + try { + os.flush(); + os.close(); + } catch (IOException ex1) { + } + if (is != null) + try { + is.close(); + } catch (IOException ex1) { + } + + if (callback != null) { + if (ex != null) + callback.error(ex); + else if (run == true) + callback.completed(); + else + callback.canceled(); + } + } + } + } + + public static String excutePost(String targetURL, String urlParameters) { + HttpURLConnection connection = null; + try { + // Create connection + URL url = new URL(targetURL); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + + connection.setRequestProperty("Content-Length", Integer.toString(urlParameters.getBytes().length)); + connection.setRequestProperty("Content-Language", "en-US"); + + connection.setUseCaches(false); + connection.setDoOutput(true); + + // Send request + DataOutputStream wr = new DataOutputStream(connection.getOutputStream()); + wr.writeBytes(urlParameters); + wr.close(); + + // Get Response + InputStream is = connection.getInputStream(); + BufferedReader rd = new BufferedReader(new InputStreamReader(is)); + StringBuilder response = new StringBuilder(); + + String line; + while ((line = rd.readLine()) != null) { + response.append(line); + response.append('\r'); + } + rd.close(); + return response.toString(); + } catch (Exception e) { + EditorLogger.printStackTrace(e); + return null; + } finally { + if (connection != null) { + connection.disconnect(); + } + } + } + + public static String excuteHTTP(String targetURL, String urlParameters) { + BufferedReader in = null; + StringBuilder response = new StringBuilder(); + + try { + String httpsURL = targetURL; + URL myurl = new URL(httpsURL); + URLConnection con = myurl.openConnection(); + InputStream ins = con.getInputStream(); +// ((HttpURLConnection)con).setRequestMethod("GET"); + InputStreamReader isr = new InputStreamReader(ins); + in = new BufferedReader(isr); + + String inputLine; + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + } catch (IOException e) { + EditorLogger.printStackTrace(e); + return null; + } finally { + if (in != null) + try { + in.close(); + } catch (IOException e) { + return null; + } + } + + return response.toString(); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/I18NUtils.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/I18NUtils.java new file mode 100644 index 000000000..86263b3f2 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/I18NUtils.java @@ -0,0 +1,255 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.common; + +import com.bladecoder.engine.i18n.I18N; +import com.bladecoder.engineeditor.common.OrderedProperties.OrderedPropertiesBuilder; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.Map.Entry; +import java.util.Set; + +public class I18NUtils { + private static final String SEPARATOR = "\t"; + private static final String TSV_EXT = ".tsv"; + private static final String PROPERTIES_EXT = ".properties"; + + public static final void exportTSV(String modelPath, String outFile, final String chapterId, String defaultLocale) + throws FileNotFoundException, IOException { + File defaultChapter = new File(modelPath, chapterId + PROPERTIES_EXT); + + File outputFile; + + if (outFile == null) + outputFile = new File(modelPath, chapterId + TSV_EXT); + else + outputFile = new File(outFile); + + // 1. Find all chapter properties + File[] files = new File(modelPath).listFiles(new FilenameFilter() { + @Override + public boolean accept(File arg0, String arg1) { + if (!arg1.endsWith(PROPERTIES_EXT) || !arg1.startsWith(chapterId + "_")) + return false; + + return true; + } + }); + + OrderedProperties props[] = new OrderedProperties[files.length + 1]; + + props[0] = new OrderedPropertiesBuilder().withSuppressDateInComment(true).withOrdering().build(); + + props[0].load(new InputStreamReader(new FileInputStream(defaultChapter), I18N.ENCODING)); + + for (int i = 1; i < props.length; i++) { + props[i] = new OrderedPropertiesBuilder().withSuppressDateInComment(true).withOrdering().build(); + props[i].load(new InputStreamReader(new FileInputStream(files[i - 1]), I18N.ENCODING)); + } + + // WRITE THE OUTPUT FILE + BufferedWriter writer = null; + + writer = new BufferedWriter(new FileWriter(outputFile)); + + String lang = defaultLocale; + + writer.write("KEY"); + + // write header + for (int i = 0; i < props.length; i++) { + if (i != 0) + lang = files[i - 1].getName().substring(files[i - 1].getName().lastIndexOf('_') + 1, + files[i - 1].getName().lastIndexOf('.')); + + writer.write(SEPARATOR + lang); + } + + writer.write("\n"); + + Set> keySet = props[0].entrySet(); + + for (Entry e : keySet) { + writer.write(e.getKey()); + + for (OrderedProperties p : props) { + if (p.getProperty(e.getKey()) == null) { + writer.write(SEPARATOR + "**" + props[0].getProperty(e.getKey()).replace("\n", "\\n")); + System.out.println("KEY NOT FOUND: " + e); + } else { + writer.write(SEPARATOR + p.getProperty(e.getKey()).replace("\n", "\\n")); + } + } + + writer.write("\n"); + } + + writer.close(); + } + + public static final void importTSV(String modelPath, String tsvFile, String chapterId, String defaultLocale) + throws FileNotFoundException, IOException { + File inputFile = new File(tsvFile); + + try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile), "UTF8"))) { + // get header + String line = br.readLine(); + + if (line != null) { + String[] langs = line.split(SEPARATOR); + OrderedProperties props[] = new OrderedProperties[langs.length - 1]; + + for (int i = 0; i < props.length; i++) { + OrderedPropertiesBuilder builder = new OrderedPropertiesBuilder(); + builder.withSuppressDateInComment(true); + props[i] = builder.build(); + } + + // get keys and texts + while ((line = br.readLine()) != null) { + String[] values = line.split(SEPARATOR); + + if (values.length != langs.length) { + EditorLogger.error("Incorrect line in .tsv: " + line); + continue; + } + + String key = values[0]; + + for (int i = 0; i < props.length; i++) { + String value = values[i + 1]; + if (value != null) + value = value.replace("\\n", "\n"); + + props[i].setProperty(key, value); + } + } + + // save properties + for (int i = 0; i < props.length; i++) { + + String i18nFilename; + + if (langs[i + 1].equals(defaultLocale)) { + i18nFilename = modelPath + "/" + chapterId + PROPERTIES_EXT; + } else { + i18nFilename = modelPath + "/" + chapterId + "_" + langs[i + 1] + PROPERTIES_EXT; + } + + FileOutputStream os = new FileOutputStream(i18nFilename); + Writer out = new OutputStreamWriter(os, I18N.ENCODING); + props[i].store(out, null); + } + } + } + } + + public static final void newLocale(String modelPath, final String chapterId, String defaultLocale, String newLocale) + throws FileNotFoundException, IOException { + File defaultChapter = new File(modelPath, chapterId + PROPERTIES_EXT); + File newChapter = new File(modelPath, chapterId + "_" + newLocale + PROPERTIES_EXT); + + OrderedProperties defaultProp = new OrderedPropertiesBuilder().withSuppressDateInComment(true).withOrdering() + .build(); + OrderedProperties newProp = new OrderedPropertiesBuilder().withSuppressDateInComment(true).withOrdering() + .build(); + + defaultProp.load(new InputStreamReader(new FileInputStream(defaultChapter), I18N.ENCODING)); + + for (Entry e : defaultProp.entrySet()) { + newProp.setProperty(e.getKey(), "**" + defaultProp.getProperty(e.getKey())); + } + + // save new .properties + FileOutputStream os = new FileOutputStream(newChapter); + Writer out = new OutputStreamWriter(os, I18N.ENCODING); + newProp.store(out, newChapter.getName()); + } + + public static final void compare(String modelPath, final String chapterId, String defaultLocale, String destLocale) + throws FileNotFoundException, IOException { + File defaultChapter = new File(modelPath, chapterId + PROPERTIES_EXT); + File destChapter = new File(modelPath, chapterId + "_" + destLocale + PROPERTIES_EXT); + + OrderedProperties defaultProp = new OrderedPropertiesBuilder().withSuppressDateInComment(true).withOrdering() + .build(); + OrderedProperties destProp = new OrderedPropertiesBuilder().withSuppressDateInComment(true).withOrdering() + .build(); + + defaultProp.load(new InputStreamReader(new FileInputStream(defaultChapter), I18N.ENCODING)); + destProp.load(new InputStreamReader(new FileInputStream(destChapter), I18N.ENCODING)); + + // SEARCH FOR NOT EXISTING DEST KEYS + for (Entry e : defaultProp.entrySet()) { + if (destProp.getProperty(e.getKey()) == null) { + EditorLogger.error("Key not found in '" + destLocale + "' locale: " + e.getKey()); + } + } + + // SEARCH FOR NOT EXISTING DEFAULT CHAPTER KEYS + for (Entry e : destProp.entrySet()) { + if (defaultProp.getProperty(e.getKey()) == null) { + EditorLogger.error("Key not found in default locale: " + e.getKey()); + } + } + } + + public static final void sync(String modelPath, final String chapterId, String defaultLocale, String destLocale) + throws FileNotFoundException, IOException { + File defaultChapter = new File(modelPath, chapterId + PROPERTIES_EXT); + File destChapter = new File(modelPath, chapterId + "_" + destLocale + PROPERTIES_EXT); + + OrderedProperties defaultProp = new OrderedPropertiesBuilder().withSuppressDateInComment(true).withOrdering() + .build(); + OrderedProperties destProp = new OrderedPropertiesBuilder().withSuppressDateInComment(true).withOrdering() + .build(); + + defaultProp.load(new InputStreamReader(new FileInputStream(defaultChapter), I18N.ENCODING)); + destProp.load(new InputStreamReader(new FileInputStream(destChapter), I18N.ENCODING)); + + // SEARCH FOR NOT EXISTING DEST KEYS + for (String key : defaultProp.stringPropertyNames()) { + if (destProp.getProperty(key) == null) { + System.out.println("ADDING Key not found in '" + destLocale + "' locale: " + key + "=" + + defaultProp.getProperty(key)); + destProp.setProperty(key, "**" + defaultProp.getProperty(key)); + } + } + + // SEARCH FOR NOT EXISTING DEFAULT CHAPTER KEYS + for (String key : destProp.stringPropertyNames()) { + if (defaultProp.getProperty(key) == null) { + System.out.println("DELETE MANUALLY Key not found in default locale: " + key); + } + } + + // save dest .properties + FileOutputStream os = new FileOutputStream(destChapter); + Writer out = new OutputStreamWriter(os, I18N.ENCODING); + destProp.store(out, destChapter.getName()); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ImageUtils.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ImageUtils.java new file mode 100644 index 000000000..bba0989ba --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ImageUtils.java @@ -0,0 +1,226 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.common; + +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; + +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; + +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.graphics.Pixmap.Format; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.Texture.TextureFilter; +import com.badlogic.gdx.graphics.g2d.TextureAtlas.TextureAtlasData; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.tools.texturepacker.TexturePacker; +import com.badlogic.gdx.tools.texturepacker.TexturePacker.Settings; +import com.bladecoder.engineeditor.Ctx; + +public class ImageUtils { + + public static ImageIcon getImageIcon(URL u, int w) throws IOException { + BufferedImage img = null; + BufferedImage tmp = ImageIO.read(u); + ImageIcon icon = null; + + if (tmp != null) { + float h = (float) tmp.getHeight() * (float) w / tmp.getWidth(); + + img = scaleImage(w, (int) h, tmp, RenderingHints.VALUE_INTERPOLATION_BICUBIC); + icon = new ImageIcon(img); + } + + return icon; + } + + public static BufferedImage scaleImage(int w, int h, BufferedImage img, Object interpolation) { + BufferedImage bi; + + bi = new BufferedImage(w, h, img.getType()); + Graphics2D g2d = bi.createGraphics(); + // g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + // RenderingHints.VALUE_ANTIALIAS_ON); + // g2d.addRenderingHints(new + // RenderingHints(RenderingHints.KEY_RENDERING, + // RenderingHints.VALUE_RENDER_QUALITY)); + + g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolation); + g2d.drawImage(img, 0, 0, w, h, null); + g2d.dispose(); + return bi; + } + + public static void scaleImageFile(File org, File dest, float scale) throws IOException { + BufferedImage destImg = null; + BufferedImage orgImg = ImageIO.read(org); + + if (orgImg != null) { + Object interpolation; + + if (orgImg.getWidth() < 20) { + interpolation = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR; + } else { + interpolation = RenderingHints.VALUE_INTERPOLATION_BICUBIC; + } + + destImg = scaleImage(Math.max(1, (int) (orgImg.getWidth() * scale)), + Math.max(1, (int) (orgImg.getHeight() * scale)), orgImg, interpolation); + ImageIO.write(destImg, org.getName().substring(org.getName().lastIndexOf('.') + 1), dest); + } + } + + /** + * Scale all images in a folder. + * + * WARNING: .etc1 file format is not supported. + * + * @param orgDir + * @param destDir + * @param scale + * @throws IOException + */ + public static void scaleDirFiles(File orgDir, File destDir, float scale) throws IOException { + File[] files = orgDir.listFiles(new FilenameFilter() { + + @Override + public boolean accept(File dir, String name) { + if (name.toLowerCase().endsWith(".png") || name.toLowerCase().endsWith(".jpg")) + return true; + + return false; + } + }); + + if (files != null) { + for (File f : files) { + if (f.getName().endsWith(".9.png")) { // 9 patches doesn't scale + Files.copy(f.toPath(), new File(destDir, f.getName()).toPath()); + } else { + ImageUtils.scaleImageFile(f, new File(destDir, f.getName()), scale); + } + } + } + } + + public static void scaleAtlas(File orgAtlas, File destDir, float scale) throws IOException { + File tmpDir = DesktopUtils.createTempDirectory(); + + EditorLogger.debug("SCALING: " + orgAtlas.getName()); + unpackAtlas(orgAtlas, tmpDir); + + String atlasParentPath = orgAtlas.getParentFile().getAbsolutePath(); + TextureAtlasData atlasData = new TextureAtlasData(new FileHandle(orgAtlas), new FileHandle(atlasParentPath), + false); + + String outputFormat = atlasData.getPages().get(0).textureFile.extension(); + + int maxWH = (int) (getRecommendedAtlasSize() * scale); + + createAtlas(tmpDir.getAbsolutePath(), destDir.getAbsolutePath(), orgAtlas.getName(), scale, maxWH, maxWH, + atlasData.getPages().get(0).minFilter, atlasData.getPages().get(0).magFilter, outputFormat, true); + + DesktopUtils.removeDir(tmpDir.getAbsolutePath()); + } + + public static void unpackAtlas(File orgAtlas, File destDir) { + CustomTextureUnpacker unpacker = new CustomTextureUnpacker(); + String atlasParentPath = orgAtlas.getParentFile().getAbsolutePath(); + TextureAtlasData atlas = new TextureAtlasData(new FileHandle(orgAtlas), new FileHandle(atlasParentPath), false); + unpacker.splitAtlas(atlas, destDir.getAbsolutePath()); + } + + public static void scaleDirAtlases(File orgDir, File destDir, float scale) throws IOException { + File[] files = orgDir.listFiles(new FilenameFilter() { + + @Override + public boolean accept(File dir, String name) { + if (name.toLowerCase().endsWith(".atlas")) + return true; + + return false; + } + }); + + for (File f : files) { + ImageUtils.scaleAtlas(f, destDir, scale); + } + } + + public static int getRecommendedAtlasSize() { + int wWidth = Ctx.project.getWorld().getWidth(); + + return MathUtils.nextPowerOfTwo((int) (wWidth * 2f)); + } + + public static void createAtlas(String inDir, String outdir, String name, float scale, int maxWidth, int maxHeight, + TextureFilter filterMin, TextureFilter filterMag, String outputFormat, boolean stripWhiteSpace) + throws IOException { + Settings settings = new Settings(); + + settings.pot = false; + settings.paddingX = 2; + settings.paddingY = 2; + settings.duplicatePadding = false; + settings.edgePadding = true; + settings.rotation = false; + settings.minWidth = 16; + settings.minWidth = 16; + settings.stripWhitespaceX = stripWhiteSpace; + settings.stripWhitespaceY = stripWhiteSpace; + settings.alphaThreshold = 0; + + settings.filterMin = filterMin; + settings.filterMag = filterMag; + settings.wrapX = Texture.TextureWrap.ClampToEdge; + settings.wrapY = Texture.TextureWrap.ClampToEdge; + settings.format = Format.RGBA8888; + settings.alias = true; + settings.outputFormat = outputFormat; + settings.jpegQuality = 0.9f; + settings.ignoreBlankImages = true; + settings.fast = false; + settings.debug = false; + + settings.maxWidth = maxWidth; + settings.maxHeight = maxHeight; + + EditorLogger.debug("ATLAS MAXWIDTH: " + settings.maxWidth); + + File inTmpDir = new File(inDir); + + // Resize images to create atlas for different resolutions + if (scale != 1.0f) { + inTmpDir = DesktopUtils.createTempDirectory(); + + ImageUtils.scaleDirFiles(new File(inDir), inTmpDir, scale); + } + + TexturePacker.process(settings, inTmpDir.getAbsolutePath(), outdir, + name.endsWith(".atlas") ? name : name + ".atlas"); + + if (scale != 1.0f) { + DesktopUtils.removeDir(inTmpDir.getAbsolutePath()); + } + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/Message.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/Message.java new file mode 100644 index 000000000..dad15eb92 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/Message.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.common; + +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeOut; +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.sequence; + +import com.badlogic.gdx.Input.Keys; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.math.Interpolation; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.actions.Actions; +import com.badlogic.gdx.scenes.scene2d.ui.Dialog; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.Timer; +import com.badlogic.gdx.utils.Timer.Task; + +public class Message { + private static final float FADE_DURATION = 0f; + private static Label msg; + private static Skin skin; + private static boolean isModal; + + public static void init(Skin skin) { + msg = new Label("", skin, "message") { + + @Override + public Actor hit(float x, float y, boolean touchable) { + if (isModal) + return this; + + return null; + } + }; + + Message.skin = skin; + msg.setWrap(true); + msg.setAlignment(Align.center, Align.center); + } + + public static void showMsg(Stage stage, String text) { + showMsg(stage, text, false); + } + + @SuppressWarnings("unused") + public static void showMsg(final Stage stage, final String text, final boolean modal) { + + // show in the next frame to allow calling when no OpenGL context is available. + Timer.post(new Task() { + + @Override + public void run() { + isModal = modal; + + if (text == null) { + hideMsg(); + return; + } + + add(stage, text); + + if (FADE_DURATION > 0) { + msg.getColor().a = 0; + msg.addAction(Actions.fadeIn(FADE_DURATION, Interpolation.fade)); + } + + } + }); + + } + + private static void add(Stage stage, String text) { + msg.clearActions(); + + msg.setText(text); + + GlyphLayout textLayout = new GlyphLayout(); + + textLayout.setText(msg.getStyle().font, text, Color.BLACK, stage.getWidth() * .8f, Align.center, true); + + msg.setSize(textLayout.width + textLayout.height, textLayout.height + textLayout.height * 2); + + if (!stage.getActors().contains(msg, true)) + stage.addActor(msg); + + msg.setPosition(Math.round((stage.getWidth() - msg.getWidth()) / 2), + Math.round((stage.getHeight() - msg.getHeight()) / 2)); + msg.invalidate(); + } + + @SuppressWarnings("unused") + public static void showMsg(final Stage stage, final String text, final float duration) { + + Timer.post(new Task() { + + @Override + public void run() { + isModal = false; + + if (text == null) { + hideMsg(); + return; + } + + add(stage, text); + + if (FADE_DURATION > 0) { + msg.getColor().a = 0; + msg.addAction(sequence(Actions.fadeIn(FADE_DURATION, Interpolation.fade), Actions.delay(duration, + sequence(fadeOut(FADE_DURATION, Interpolation.fade), Actions.removeActor())))); + } else { + msg.addAction(sequence(Actions.delay(duration, Actions.removeActor()))); + } + } + }); + + } + + @SuppressWarnings("unused") + public static void hideMsg() { + isModal = false; + msg.setText(""); + + if (FADE_DURATION > 0) { + msg.addAction(sequence(fadeOut(FADE_DURATION, Interpolation.fade), Actions.removeActor())); + } else { + msg.remove(); + } + } + + public static void showMsgDialog(final Stage stage, final String title, final String msg) { + + Timer.post(new Task() { + + @Override + public void run() { + Message.hideMsg(); + + new Dialog(title, skin).text(msg).button("Close", true).key(Keys.ENTER, true).key(Keys.ESCAPE, false) + .show(stage); + } + }); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ModelTools.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ModelTools.java new file mode 100644 index 000000000..3f65720ac --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ModelTools.java @@ -0,0 +1,683 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.common; + +import com.badlogic.gdx.utils.Base64Coder; +import com.badlogic.gdx.utils.JsonReader; +import com.badlogic.gdx.utils.JsonValue; +import com.badlogic.gdx.utils.JsonWriter.OutputType; +import com.bladecoder.engine.actions.Action; +import com.bladecoder.engine.actions.LookAtAction; +import com.bladecoder.engine.actions.SayAction; +import com.bladecoder.engine.actions.SetCutmodeAction; +import com.bladecoder.engine.assets.EngineAssetManager; +import com.bladecoder.engine.i18n.I18N; +import com.bladecoder.engine.ink.InkManager; +import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.CharacterActor; +import com.bladecoder.engine.model.Dialog; +import com.bladecoder.engine.model.DialogOption; +import com.bladecoder.engine.model.InteractiveActor; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.SoundDesc; +import com.bladecoder.engine.model.Verb; +import com.bladecoder.engine.util.ActionUtils; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.OrderedProperties.OrderedPropertiesBuilder; +import com.bladecoder.engineeditor.model.Project; +import org.apache.commons.io.FileUtils; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class ModelTools { + public static void extractDialogs() { + Map scenes = Ctx.project.getWorld().getScenes(); + + BufferedWriter writer = null; + try { + // create a temporary file + File dFile = new File(Ctx.project.getProjectPath() + "/" + "DIALOGS.md"); + + writer = new BufferedWriter(new FileWriter(dFile)); + + writer.write("# DIALOGS - " + (Ctx.project.getTitle() != null ? Ctx.project.getTitle().toUpperCase() : "") + + "\n\n"); + + for (Scene scn : scenes.values()) { + Map actors = scn.getActors(); + + writer.write("\n## SCENE: " + scn.getId() + "\n\n"); + + HashMap verbs = scn.getVerbManager().getVerbs(); + + // Process SayAction of TALK type + for (Verb v : verbs.values()) { + ArrayList actions = v.getActions(); + + for (Action act : actions) { + + if (act instanceof SayAction) { + String type = ActionUtils.getStringValue(act, "type"); + + if ("TALK".equals(type)) { + String actor = ActionUtils.getStringValue(act, "actor").toUpperCase(); + String rawText = ActionUtils.getStringValue(act, "text"); + String text = Ctx.project.translate(rawText).replace("\\n\\n", "\n").replace("\\n", + "\n"); + + writer.write(actor + ": " + text + "\n"); + } + } + } + } + + for (BaseActor a : actors.values()) { + if (a instanceof InteractiveActor) { + InteractiveActor ia = (InteractiveActor) a; + + verbs = ia.getVerbManager().getVerbs(); + + // Process SayAction of TALK type + for (Verb v : verbs.values()) { + ArrayList actions = v.getActions(); + + for (Action act : actions) { + + if (act instanceof SayAction) { + String type = ActionUtils.getStringValue(act, "type"); + + if ("TALK".equals(type)) { + String actor = ActionUtils.getStringValue(act, "actor").toUpperCase(); + String rawText = ActionUtils.getStringValue(act, "text"); + String text = Ctx.project.translate(rawText).replace("\\n\\n", "\n") + .replace("\\n", "\n"); + + writer.write(actor + ": " + text + "\n"); + } + } + } + } + } + + if (a instanceof CharacterActor) { + CharacterActor ca = (CharacterActor) a; + + HashMap dialogs = ca.getDialogs(); + + if (dialogs == null) + continue; + + // Process SayAction of TALK type + for (Dialog d : dialogs.values()) { + ArrayList options = d.getOptions(); + + if (options.size() > 0) + writer.write("\n**" + ca.getId().toUpperCase() + " - " + d.getId() + "**\n\n"); + + for (DialogOption o : options) { + String text = o.getText(); + String response = o.getResponseText(); + + writer.write(scn.getPlayer().getId().toUpperCase() + ": " + + Ctx.project.translate(text).replace("\\n\\n", "\n").replace("\\n", "\n") + + "\n"); + + if (response != null) + writer.write(ca.getId().toUpperCase() + ": " + Ctx.project.translate(response) + .replace("\\n\\n", "\n").replace("\\n", "\n") + "\n\n"); + } + } + } + } + } + + } catch (Exception e) { + EditorLogger.printStackTrace(e); + } finally { + try { + // Close the writer regardless of what happens... + writer.close(); + } catch (Exception e) { + } + } + } + + public static final void addCutMode() { + Map scenes = Ctx.project.getWorld().getScenes(); + + for (Scene scn : scenes.values()) { + Map actors = scn.getActors(); + + for (BaseActor a : actors.values()) { + if (a instanceof InteractiveActor) { + InteractiveActor ia = (InteractiveActor) a; + + HashMap verbs = ia.getVerbManager().getVerbs(); + + for (Verb v : verbs.values()) { + ArrayList actions = v.getActions(); + + // Don't process verbs for inventory + if (v.getState() != null && v.getState().equalsIgnoreCase("INVENTORY")) + continue; + + if (actions.size() == 1) { + Action act = actions.get(0); + + if (act instanceof LookAtAction || act instanceof SayAction) { + actions.clear(); + + SetCutmodeAction cma1 = new SetCutmodeAction(); + SetCutmodeAction cma2 = new SetCutmodeAction(); + try { + ActionUtils.setParam(cma1, "value", "true"); + ActionUtils.setParam(cma2, "value", "false"); + + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + EditorLogger.printStackTrace(e); + } + + actions.add(cma1); + actions.add(act); + actions.add(cma2); + } + } + } + } + } + } + + Ctx.project.setModified(); + } + + public static void fixSaySubtitleActor() { + Map scenes = Ctx.project.getWorld().getScenes(); + + for (Scene scn : scenes.values()) { + Map actors = scn.getActors(); + + HashMap verbs = scn.getVerbManager().getVerbs(); + + for (Verb v : verbs.values()) { + ArrayList actions = v.getActions(); + + for (Action act : actions) { + + if (act instanceof SayAction) { + try { + + String stringValue = ActionUtils.getStringValue(act, "type"); + + if (stringValue.equals("SUBTITLE")) + ActionUtils.setParam(act, "actor", "$PLAYER"); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + EditorLogger.printStackTrace(e); + return; + } + } + } + } + + for (BaseActor a : actors.values()) { + if (a instanceof InteractiveActor) { + InteractiveActor ia = (InteractiveActor) a; + + verbs = ia.getVerbManager().getVerbs(); + + for (Verb v : verbs.values()) { + ArrayList actions = v.getActions(); + + for (Action act : actions) { + + if (act instanceof SayAction) { + try { + + String stringValue = ActionUtils.getStringValue(act, "type"); + + if (stringValue.equals("SUBTITLE")) + ActionUtils.setParam(act, "actor", "$PLAYER"); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + EditorLogger.printStackTrace(e); + return; + } + } + } + } + } + } + } + + Ctx.project.setModified(); + } + + public static final void checkI18NMissingKeys() + throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { + Map scenes = Ctx.project.getWorld().getScenes(); + + for (Scene scn : scenes.values()) { + Map actors = scn.getActors(); + + // SCENE VERBS + HashMap verbs = scn.getVerbManager().getVerbs(); + + for (Verb v : verbs.values()) { + ArrayList actions = v.getActions(); + + for (Action act : actions) { + + String[] params = ActionUtils.getFieldNames(act); + + for (String p : params) { + String val = ActionUtils.getStringValue(act, p); + + if (val != null && !val.isEmpty() && val.charAt(0) == I18N.PREFIX) { + String trans = Ctx.project.translate(val); + + if (trans == val) { + EditorLogger.error("Key not found: " + val); + } + } + } + } + } + + for (BaseActor a : actors.values()) { + if (a instanceof InteractiveActor) { + InteractiveActor ia = (InteractiveActor) a; + + // DESC + if (ia.getDesc() != null && !ia.getDesc().isEmpty() && ia.getDesc().charAt(0) == I18N.PREFIX) { + String trans = Ctx.project.translate(ia.getDesc()); + + if (trans == ia.getDesc()) { + EditorLogger.error("Key not found: " + ia.getDesc()); + } + } + + // ACTOR VERBS + verbs = ia.getVerbManager().getVerbs(); + + for (Verb v : verbs.values()) { + ArrayList actions = v.getActions(); + + for (Action act : actions) { + + String[] params = ActionUtils.getFieldNames(act); + + for (String p : params) { + String val = ActionUtils.getStringValue(act, p); + + if (val != null && !val.isEmpty() && val.charAt(0) == I18N.PREFIX) { + String trans = Ctx.project.translate(val); + + if (trans == val) { + EditorLogger.error("Key not found: " + val); + } + } + } + } + } + } + + // DIALOGS + if (a instanceof CharacterActor) { + HashMap dialogs = ((CharacterActor) a).getDialogs(); + + if (dialogs != null) { + for (Dialog d : dialogs.values()) { + ArrayList options = d.getOptions(); + + for (DialogOption o : options) { + + if (o.getText() != null && !o.getText().isEmpty() + && o.getText().charAt(0) == I18N.PREFIX) { + String trans = Ctx.project.translate(o.getText()); + + if (trans == o.getText()) { + EditorLogger.error("Key not found: " + o.getText()); + } + } + + if (o.getResponseText() != null && !o.getResponseText().isEmpty() + && o.getResponseText().charAt(0) == I18N.PREFIX) { + String trans = Ctx.project.translate(o.getResponseText()); + + if (trans == o.getResponseText()) { + EditorLogger.error("Key not found: " + o.getResponseText()); + } + } + } + } + } + } + } + } + + } + + public static void printUnusedSounds() { + ArrayList unusedSounds = new ArrayList<>(Arrays.asList(getSoundList())); + + HashMap sounds = Ctx.project.getWorld().getSounds(); + + if (sounds != null) { + for (SoundDesc s : sounds.values()) { + unusedSounds.remove(s.getFilename()); + } + } + + for (String s : unusedSounds) + EditorLogger.error(s); + } + + public static String[] getSoundList() { + String path = Ctx.project.getAssetPath() + Project.SOUND_PATH; + + File f = new File(path); + + String soundFiles[] = f.list(new FilenameFilter() { + + @Override + public boolean accept(File arg0, String arg1) { + if (arg1.endsWith(".ogg") || arg1.endsWith(".wav") || arg1.endsWith(".mp3")) + return true; + + return false; + } + }); + + if (soundFiles == null) + soundFiles = new String[0]; + + Arrays.sort(soundFiles); + + return soundFiles; + } + + public static void extractInkTexts(String file, String lang) throws IOException { + + BufferedReader br = new BufferedReader( + new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); + StringBuilder sb = new StringBuilder(); + + try { + String line = br.readLine(); + + // Replace the BOM mark + if (line != null) + line = line.replace('\uFEFF', ' '); + + while (line != null) { + sb.append(line); + sb.append("\n"); + line = br.readLine(); + } + + } finally { + br.close(); + } + + JsonValue root = new JsonReader().parse(sb.toString()); + + // .tsv generation to help in translation + StringBuilder tsvString = new StringBuilder(); + + // .md generation to have a better readable document of texts + StringBuilder mdString = new StringBuilder(); + + OrderedPropertiesBuilder builder = new OrderedPropertiesBuilder(); + builder.withSuppressDateInComment(true); + OrderedProperties prop = builder.build(); + + extractInkTextsInternal(root, tsvString, mdString, prop); + FileUtils.writeStringToFile(new File(file + ".tsv"), tsvString.toString()); + FileUtils.writeStringToFile(new File(file + ".txt"), mdString.toString()); + + String json = root.toJson(OutputType.json); + FileUtils.writeStringToFile(new File(file), json); + + try { + String file2 = file.substring(0, file.length() - EngineAssetManager.INK_EXT.length()); + + if (lang == null || lang.isEmpty() || lang.equals("default")) + file2 += "-ink.properties"; + else + file2 += "-ink" + "_" + lang + ".properties"; + + FileOutputStream os = new FileOutputStream(file2); + Writer out = new OutputStreamWriter(os, I18N.ENCODING); + prop.store(out, null); + } catch (IOException e) { + EditorLogger.error("ERROR WRITING BUNDLE: " + file + ".properties"); + } + } + + private static void extractInkTextsInternal(JsonValue v, StringBuilder sbTSV, StringBuilder sbMD, + OrderedProperties prop) { + if (v.isArray() || v.isObject()) { + if (v.name != null && v.isArray() && v.parent != null && v.parent.parent != null + && v.parent.parent.parent != null) { + if (v.name.contains("-")) + sbMD.append('\n'); + else if (v.parent.parent.parent.parent == null) + sbMD.append("\n==== " + v.name + " ====\n"); + else if (v.name.equals("s")) + sbMD.append(" * "); + // else + // sbMD.append("\n-- " + v.name + " --\n"); + } + + for (int i = 0; i < v.size; i++) { + JsonValue aValue = v.get(i); + + // Ignore string declr ej. "xxx" + if (i > 0 && v.get(i - 1).isString() && v.get(i - 1).asString().equals("str")) { + // check if inside a choice with [xxx] text. + + // comparison == or !=? + if (v.size > i + 2 && v.get(i + 2).isString() + && (v.get(i + 2).asString().equals("==") || v.get(i + 2).asString().equals("!="))) + continue; + + // find "/ev" + boolean ev = false; + int j = i + 2; + while (j < v.size && !ev) { + JsonValue next = v.get(j); + if (!next.isObject() && next.asString().equals("/ev")) { + ev = true; + } + + j++; + } + + JsonValue next = v.get(j); + if (!next.isObject() || next.get("*") == null) + continue; + } + + // Ignore tags + if (i > 0 && v.get(i - 1).isString() && v.get(i - 1).asString().equals("#")) { + continue; + } + + // Ignore listInt checks + if (v.size > i + 2 && v.get(i + 2).isString() && v.get(i + 2).asString().equals("listInt")) { + continue; + } + + extractInkTextsInternal(aValue, sbTSV, sbMD, prop); + } + + } else if (v.isString() && !v.asString().isEmpty() && v.asString().charAt(0) == '^') { + String value = v.asString().substring(1).trim(); + + if (value.length() == 0 || value.charAt(0) == InkManager.COMMAND_MARK) + return; + + // if we are inside an expression, exit + + + String charName = ""; + int idx = value.indexOf(InkManager.COMMAND_MARK); + + if (idx == -1) { + idx = value.indexOf(InkManager.CHAR_SEPARATOR_MARK); + } + + if (idx != -1) { + String charNameTmp = value.substring(0, idx).trim(); + + if (charNameTmp.indexOf(' ') == -1) { + // charName shouldn't contain spaces, if found means that intentional ':' is used in line. + charName = charNameTmp; + value = value.substring(idx + 1).trim(); + + if (value.length() == 0) + return; + } + } + + String key; + + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + byte[] bytes = value.getBytes(StandardCharsets.UTF_8); + md.update(bytes); + byte[] digest = md.digest(); + key = Base64Coder.encodeLines(digest).substring(0, InkManager.KEY_SIZE); + } catch (NoSuchAlgorithmException e) { + EditorLogger.error("Error encoding key." + e); + return; + } + + prop.setProperty(key, value); + sbTSV.append(key).append("\t").append(charName).append("\t").append(value).append("\n"); + + sbMD.append(charName).append(charName.isEmpty() ? "" : ": ").append(value).append(" (").append(key) + .append(")\n"); + + if (charName.isEmpty()) + v.set("^" + I18N.PREFIX + key); + else + v.set("^" + charName + InkManager.CHAR_SEPARATOR_MARK + I18N.PREFIX + key); + } + } + + public static void readableInkDialogs(String story, String lang) throws IOException { + String file = Ctx.project.getModelPath() + "/" + story + EngineAssetManager.INK_EXT; + + StringBuilder sb = new StringBuilder(); + + try (BufferedReader br = new BufferedReader( + new InputStreamReader(Files.newInputStream(Paths.get(file)), StandardCharsets.UTF_8))) { + String line = br.readLine(); + + // Replace the BOM mark + if (line != null) + line = line.replace('\uFEFF', ' '); + + while (line != null) { + sb.append(line); + sb.append("\n"); + line = br.readLine(); + } + + } + + JsonValue root = new JsonReader().parse(sb.toString()); + + // TODO: Add lang and check if default + File propFile = new File(Ctx.project.getModelPath() + "/" + story + "-ink.properties"); + OrderedProperties langProp = new OrderedPropertiesBuilder().withSuppressDateInComment(true).withOrdering() + .build(); + + langProp.load(new InputStreamReader(Files.newInputStream(propFile.toPath()), I18N.ENCODING)); + + // .md generation to have a better readable document of texts + StringBuilder mdString = new StringBuilder(); + + readableInkDialogsInternal(root, mdString, langProp); + FileUtils.writeStringToFile(new File(Ctx.project.getModelPath() + "/" + story + "-DIALOGS.txt"), + mdString.toString()); + } + + private static void readableInkDialogsInternal(JsonValue v, StringBuilder sbMD, OrderedProperties prop) { + if (v.isArray() || v.isObject()) { + if (v.name != null && v.isArray() && v.parent != null && v.parent.parent != null + && v.parent.parent.parent != null) { + if (v.name.contains("-")) + sbMD.append('\n'); + else if (v.parent.parent.parent.parent == null) + sbMD.append("\n==== ").append(v.name).append(" ====\n"); + else if (v.name.equals("s")) + sbMD.append(" * "); + // else + // sbMD.append("\n-- " + v.name + " --\n"); + } + + for (int i = 0; i < v.size; i++) { + JsonValue aValue = v.get(i); + + readableInkDialogsInternal(aValue, sbMD, prop); + } + + } else if (v.isString() && v.asString().charAt(0) == '^') { + String key = v.asString().substring(1).trim(); + + if (key.length() == 0 || key.charAt(0) == '>') + return; + + int idx = key.indexOf('>'); + String charName = ""; + + if (idx != -1) { + charName = key.substring(0, idx).trim(); + key = key.substring(idx + 1).trim(); + + if (key.length() <= 1) + return; + } + + key = key.substring(1); + + String value = prop.getProperty(key); + + sbMD.append(charName).append(charName.isEmpty() ? "" : ": ").append(value).append(" (").append(key) + .append(")\n"); + } + } + +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/OrderedProperties.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/OrderedProperties.java new file mode 100644 index 000000000..7008c8dfe --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/OrderedProperties.java @@ -0,0 +1,573 @@ +package com.bladecoder.engineeditor.common; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.Serializable; +import java.io.Writer; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.InvalidPropertiesFormatException; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TreeMap; +import java.util.Vector; + +/** + * This class provides an alternative to the JDK's {@link Properties} class. It + * fixes the design flaw of using inheritance over composition, while keeping up + * the same APIs as the original class. Keys and values are guaranteed to be of + * type {@link String}. + *

+ * This class is not synchronized, contrary to the original implementation. + *

+ * As additional functionality, this class keeps its properties in a + * well-defined order. By default, the order is the one in which the individual + * properties have been added, either through explicit API calls or through + * reading them top-to-bottom from a properties file. + *

+ * Also, an optional flag can be set to omit the comment that contains the + * current date when storing the properties to a properties file. + *

+ * Currently, this class does not support the concept of default properties, + * contrary to the original implementation. + *

+ * Note that this implementation is not synchronized. If + * multiple threads access ordered properties concurrently, and at least one of + * the threads modifies the ordered properties structurally, it must be + * synchronized externally. This is typically accomplished by synchronizing on + * some object that naturally encapsulates the properties. + *

+ * Note that the actual (and quite complex) logic of parsing and storing + * properties from and to a stream is delegated to the {@link Properties} class + * from the JDK. + * + * @see Properties + */ + +public final class OrderedProperties implements Serializable { + + private static final long serialVersionUID = 1L; + + private transient Map properties; + private transient boolean suppressDate; + + /** + * Creates a new instance that will keep the properties in the order they have + * been added. Other than the ordering of the keys, this instance behaves like + * an instance of the {@link Properties} class. + */ + public OrderedProperties() { + this(new LinkedHashMap(), false); + } + + private OrderedProperties(Map properties, boolean suppressDate) { + this.properties = properties; + this.suppressDate = suppressDate; + } + + /** + * See {@link Properties#getProperty(String)}. + */ + public String getProperty(String key) { + return properties.get(key); + } + + /** + * See {@link Properties#getProperty(String, String)}. + */ + public String getProperty(String key, String defaultValue) { + String value = properties.get(key); + return (value == null) ? defaultValue : value; + } + + /** + * See {@link Properties#setProperty(String, String)}. + */ + public String setProperty(String key, String value) { + return properties.put(key, value); + } + + /** + * Removes the property with the specified key, if it is present. Returns the + * value of the property, or null if there was no property with the + * specified key. + * + * @param key the key of the property to remove + * @return the previous value of the property, or null if there was no + * property with the specified key + */ + public String removeProperty(String key) { + return properties.remove(key); + } + + /** + * Returns true if there is a property with the specified key. + * + * @param key the key whose presence is to be tested + */ + public boolean containsProperty(String key) { + return properties.containsKey(key); + } + + /** + * See {@link Properties#size()}. + */ + public int size() { + return properties.size(); + } + + /** + * See {@link Properties#isEmpty()}. + */ + public boolean isEmpty() { + return properties.isEmpty(); + } + + /** + * See {@link Properties#propertyNames()}. + */ + public Enumeration propertyNames() { + return new Vector<>(properties.keySet()).elements(); + } + + /** + * See {@link Properties#stringPropertyNames()}. + */ + public Set stringPropertyNames() { + return new LinkedHashSet<>(properties.keySet()); + } + + /** + * See {@link Properties#entrySet()}. + */ + public Set> entrySet() { + return new LinkedHashSet<>(properties.entrySet()); + } + + /** + * See {@link Properties#load(InputStream)}. + */ + public void load(InputStream stream) throws IOException { + CustomProperties customProperties = new CustomProperties(this.properties); + customProperties.load(stream); + } + + /** + * See {@link Properties#load(Reader)}. + */ + public void load(Reader reader) throws IOException { + CustomProperties customProperties = new CustomProperties(this.properties); + customProperties.load(reader); + } + + /** + * See {@link Properties#loadFromXML(InputStream)}. + */ + public void loadFromXML(InputStream stream) throws IOException, InvalidPropertiesFormatException { + CustomProperties customProperties = new CustomProperties(this.properties); + customProperties.loadFromXML(stream); + } + + /** + * See {@link Properties#store(OutputStream, String)}. + */ + public void store(OutputStream stream, String comments) throws IOException { + CustomProperties customProperties = new CustomProperties(this.properties); + if (suppressDate) { + customProperties.store( + new DateSuppressingPropertiesBufferedWriter(new OutputStreamWriter(stream, "8859_1")), comments); + } else { + customProperties.store(stream, comments); + } + } + + /** + * See {@link Properties#store(Writer, String)}. + */ + public void store(Writer writer, String comments) throws IOException { + CustomProperties customProperties = new CustomProperties(this.properties); + if (suppressDate) { + customProperties.store(new DateSuppressingPropertiesBufferedWriter(writer), comments); + } else { + customProperties.store(writer, comments); + } + } + + /** + * See {@link Properties#storeToXML(OutputStream, String)}. + */ + public void storeToXML(OutputStream stream, String comment) throws IOException { + CustomProperties customProperties = new CustomProperties(this.properties); + customProperties.storeToXML(stream, comment); + } + + /** + * See {@link Properties#storeToXML(OutputStream, String, String)}. + */ + public void storeToXML(OutputStream stream, String comment, String encoding) throws IOException { + CustomProperties customProperties = new CustomProperties(this.properties); + customProperties.storeToXML(stream, comment, encoding); + } + + /** + * See {@link Properties#list(PrintStream)}. + */ + public void list(PrintStream stream) { + CustomProperties customProperties = new CustomProperties(this.properties); + customProperties.list(stream); + } + + /** + * See {@link Properties#list(PrintWriter)}. + */ + public void list(PrintWriter writer) { + CustomProperties customProperties = new CustomProperties(this.properties); + customProperties.list(writer); + } + + /** + * Convert this instance to a {@link Properties} instance. + * + * @return the {@link Properties} instance + */ + public Properties toJdkProperties() { + Properties jdkProperties = new Properties(); + for (Map.Entry entry : this.entrySet()) { + jdkProperties.put(entry.getKey(), entry.getValue()); + } + return jdkProperties; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + + if (other == null || getClass() != other.getClass()) { + return false; + } + + OrderedProperties that = (OrderedProperties) other; + return Arrays.equals(properties.entrySet().toArray(), that.properties.entrySet().toArray()); + } + + @Override + public int hashCode() { + return Arrays.hashCode(properties.entrySet().toArray()); + } + + private void writeObject(ObjectOutputStream stream) throws IOException { + stream.defaultWriteObject(); + stream.writeObject(properties); + stream.writeBoolean(suppressDate); + } + + @SuppressWarnings("unchecked") + private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + properties = (Map) stream.readObject(); + suppressDate = stream.readBoolean(); + } + + /** + * See {@link Properties#toString()}. + */ + @Override + public String toString() { + return properties.toString(); + } + + /** + * Creates a new instance that will have both the same property entries and the + * same behavior as the given source. + *

+ * Note that the source instance and the copy instance will share the same + * comparator instance if a custom ordering had been configured on the source. + * + * @param source the source to copy from + * @return the copy + */ + public static OrderedProperties copyOf(OrderedProperties source) { + // create a copy that has the same behaviour + OrderedPropertiesBuilder builder = new OrderedPropertiesBuilder(); + builder.withSuppressDateInComment(source.suppressDate); + if (source.properties instanceof TreeMap) { + builder.withOrdering(((TreeMap) source.properties).comparator()); + } + OrderedProperties result = builder.build(); + + // copy the properties from the source to the target + for (Map.Entry entry : source.entrySet()) { + result.setProperty(entry.getKey(), entry.getValue()); + } + return result; + } + + /** + * Builder for {@link OrderedProperties} instances. + */ + public static final class OrderedPropertiesBuilder { + + private Comparator comparator; + private boolean suppressDate; + + /** + * Use a custom ordering of the keys. + * + * @param comparator the ordering to apply on the keys + * @return the builder + */ + public OrderedPropertiesBuilder withOrdering(Comparator comparator) { + this.comparator = comparator; + return this; + } + + /** + * Suppress the comment that contains the current date when storing the + * properties. + * + * @param suppressDate whether to suppress the comment that contains the current + * date + * @return the builder + */ + public OrderedPropertiesBuilder withSuppressDateInComment(boolean suppressDate) { + this.suppressDate = suppressDate; + return this; + } + + public OrderedPropertiesBuilder withOrderingCaseSensitive() { + this.comparator = new Comparator() { + + @Override + public int compare(String a, String b) { + return a.compareTo(b); + } + }; + + return this; + + } + + public OrderedPropertiesBuilder withOrdering() { + this.comparator = String.CASE_INSENSITIVE_ORDER; + + return this; + } + + /** + * Builds a new {@link OrderedProperties} instance. + * + * @return the new instance + */ + public OrderedProperties build() { + Map properties = (this.comparator != null) ? new TreeMap(comparator) + : new LinkedHashMap(); + return new OrderedProperties(properties, suppressDate); + } + + } + + /** + * Custom {@link Properties} that delegates reading, writing, and enumerating + * properties to the backing {@link OrderedProperties} instance's properties. + */ + @SuppressWarnings("serial") + private static final class CustomProperties extends Properties { + + private final Map targetProperties; + + private CustomProperties(Map targetProperties) { + this.targetProperties = targetProperties; + } + + @Override + public Object get(Object key) { + return targetProperties.get(key); + } + + @Override + public Object put(Object key, Object value) { + return targetProperties.put((String) key, (String) value); + } + + @Override + public String getProperty(String key) { + return targetProperties.get(key); + } + + @Override + public Enumeration keys() { + return new Vector(targetProperties.keySet()).elements(); + } + + @Override + public Set keySet() { + return new LinkedHashSet(targetProperties.keySet()); + } + + @Override + public void store(Writer writer, String comments) throws IOException { + store1((writer instanceof BufferedWriter) ? (BufferedWriter) writer : new BufferedWriter(writer), comments, + false); + } + + @Override + public void store(OutputStream out, String comments) throws IOException { + store1(new BufferedWriter(new OutputStreamWriter(out, "8859_1")), comments, true); + } + + private void store1(BufferedWriter bw, String comments, boolean escUnicode) throws IOException { + + synchronized (this) { + for (Enumeration e = keys(); e.hasMoreElements();) { + String key = (String) e.nextElement(); + String val = (String) get(key); + key = saveConvert(key, true, escUnicode); + /* + * No need to escape embedded and trailing spaces for value, hence pass false to + * flag. + */ + val = saveConvert(val, false, escUnicode); + bw.write(key + "=" + val); + bw.newLine(); + } + } + bw.flush(); + } + + /* + * Converts unicodes to encoded \uxxxx and escapes special characters with a + * preceding slash + */ + private String saveConvert(String theString, boolean escapeSpace, boolean escapeUnicode) { + int len = theString.length(); + int bufLen = len * 2; + if (bufLen < 0) { + bufLen = Integer.MAX_VALUE; + } + StringBuilder outBuffer = new StringBuilder(bufLen); + + for (int x = 0; x < len; x++) { + char aChar = theString.charAt(x); + // Handle common case first, selecting largest block that + // avoids the specials below + if ((aChar > 61) && (aChar < 127)) { + if (aChar == '\\') { + outBuffer.append('\\'); + outBuffer.append('\\'); + continue; + } + outBuffer.append(aChar); + continue; + } + switch (aChar) { + case ' ': + if (x == 0 || escapeSpace) + outBuffer.append('\\'); + outBuffer.append(' '); + break; + case '\t': + outBuffer.append('\\'); + outBuffer.append('t'); + break; + case '\n': + outBuffer.append('\\'); + outBuffer.append('n'); + break; + case '\r': + outBuffer.append('\\'); + outBuffer.append('r'); + break; + case '\f': + outBuffer.append('\\'); + outBuffer.append('f'); + break; + case '=': // Fall through + case ':': // Fall through + case '#': // Fall through +// case '!': + outBuffer.append('\\'); + outBuffer.append(aChar); + break; + default: + if (((aChar < 0x0020) || (aChar > 0x007e)) && escapeUnicode) { + outBuffer.append('\\'); + outBuffer.append('u'); + outBuffer.append(toHex((aChar >> 12) & 0xF)); + outBuffer.append(toHex((aChar >> 8) & 0xF)); + outBuffer.append(toHex((aChar >> 4) & 0xF)); + outBuffer.append(toHex(aChar & 0xF)); + } else { + outBuffer.append(aChar); + } + } + } + return outBuffer.toString(); + } + + /** + * Convert a nibble to a hex character + * + * @param nibble the nibble to convert. + */ + private static char toHex(int nibble) { + return hexDigit[(nibble & 0xF)]; + } + + private static final char[] hexDigit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', + 'E', 'F' }; + + } + + /** + * Custom {@link BufferedWriter} for storing properties that will write all + * leading lines of comments except the last comment line. Using the JDK + * Properties class to store properties, the last comment line always contains + * the current date which is what we want to filter out. + */ + private static final class DateSuppressingPropertiesBufferedWriter extends BufferedWriter { + + private final String LINE_SEPARATOR = System.getProperty("line.separator"); + + private StringBuilder currentComment; + private String previousComment; + + private DateSuppressingPropertiesBufferedWriter(Writer out) { + super(out); + } + + @Override + public void write(String string) throws IOException { + if (currentComment != null) { + currentComment.append(string); + if (string.endsWith(LINE_SEPARATOR)) { + if (previousComment != null) { + super.write(previousComment); + } + + previousComment = currentComment.toString(); + currentComment = null; + } + } else if (string.startsWith("#")) { + currentComment = new StringBuilder(string); + } else { + super.write(string); + } + } + + } + +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/RunProccess.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/RunProccess.java new file mode 100644 index 000000000..20efebbba --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/RunProccess.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.common; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Run Java Process in a new VM + * + * @author rgarcia + */ +public class RunProccess { + private static final String ANT_MAIN_CLASS = "org.apache.tools.ant.launch.Launcher"; + + private static String getClasspath(List classpathEntries) { + StringBuilder builder = new StringBuilder(); + int count = 0; + final int totalSize = classpathEntries.size(); + for (String classpathEntry : classpathEntries) { + builder.append(classpathEntry); + count++; + if (count < totalSize) { + builder.append(System.getProperty("path.separator")); + } + } + return builder.toString(); + } + + public static boolean runBladeEngine(File prjFolder, String chapter, String scene, boolean fullscreen) + throws IOException { + List args = new ArrayList<>(); + args.add(":desktop:run"); + String appArgs = "-PappArgs=['-d'"; + + if (!fullscreen) + appArgs += ",'-w'"; + + if (chapter != null) { + appArgs += ",'-chapter','" + chapter + "'"; + } + + if (scene != null) { + appArgs += ",'-t','" + scene + "'"; + } + + appArgs += "]"; + args.add(appArgs); + + return runGradle(prjFolder, args); + } + + public static boolean runBladeEngineInternal(File prjFolder, String chapter, String scene) throws IOException { + List args = new ArrayList<>(); + args.add("-w"); + args.add("-adv-dir"); + args.add(prjFolder.getAbsolutePath()); + + if (scene != null) { + args.add("-t"); + args.add(scene); + } + + if (chapter != null) { + args.add("-chapter"); + args.add(chapter); + } + + List cp = new ArrayList<>(); + cp.add(System.getProperty("java.class.path")); + + runJavaProccess("com.bladecoder.engineeditor.utils.DesktopLauncher", cp, args); + + return true; + } + + public static Process runJavaProccess(String mainClass, List classpathEntries, List args) + throws IOException { + String javaRT = System.getProperty("java.home") + "/bin/java"; + String workingDirectory = "."; + + List argumentsList = new ArrayList<>(); + argumentsList.add(javaRT); + + if (classpathEntries != null && classpathEntries.size() > 0) { + argumentsList.add("-classpath"); + argumentsList.add(getClasspath(classpathEntries)); + } + + argumentsList.add(mainClass); + + if (args != null) + argumentsList.addAll(args); + + ProcessBuilder processBuilder = new ProcessBuilder(argumentsList.toArray(new String[argumentsList.size()])); + // processBuilder.redirectErrorStream(true); + processBuilder.directory(new File(workingDirectory)); + processBuilder.inheritIO(); + + return processBuilder.start(); + } + + public static Process runJavaHomeBin(String bin, List args) throws IOException { + String cmd = System.getProperty("java.home") + "/bin/" + bin; + String workingDirectory = "."; + + List argumentsList = new ArrayList<>(); + argumentsList.add(cmd); + + if (args != null) + argumentsList.addAll(args); + + ProcessBuilder processBuilder = new ProcessBuilder(argumentsList.toArray(new String[argumentsList.size()])); + // processBuilder.redirectErrorStream(true); + processBuilder.directory(new File(workingDirectory)); + processBuilder.inheritIO(); + + return processBuilder.start(); + } + + public static boolean runGradle(File workingDir, List parameters) { + String exec = workingDir.getAbsolutePath() + "/" + + (System.getProperty("os.name").contains("Windows") ? "gradlew.bat" : "gradlew"); + + List argumentsList = new ArrayList<>(); + argumentsList.add(exec); + argumentsList.addAll(parameters); + + EditorLogger.msgThreaded("Executing 'gradlew " + parameters + "'"); + + try { + final ProcessBuilder pb = new ProcessBuilder(argumentsList).directory(workingDir).redirectErrorStream(true); + + // TODO: READ OUTPUT FROM pb AND print in output stream + // if (System.console() != null) + // pb.inheritIO(); + + final Process process = pb.start(); + + BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line; + while ((line = in.readLine()) != null) { + EditorLogger.msgThreaded(line); + } + + process.waitFor(); + return process.exitValue() == 0; + } catch (Exception e) { + EditorLogger.msgThreaded("ERROR: " + e.getMessage()); + return false; + } + } + + public static boolean runInklecate(File workingDir, List parameters) { + String exec = workingDir.getAbsolutePath() + "/" + "inklecate.exe"; + + if (!new File(exec).exists()) { + exec = workingDir.getAbsolutePath() + "/" + "inklecate"; + } + + if (!new File(exec).exists()) { + EditorLogger.msgThreaded("ERROR: Could not find inklecate.exe or inklecate in " + workingDir.getAbsolutePath()); + return false; + } + + List argumentsList = new ArrayList<>(); + argumentsList.add(exec); + argumentsList.addAll(parameters); + + EditorLogger.msgThreaded("Executing 'inklecate " + parameters + "'"); + + try { + final ProcessBuilder pb = new ProcessBuilder(argumentsList).directory(workingDir).redirectErrorStream(true); + + // TODO: READ OUTPUT FROM pb AND print in output stream + // if (System.console() != null) + // pb.inheritIO(); + + final Process process = pb.start(); + + BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line; + while ((line = in.readLine()) != null) { + EditorLogger.msgThreaded(line); + } + + process.waitFor(); + return process.exitValue() == 0; + } catch (Exception e) { + EditorLogger.msgThreaded("ERROR: " + e.getMessage()); + return false; + } + } + + public static boolean runGradle(File workingDir, String parameters) { + + String[] split = parameters.split(" "); + + return runGradle(workingDir, Arrays.asList(split)); + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/TemplateUtils.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/TemplateUtils.java similarity index 98% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/TemplateUtils.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/common/TemplateUtils.java index 1e839ebd2..edbc838aa 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/utils/TemplateUtils.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/TemplateUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ -package com.bladecoder.engineeditor.utils; +package com.bladecoder.engineeditor.common; import java.io.BufferedReader; import java.io.File; diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/Versions.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/Versions.java new file mode 100644 index 000000000..44b9abb28 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/Versions.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.common; + +import java.io.InputStream; +import java.util.Properties; + +public class Versions { + private static final String VERSION_PROP = "version"; + private static final String LIBGDX_VERSION_PROP = "libgdxVersion"; + private static final String ROBOVM_VERSION_PROP = "roboVMVersion"; + private static final String ANDROID_API_LEVEL_PROP = "androidAPILevel"; + private static final String ANDROID_GRADLE_VERSION_PROP = "androidGradlePluginVersion"; + private static final String BLADE_INK_VERSION_PROP = "bladeInkVersion"; + + public static final String PROPERTIES_FILENAME = "/versions.properties"; + + private static Properties config = null; + + private static String getProperty(String key, String defaultValue) { + if (config == null) { + config = new Properties(); + + try { + InputStream is = Versions.class.getResourceAsStream(PROPERTIES_FILENAME); + config.load(is); + } catch (Exception e) { + EditorLogger.error("ERROR LOADING VERSION FILE: " + e.getMessage()); + } + } + + return config.getProperty(key, defaultValue); + } + + public static String getVersion() { + return getProperty(VERSION_PROP, null); + } + + public static String getLibgdxVersion() { + return getProperty(LIBGDX_VERSION_PROP, null); + } + + public static String getRoboVMVersion() { + return getProperty(ROBOVM_VERSION_PROP, null); + } + + public static String getAndroidAPILevel() { + return getProperty(ANDROID_API_LEVEL_PROP, null); + } + + public static void setAndroidAPILevel(String v) { + config.setProperty(ANDROID_API_LEVEL_PROP, v); + } + + public static String getAndroidGradlePluginVersion() { + return getProperty(ANDROID_GRADLE_VERSION_PROP, null); + } + + public static String getBladeInkVersion() { + return getProperty(BLADE_INK_VERSION_PROP, null); + } + +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ZipUtils.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ZipUtils.java new file mode 100644 index 000000000..b3100c9ca --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/common/ZipUtils.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.common; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.zip.Deflater; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; + +public class ZipUtils { + // 4MB buffer + private static final byte[] BUFFER = new byte[4096 * 1024]; + + // copy input to output stream + private static void copy(InputStream input, OutputStream output) throws IOException { + int bytesRead; + while ((bytesRead = input.read(BUFFER)) != -1) { + output.write(BUFFER, 0, bytesRead); + } + } + + public static void mergeZIPs(String f[], String dest) throws Exception { + // Needed to avoid appending repeated entries. + HashMap destEntries = new HashMap(); + + // read the org zips + ZipFile fZip[] = new ZipFile[f.length]; + + for (int i = 0; i < fZip.length; i++) + fZip[i] = new ZipFile(f[i]); + + // write the dest zip + ZipOutputStream destZip = new ZipOutputStream(new FileOutputStream(dest)); + + // copy contents from f zip to the dest zip + + for (ZipFile z : fZip) { + Enumeration entries = z.entries(); + while (entries.hasMoreElements()) { + ZipEntry e = entries.nextElement(); + + String name = e.getName(); + if (destEntries.get(name) == null) { + destEntries.put(name, name); + EditorLogger.debug("copy: " + e.getName()); + destZip.putNextEntry(e); + EditorLogger.debug("putnextEntry done"); + if (!e.isDirectory()) { + copy(z.getInputStream(e), destZip); + } + destZip.closeEntry(); + } + } + } + + EditorLogger.debug("appending done "); + + // close + for (ZipFile z : fZip) { + z.close(); + } + + destZip.close(); + } + + public static void packZip(List sources, File output) throws IOException { + EditorLogger.debug("Packaging to " + output.getName()); + ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(output)); + zipOut.setLevel(Deflater.DEFAULT_COMPRESSION); + + for (File source : sources) { + if (source.isDirectory()) { + zipDir(zipOut, "", source); + } else { + zipFile(zipOut, "", source); + } + } + zipOut.flush(); + zipOut.close(); + EditorLogger.debug("Done"); + } + + private static String buildPath(String path, String file) { + if (path == null || path.isEmpty()) { + return file; + } else { + return path + "/" + file; + } + } + + private static void zipDir(ZipOutputStream zos, String path, File dir) throws IOException { + if (!dir.canRead()) { + EditorLogger.error("Cannot read " + dir.getCanonicalPath() + + " (maybe because of permissions)"); + return; + } + + File[] files = dir.listFiles(); + path = buildPath(path, dir.getName()); + EditorLogger.debug("Adding Directory " + path); + + for (File source : files) { + if (source.isDirectory()) { + zipDir(zos, path, source); + } else { + zipFile(zos, path, source); + } + } + + EditorLogger.debug("Leaving Directory " + path); + } + + private static void zipFile(ZipOutputStream zos, String path, File file) throws IOException { + if (!file.canRead()) { + EditorLogger.error("Cannot read " + file.getCanonicalPath() + + " (maybe because of permissions)"); + return; + } + + EditorLogger.debug("Compressing " + file.getName()); + zos.putNextEntry(new ZipEntry(buildPath(path, file.getName()))); + + FileInputStream fis = new FileInputStream(file); + + byte[] buffer = new byte[4092]; + int byteCount = 0; + while ((byteCount = fis.read(buffer)) != -1) { + zos.write(buffer, 0, byteCount); + } + + fis.close(); + zos.closeEntry(); + } + + public static void unzip(File zipFile, Path targetDir) throws IOException { + InputStream is = Files.newInputStream(zipFile.toPath()); + + targetDir = targetDir.toAbsolutePath(); + + try (ZipInputStream zipIn = new ZipInputStream(is)) { + for (ZipEntry ze; (ze = zipIn.getNextEntry()) != null; ) { + Path resolvedPath = targetDir.resolve(ze.getName()).normalize(); + if (!resolvedPath.startsWith(targetDir)) { + // see: https://snyk.io/research/zip-slip-vulnerability + throw new RuntimeException("Entry with an illegal path: " + + ze.getName()); + } + if (ze.isDirectory()) { + Files.createDirectories(resolvedPath); + } else { + Files.createDirectories(resolvedPath.getParent()); + Files.copy(zipIn, resolvedPath); + } + } + } + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/model/Chapter.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/model/Chapter.java new file mode 100644 index 000000000..994a898f9 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/model/Chapter.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.model; + +import com.bladecoder.engine.assets.EngineAssetManager; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.ElementUtils; +import org.apache.commons.io.FileUtils; +import org.xml.sax.SAXException; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.net.URL; + +public class Chapter { + private String modelPath; + private String id; + + public Chapter(String modelPath) { + this.modelPath = modelPath; + + if (!modelPath.endsWith("/")) + this.modelPath = modelPath + "/"; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public String toString() { + return getId(); + } + + public void load(String id) throws IOException { + setId(id); + Ctx.project.getWorld().getSerializer().loadChapter(id, null, false); + } + + public void save() throws IOException { + Ctx.project.getWorld().getSerializer().saveModel(id); + } + + public String[] getChapters() { + + String[] chapters = new File(modelPath).list(new FilenameFilter() { + @Override + public boolean accept(File arg0, String arg1) { + if (!arg1.endsWith(EngineAssetManager.CHAPTER_EXT) && !arg1.endsWith(".chapter")) + return false; + + return true; + } + }); + + for (int i = 0; i < chapters.length; i++) { + if (chapters[i].endsWith(EngineAssetManager.CHAPTER_EXT)) + chapters[i] = chapters[i].substring(0, chapters[i].lastIndexOf(EngineAssetManager.CHAPTER_EXT)); + else + chapters[i] = chapters[i].substring(0, chapters[i].lastIndexOf(".chapter")); + } + + return chapters; + } + + public String getInitChapter() { + String init = Ctx.project.getWorld().getInitChapter(); + + if (init == null || init.isEmpty()) { + init = getChapters()[0]; + + Ctx.project.getWorld().setInitChapter(init); + } + + return init; + } + + public String createChapter(String id) throws TransformerException, ParserConfigurationException, IOException { + String checkedId = ElementUtils.getCheckedId(id, getChapters()); + + URL inputUrl = getClass().getResource("/projectTmpl/assets/model/00.chapter.json"); + File dest = new File(modelPath + checkedId + EngineAssetManager.CHAPTER_EXT); + FileUtils.copyURLToFile(inputUrl, dest); + + return checkedId; + } + + public void renameChapter(String oldId, String newId) + throws TransformerException, ParserConfigurationException, SAXException, IOException { + File f = new File(modelPath + id + EngineAssetManager.CHAPTER_EXT); + f.renameTo(new File(modelPath + newId + EngineAssetManager.CHAPTER_EXT)); + + String i18nFilename = modelPath + id + ".properties"; + f = new File(i18nFilename); + f.renameTo(new File(modelPath + newId + ".properties")); + } + + public void deleteChapter(String id) + throws TransformerException, ParserConfigurationException, SAXException, IOException { + File f = new File(modelPath + id + EngineAssetManager.CHAPTER_EXT); + f.delete(); + + String i18nFilename = modelPath + id + ".properties"; + f = new File(i18nFilename); + f.delete(); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/model/I18NHandler.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/model/I18NHandler.java new file mode 100644 index 000000000..0313bd8e6 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/model/I18NHandler.java @@ -0,0 +1,539 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.model; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +import com.bladecoder.engine.actions.Action; +import com.bladecoder.engine.actions.DisableActionAction; +import com.bladecoder.engine.assets.EngineAssetManager; +import com.bladecoder.engine.i18n.I18N; +import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.CharacterActor; +import com.bladecoder.engine.model.Dialog; +import com.bladecoder.engine.model.DialogOption; +import com.bladecoder.engine.model.InteractiveActor; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.SpriteActor; +import com.bladecoder.engine.model.TextRenderer; +import com.bladecoder.engine.model.Verb; +import com.bladecoder.engine.util.ActionUtils; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.OrderedProperties; +import com.bladecoder.engineeditor.common.OrderedProperties.OrderedPropertiesBuilder; + +public class I18NHandler { + public static final String WORLD_VERBS_PREFIX = "default"; + + private String modelPath; + private String worldFilename; + private String chapterFilename; + + private OrderedProperties i18nWorld; + private OrderedProperties i18nChapter; + + public I18NHandler(String modelPath) { + this.worldFilename = EngineAssetManager.WORLD_FILENAME; + this.modelPath = modelPath; + + if (!modelPath.endsWith("/")) + this.modelPath = modelPath + "/"; + + i18nWorld = loadI18N(worldFilename); + } + + private String getI18NFilename(String modelFilename) { + return modelPath + modelFilename + ".properties"; + } + + public void load(String chapterId) { + this.chapterFilename = chapterId; + i18nChapter = loadI18N(chapterFilename); + } + + private OrderedProperties loadI18N(String modelFilename) { + String i18nFilename = getI18NFilename(modelFilename); + + // To save in alphabetical order we use the OrderedProperties + OrderedProperties i18n = new OrderedPropertiesBuilder().withSuppressDateInComment(true).withOrdering().build(); + + try { + i18n.load(new InputStreamReader(new FileInputStream(i18nFilename), I18N.ENCODING)); + } catch (IOException e) { + EditorLogger.error("ERROR LOADING BUNDLE: " + i18nFilename); + } + + return i18n; + } + + public String getWorldTranslation(String key) { + if (key == null || key.isEmpty() || key.charAt(0) != I18N.PREFIX || i18nWorld == null) + return key; + + return i18nWorld.getProperty(key.substring(1), key); + } + + /** + * Returns the translation from chapter property + * + * @param key + * @return + */ + public String getTranslation(String key) { + if (key == null || key.isEmpty() || key.charAt(0) != I18N.PREFIX || i18nChapter == null) + return key; + + return i18nChapter.getProperty(key.substring(1), key); + } + + public void setTranslation(String key, String value) { + if (key.charAt(0) != I18N.PREFIX) { + if (value == null || value.equals("")) + i18nChapter.removeProperty(key); + else + i18nChapter.setProperty(key, value); + } else { + if (value == null || value.equals("")) + i18nChapter.removeProperty(key.substring(1)); + else + i18nChapter.setProperty(key.substring(1), value); + } + } + + public void setWorldTranslation(String key, String value) { + if (key.charAt(0) != I18N.PREFIX) { + if (value == null || value.equals("")) + i18nWorld.removeProperty(key); + else + i18nWorld.setProperty(key, value); + } else { + if (value == null || value.equals("")) + i18nWorld.removeProperty(key.substring(1)); + else + i18nWorld.setProperty(key.substring(1), value); + } + } + + private void save(String filename, OrderedProperties p) { + String i18nFilename = getI18NFilename(filename); + + deleteUnusedKeys(); + + try { + FileOutputStream os = new FileOutputStream(i18nFilename); + Writer out = new OutputStreamWriter(os, I18N.ENCODING); + p.store(out, filename); + } catch (IOException e) { + EditorLogger.error("ERROR WRITING BUNDLE: " + i18nFilename); + } + } + + public void save() throws FileNotFoundException { + save(worldFilename, i18nWorld); + save(chapterFilename, i18nChapter); + } + + public void putTranslationsInElement(Scene scn) { + + HashMap verbs = scn.getVerbManager().getVerbs(); + + for (Verb v : verbs.values()) + putTranslationsInElement(v, false); + + for (BaseActor a : scn.getActors().values()) { + putTranslationsInElement(a); + } + } + + public void putTranslationsInElement(BaseActor a) { + if (a instanceof InteractiveActor) { + InteractiveActor ia = (InteractiveActor) a; + + // 1. DESC attribute + ia.setDesc(getTranslation(ia.getDesc())); + + // 2. ACTIONS + HashMap verbs = ia.getVerbManager().getVerbs(); + + for (Verb v : verbs.values()) + putTranslationsInElement(v, false); + + // 3. DIALOGS + if (a instanceof CharacterActor) { + HashMap dialogs = ((CharacterActor) a).getDialogs(); + + if (dialogs != null) { + for (Dialog d : dialogs.values()) + putTranslationsInElement(d); + } + } + + // 4. Text for TextRenderer + if (a instanceof SpriteActor && ((SpriteActor) a).getRenderer() instanceof TextRenderer) { + + TextRenderer r = (TextRenderer) ((SpriteActor) a).getRenderer(); + + r.setText(getTranslation(r.getText())); + } + } + } + + public void putTranslationsInElement(Verb v, boolean worldScope) { + ArrayList actions = v.getActions(); + + for (Action a : actions) { + putTranslationsInElement(a, worldScope); + } + } + + public void putTranslationsInElement(Action a, boolean worldScope) { + String[] names = ActionUtils.getFieldNames(a); + + for (String name : names) { + if (name.toLowerCase().endsWith("text")) { + + try { + String value = null; + + if (worldScope) + value = getWorldTranslation(ActionUtils.getStringValue(a, name)); + else + value = getTranslation(ActionUtils.getStringValue(a, name)); + + ActionUtils.setParam(a, name, value); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + EditorLogger.error(e.getMessage()); + } + } + } + } + + public void putTranslationsInElement(Dialog d) { + ArrayList options = d.getOptions(); + + for (DialogOption o : options) { + putTranslationsInElement(o); + } + } + + public void putTranslationsInElement(DialogOption o) { + o.setText(getTranslation(o.getText())); + o.setResponseText(getTranslation(o.getResponseText())); + } + + public void extractStrings(Scene scn) { + HashMap verbs = scn.getVerbManager().getVerbs(); + + for (Verb v : verbs.values()) + extractStrings(scn.getId(), null, v); + + for (BaseActor a : scn.getActors().values()) { + extractStrings(scn.getId(), a); + } + } + + public void extractStrings(String sceneid, BaseActor a) { + if (a instanceof InteractiveActor) { + InteractiveActor ia = (InteractiveActor) a; + + // 1. DESC attribute + if (ia.getDesc() != null && !ia.getDesc().isEmpty() && ia.getDesc().charAt(0) != I18N.PREFIX) { + String key = genKey(sceneid, a.getId(), "desc"); + String value = ia.getDesc(); + ia.setDesc(key); + setTranslation(key, value); + } + + // 2. ACTIONS + HashMap verbs = ia.getVerbManager().getVerbs(); + + for (Verb v : verbs.values()) + extractStrings(sceneid, a.getId(), v); + + // 3. DIALOGS + if (a instanceof CharacterActor) { + HashMap dialogs = ((CharacterActor) a).getDialogs(); + + if (dialogs != null) + for (Dialog d : dialogs.values()) + extractStrings(sceneid, a.getId(), d); + } + + // 4. Text for TextRenderer + if (a instanceof SpriteActor && ((SpriteActor) a).getRenderer() instanceof TextRenderer) { + + TextRenderer r = (TextRenderer) ((SpriteActor) a).getRenderer(); + + String v = r.getText(); + + if (v != null && !v.isEmpty() && v.charAt(0) != I18N.PREFIX) { + String key = genKey(sceneid, a.getId(), "text"); + r.setText(key, r.getText()); + setTranslation(key, v); + } + } + } + } + + public void extractStrings(String sceneid, String actorid, Verb v) { + ArrayList actions = v.getActions(); + + for (int i = 0; i < actions.size(); i++) { + Action a = actions.get(i); + + extractStrings(sceneid, actorid, v.getHashKey(), i, a); + } + } + + public void extractStrings(String sceneid, String actorid, Dialog d) { + ArrayList options = d.getOptions(); + + for (int i = 0; i < options.size(); i++) { + DialogOption o = options.get(i); + + extractStrings(sceneid, actorid, d.getId(), i, o); + } + } + + public void extractStrings(String sceneid, String actorid, String dialogid, int pos, DialogOption o) { + if (o.getText() != null && !o.getText().isEmpty() && o.getText().charAt(0) != I18N.PREFIX) { + String key = genKey(sceneid, actorid, dialogid, pos, "text"); + String value = o.getText(); + o.setText(key); + setTranslation(key, value); + } + + if (o.getResponseText() != null && !o.getResponseText().isEmpty() + && o.getResponseText().charAt(0) != I18N.PREFIX) { + String key = genKey(sceneid, actorid, dialogid, pos, "responseText"); + String value = o.getResponseText(); + o.setResponseText(key); + setTranslation(key, value); + } + } + + public void extractStrings(String sceneid, String actorid, String parent, int pos, Action a) { + String[] names = ActionUtils.getFieldNames(a); + + for (String name : names) { + if (name.toLowerCase().endsWith("text")) { + + try { + String value = ActionUtils.getStringValue(a, name); + + if (value != null && !value.isEmpty() && value.charAt(0) != I18N.PREFIX) { + String key = genKey(sceneid, actorid, parent, pos, name); + ActionUtils.setParam(a, name, key); + + if (sceneid == null) + setWorldTranslation(key, value); + else + setTranslation(key, value); + } + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + EditorLogger.error(e.getMessage()); + } + } + } + } + + public String genKey(String sceneid, String actorid, String property) { + String key = I18N.PREFIX + sceneid + "." + actorid + "." + property; + + return getNotDuplicateKey(key); + } + + public String genKey(String sceneid, String actorid, String parent, int pos, String property) { + String key = I18N.PREFIX + (sceneid == null ? WORLD_VERBS_PREFIX : sceneid) + + (actorid == null ? "" : "." + actorid) + "." + parent + "." + pos + "." + property; + + if (sceneid == null) + return getNotDuplicateKeyWorld(key); + + return getNotDuplicateKey(key); + } + + public String getNotDuplicateKey(String key) { + // first delete all numbers at the end to avoid always growing keys + String key2 = key.replaceAll("\\d*$", ""); + + if (key2.isEmpty()) + key2 = key; + + int i = 0; + + while (i18nChapter.containsProperty(key2.charAt(0) == I18N.PREFIX ? key2.substring(1) : key2)) { + i++; + key2 = key + i; + } + + return key2; + } + + public String getNotDuplicateKeyWorld(String key) { + // first delete all numbers at the end to avoid always growing keys + String key2 = key.replaceAll("\\d*$", ""); + + if (key2.isEmpty()) + key2 = key; + + int i = 0; + + while (i18nWorld.containsProperty(key2.charAt(0) == I18N.PREFIX ? key2.substring(1) : key2)) { + i++; + key2 = key + i; + } + + return key2; + } + + public void cleanI18N() { + Map scenes = Ctx.project.getWorld().getScenes(); + for (Scene scn : scenes.values()) { + Ctx.project.getI18N().putTranslationsInElement(scn); + } + + // i18nChapter = new + // OrderedPropertiesBuilder().withSuppressDateInComment(true).withOrdering().build(); + deleteUnusedKeys(); + + for (Scene scn : scenes.values()) { + Ctx.project.getI18N().extractStrings(scn); + } + + Ctx.project.setModified(); + } + + private void deleteUnusedKeys() { + ArrayList usedKeys = new ArrayList<>(); + + // SCENES + for (Scene s : Ctx.project.getWorld().getScenes().values()) + getUsedKeys(s, usedKeys); + + Enumeration keys = i18nChapter.propertyNames(); + + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + + // Doesn't remove ui and ink keys + if (!usedKeys.contains(key) && !key.startsWith("ui.") && !key.startsWith("ink.")) { + EditorLogger.debug("Removing translation key: " + key); + i18nChapter.removeProperty(key); + } + } + + usedKeys.clear(); + // WORLD VERBS + for (Verb v : Ctx.project.getWorld().getVerbManager().getVerbs().values()) + getUsedKeys(v, usedKeys); + + keys = i18nWorld.propertyNames(); + + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + + // Doesn't remove ui keys + if (!usedKeys.contains(key) && !key.startsWith("ui.")) { + EditorLogger.debug("Removing translation key: " + key); + i18nWorld.removeProperty(key); + } + } + + } + + private void getUsedKeys(Scene s, ArrayList usedKeys) { + for (Verb v : s.getVerbManager().getVerbs().values()) + getUsedKeys(v, usedKeys); + + for (BaseActor a : s.getActors().values()) { + if (a instanceof InteractiveActor) { + InteractiveActor ia = (InteractiveActor) a; + + if (ia.getDesc() != null && !ia.getDesc().isEmpty() && ia.getDesc().charAt(0) == I18N.PREFIX) + usedKeys.add(ia.getDesc().substring(1)); + + for (Verb v : ia.getVerbManager().getVerbs().values()) + getUsedKeys(v, usedKeys); + + if (a instanceof CharacterActor) { + CharacterActor ca = (CharacterActor) a; + + if (ca.getDialogs() != null) { + for (Dialog d : ca.getDialogs().values()) { + for (DialogOption o : d.getOptions()) { + if (o.getText() != null && !o.getText().isEmpty() + && o.getText().charAt(0) == I18N.PREFIX) + usedKeys.add(o.getText().substring(1)); + + if (o.getResponseText() != null && !o.getResponseText().isEmpty() + && o.getResponseText().charAt(0) == I18N.PREFIX) + usedKeys.add(o.getResponseText().substring(1)); + } + } + } + } + + if (a instanceof SpriteActor && ((SpriteActor) a).getRenderer() instanceof TextRenderer) { + + TextRenderer r = (TextRenderer) ((SpriteActor) a).getRenderer(); + + String k = r.getText(); + + if (k != null && !k.isEmpty() && k.charAt(0) == I18N.PREFIX) + usedKeys.add(k.substring(1)); + } + } + } + } + + private void getUsedKeys(Verb v, ArrayList usedKeys) { + for (Action a : v.getActions()) { + + if (a instanceof DisableActionAction) + a = ((DisableActionAction) a).getAction(); + + String[] fieldNames = ActionUtils.getFieldNames(a); + + for (String name : fieldNames) { + if (name.toLowerCase().endsWith("text")) { + String value = null; + + try { + value = ActionUtils.getStringValue(a, name); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + EditorLogger.error(e.getMessage()); + } + + if (value != null && !value.isEmpty() && value.charAt(0) == I18N.PREFIX) { + usedKeys.add(value.substring(1)); + } + } + } + } + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/model/Project.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/model/Project.java new file mode 100644 index 000000000..62fa778e1 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/model/Project.java @@ -0,0 +1,567 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.model; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Graphics; +import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.utils.SerializationException; +import com.bladecoder.engine.actions.ActionFactory; +import com.bladecoder.engine.assets.EngineAssetManager; +import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.World; +import com.bladecoder.engine.util.Config; +import com.bladecoder.engine.util.EngineLogger; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.FolderClassLoader; +import com.bladecoder.engineeditor.common.OrderedProperties; +import com.bladecoder.engineeditor.common.OrderedProperties.OrderedPropertiesBuilder; +import com.bladecoder.engineeditor.common.RunProccess; +import com.bladecoder.engineeditor.common.Versions; +import com.bladecoder.engineeditor.setup.BladeEngineSetup; +import com.bladecoder.engineeditor.undo.UndoStack; + +import java.beans.PropertyChangeEvent; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; + +public class Project extends PropertyChange { + public static final String NOTIFY_SCENE_SELECTED = "SCENE_SELECTED"; + public static final String NOTIFY_ACTOR_SELECTED = "ACTOR_SELECTED"; + public static final String NOTIFY_ANIM_SELECTED = "ANIM_SELECTED"; + public static final String NOTIFY_PROJECT_LOADED = "PROJECT_LOADED"; + public static final String NOTIFY_PROJECT_SAVED = "PROJECT_SAVED"; + public static final String NOTIFY_CHAPTER_LOADED = "CHAPTER_LOADED"; + + public static final String NOTIFY_ELEMENT_DELETED = "ELEMENT_DELETED"; + public static final String NOTIFY_ELEMENT_CREATED = "ELEMENT_CREATED"; + public static final String NOTIFY_MODEL_MODIFIED = "MODEL_MODIFIED"; + public static final String POSITION_PROPERTY = "pos"; + public static final String WIDTH_PROPERTY = "width"; + public static final String HEIGHT_PROPERTY = "height"; + public static final String CHAPTER_PROPERTY = "chapter"; + + public static final String SPINE_RENDERER_STRING = "spine"; + public static final String ATLAS_RENDERER_STRING = "atlas"; + public static final String IMAGE_RENDERER_STRING = "image"; + public static final String PARTICLE_RENDERER_STRING = "particle"; + public static final String TEXT_RENDERER_STRING = "text"; + + public static final String ASSETS_PATH = "/assets"; + public static final String MODEL_PATH = "/model"; + public static final String ATLASES_PATH = "/atlases"; + public static final String FONTS_PATH = "/fonts"; + public static final String MUSIC_PATH = "/music"; + public static final String SOUND_PATH = "/sounds"; + public static final String IMAGE_PATH = "/images"; + public static final String SPINE_PATH = "/spine"; + public static final String PARTICLE_PATH = "/particles"; + public static final String VOICE_PATH = "/voices"; + public static final String UI_PATH = "/ui"; + public static final String FONT_PATH = UI_PATH + "/fonts"; + + private static final String CONFIG_DIR = System.getProperty("user.home") + "/.AdventureEditor"; + private static final String CONFIG_FILENAME = "config.properties"; + + public static final String LAST_PROJECT_PROP = "last_project"; + + private final Properties editorConfig = new Properties(); + + private File projectFile; + + private final UndoStack undoStack = new UndoStack(); + private OrderedProperties projectConfig; + + private I18NHandler i18n; + private Chapter chapter; + private Scene selectedScene; + private BaseActor selectedActor; + private String selectedFA; + private boolean modified = false; + private final World world = new World(); + private final HashSet hiddenActors = new HashSet<>(); + + public Project() { + loadConfig(); + } + + public World getWorld() { + return world; + } + + public String getAssetPath(String base) { + return base + ASSETS_PATH; + } + + public String getAssetPath() { + return getAssetPath(getProjectPath()); + } + + public UndoStack getUndoStack() { + return undoStack; + } + + private void loadConfig() { + File dir = new File(CONFIG_DIR); + File f = new File(CONFIG_DIR + "/" + CONFIG_FILENAME); + + if (!dir.exists()) + dir.mkdirs(); + + try { + if (!f.exists()) { + f.createNewFile(); + } else { + editorConfig.load(new FileInputStream(f)); + } + } catch (IOException e) { + EditorLogger.error(e.getMessage()); + } + } + + public void saveConfig() { + File f = new File(CONFIG_DIR + "/" + CONFIG_FILENAME); + + try { + editorConfig.store(new FileOutputStream(f), null); + } catch (IOException e) { + EditorLogger.error(e.getMessage()); + } + } + + public Properties getEditorConfig() { + return editorConfig; + } + + public OrderedProperties getProjectConfig() { + return projectConfig; + } + + public I18NHandler getI18N() { + return i18n; + } + + public String translate(String key) { + return i18n.getTranslation(key); + } + + public void setModified(Object source, String property, Object oldValue, Object newValue) { + modified = true; + PropertyChangeEvent evt = new PropertyChangeEvent(source, property, oldValue, newValue); + firePropertyChange(evt); + } + + public void notifyPropertyChange(String property) { + firePropertyChange(property); + } + + public void setSelectedScene(Scene scn) { + selectedScene = scn; + selectedActor = null; + selectedFA = null; + + if (scn != null) + getEditorConfig().setProperty("project.selectedScene", scn.getId()); + + firePropertyChange(NOTIFY_SCENE_SELECTED, null, selectedScene); + } + + public void setSelectedActor(BaseActor a) { + BaseActor old = null; + + old = selectedActor; + + selectedActor = a; + selectedFA = null; + + firePropertyChange(NOTIFY_ACTOR_SELECTED, old, selectedActor); + } + + public Chapter getChapter() { + return chapter; + } + + public Scene getSelectedScene() { + return selectedScene; + } + + public BaseActor getSelectedActor() { + return selectedActor; + } + + public String getSelectedFA() { + return selectedFA; + } + + public void setSelectedFA(String id) { + String old = selectedFA; + + selectedFA = id; + + firePropertyChange(NOTIFY_ANIM_SELECTED, old, selectedFA); + } + + public String getModelPath() { + return getAssetPath() + MODEL_PATH; + } + + public String getProjectPath() { + return projectFile.getAbsolutePath(); + } + + public File getProjectDir() { + return projectFile; + } + + public String getTitle() { + if (projectConfig == null) + return null; + + return projectConfig.getProperty(Config.TITLE_PROP, getProjectDir().getName()); + } + + public boolean isLoaded() { + return Ctx.project.getProjectDir() != null; + } + + public String getPackageTitle() { + return getTitle().replace(" ", "").replace("'", ""); + } + + public void createProject(String projectDir, String name, String pkg, String sdkLocation, boolean spinePlugin) + throws IOException { + closeProject(); + + createLibGdxProject(projectDir, name, pkg, "BladeEngine", sdkLocation, spinePlugin); + + projectFile = new File(projectDir + "/" + name); + + loadProject(projectFile); + } + + private void createLibGdxProject(String projectDir, String name, String pkg, String mainClass, String sdkLocation, + boolean spinePlugin) throws IOException { + String sdk = null; + + if (sdkLocation != null && !sdkLocation.isEmpty()) { + sdk = sdkLocation; + } else if (System.getenv("ANDROID_HOME") != null) { + sdk = System.getenv("ANDROID_HOME"); + } + + new BladeEngineSetup().build(projectDir + "/" + name, name, pkg, mainClass, sdk, spinePlugin); + } + + public void saveProject() throws IOException { + if (projectFile != null && chapter.getId() != null && modified) { + + EngineLogger.setDebug(); + + // 1.- SAVE world + world.saveWorldDesc( + new FileHandle(new File(getAssetPath() + MODEL_PATH + "/" + EngineAssetManager.WORLD_FILENAME))); + + // 2.- SAVE .chapter + chapter.save(); + + // 3.- SAVE BladeEngine.properties + List resolutions = getResolutions(); + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < resolutions.size(); i++) { + sb.append(resolutions.get(i)); + + if (i < resolutions.size() - 1) + sb.append(','); + } + + projectConfig.setProperty(Config.RESOLUTIONS, sb.toString()); + projectConfig.store(new FileOutputStream(getAssetPath() + "/" + Config.PROPERTIES_FILENAME), null); + + // 4.- SAVE I18N + i18n.save(); + + modified = false; + firePropertyChange(NOTIFY_PROJECT_SAVED); + } + } + + public void closeProject() { + setSelectedScene(null); + this.projectFile = null; + this.projectConfig = null; + firePropertyChange(NOTIFY_PROJECT_LOADED); + } + + public void loadProject(File projectToLoad) throws IOException { + + projectToLoad = checkProjectStructure(projectToLoad); + + if (projectToLoad != null) { + // dispose the current project + closeProject(); + + this.projectFile = projectToLoad; + + // Use FolderClassLoader for loading CUSTOM actions. + // TODO Add 'core/bin' and '/core/out' folders??? + FolderClassLoader folderClassLoader = null; + + if (new File(projectFile, "/assets").exists()) { + folderClassLoader = new FolderClassLoader( + projectFile.getAbsolutePath() + "/core/build/classes/java/main"); + } else { + folderClassLoader = new FolderClassLoader(projectFile.getAbsolutePath() + "/core/build/classes/main"); + } + + ActionFactory.setActionClassLoader(folderClassLoader); + EngineAssetManager.createEditInstance(getAssetPath()); + + try { + // Clear last project to avoid reloading if the project fails. + getEditorConfig().remove(LAST_PROJECT_PROP); + saveConfig(); + + world.loadWorldDesc(); + } catch (SerializationException ex) { + // check for not compiled custom actions + if (ex.getCause() != null && ex.getCause() instanceof ClassNotFoundException) { + EditorLogger.msg("Custom action class not found. Trying to compile..."); + if (RunProccess.runGradle(getProjectDir(), "desktop:compileJava")) { + folderClassLoader.reload(); + world.loadWorldDesc(); + } else { + this.projectFile = null; + throw new IOException("Failed to run Gradle."); + } + } else { + this.projectFile = null; + throw ex; + } + } + + chapter = new Chapter(getAssetPath() + Project.MODEL_PATH); + i18n = new I18NHandler(getAssetPath() + Project.MODEL_PATH); + + // No need to load the chapter. It's loaded by the chapter combo. + // loadChapter(world.getInitChapter()); + + projectConfig = new OrderedPropertiesBuilder().withSuppressDateInComment(true).withOrderingCaseSensitive() + .build(); + projectConfig.load(new FileInputStream(getAssetPath() + "/" + Config.PROPERTIES_FILENAME)); + modified = false; + + Lwjgl3Window window = ((Lwjgl3Graphics) Gdx.graphics).getWindow(); + window.setTitle("Adventure Editor v" + Versions.getVersion() + " - " + projectFile.getAbsolutePath()); + + firePropertyChange(NOTIFY_PROJECT_LOADED); + } else { + closeProject(); + throw new IOException("Project not found."); + } + } + + public boolean checkVersion(File projectPath) throws FileNotFoundException, IOException { + String editorVersion = getEditorBladeEngineVersion(); + String projectVersion = getProjectBladeEngineVersion(projectPath); + + if (editorVersion.equals(projectVersion) || editorVersion.indexOf('.') == -1) + return true; + + if (parseVersion(editorVersion) <= parseVersion(projectVersion)) + return true; + + return false; + } + + private int parseVersion(String v) { + int number = 1; // 1 -> release, 0 -> snapshot + + if (v.endsWith("-SNAPSHOT")) { + number = 0; + v = v.substring(0, v.length() - "-SNAPSHOT".length()); + } + + String[] split = v.split("\\."); + + try { + for (int i = 0; i < split.length; i++) { + number += Math.pow(10, (split.length - i) * 2) * Integer.parseInt(split[i]); + } + } catch (NumberFormatException e) { + } + + return number; + } + + public String getProjectBladeEngineVersion(File projectPath) throws FileNotFoundException, IOException { + OrderedProperties properties = getGradleProperties(projectPath); + + return properties.getProperty(Config.BLADE_ENGINE_VERSION_PROP, "default"); + } + + public String getEditorBladeEngineVersion() { + return Versions.getVersion(); + } + + public void updateEngineVersion(File projectPath) throws FileNotFoundException, IOException { + OrderedProperties prop = getGradleProperties(projectPath); + + prop.setProperty(Config.BLADE_ENGINE_VERSION_PROP, Versions.getVersion()); + prop.setProperty("gdxVersion", Versions.getLibgdxVersion()); + prop.setProperty("roboVMVersion", Versions.getRoboVMVersion()); + + prop.setProperty("androidGradlePluginVersion", Versions.getAndroidGradlePluginVersion()); + prop.setProperty("bladeInkVersion", Versions.getBladeInkVersion()); + + saveGradleProperties(prop, projectPath); + } + + /** + * Checks if the model folder exists in the passed folder or in his parent. + * + * @return The correct project folder or null if the model folder is not found. + */ + private File checkProjectStructure(File folder) { + File projectFolder = folder; + + if (!new File(getAssetPath(projectFolder.getAbsolutePath()) + MODEL_PATH).exists()) { + projectFolder = projectFolder.getParentFile(); + + if (!new File(getAssetPath(projectFolder.getAbsolutePath()) + MODEL_PATH).exists()) + return null; + } + + return projectFolder; + } + + public BaseActor getActor(String id) { + return selectedScene.getActor(id, false); + } + + public List getResolutions() { + File atlasesPath = new File(getAssetPath() + UI_PATH); + ArrayList l = new ArrayList<>(); + + File[] list = atlasesPath.listFiles(); + + if (list == null) + return l; + + for (int i = 0; i < list.length; i++) { + String name = list[i].getName(); + + if (list[i].isDirectory()) { + try { + Float.parseFloat(name); + + l.add(name); + } catch (Exception e) { + + } + } + } + + return l; + } + + public String getResDir() { + return "1"; + } + + public void loadChapter(String selChapter) throws IOException { + undoStack.clear(); + + setSelectedScene(null); + + try { + chapter.load(selChapter); + firePropertyChange(NOTIFY_CHAPTER_LOADED); + getEditorConfig().setProperty(LAST_PROJECT_PROP, projectFile.getAbsolutePath()); + getEditorConfig().setProperty("project.selectedChapter", selChapter); + } catch (SerializationException ex) { + // check for not compiled custom actions + if (ex.getCause() != null && ex.getCause() instanceof ClassNotFoundException) { + EditorLogger.msg("Custom action class not found. Trying to compile..."); + if (RunProccess.runGradle(getProjectDir(), "desktop:compileJava")) { + ((FolderClassLoader) ActionFactory.getActionClassLoader()).reload(); + try { + chapter.load(selChapter); + } catch (SerializationException e) { + throw new IOException("Couldn't load project."); + } + } else { + throw new IOException("Failed to run Gradle."); + } + } else { + throw new IOException(ex.getMessage()); + } + } + + i18n.load(selChapter); + } + + public boolean isModified() { + return modified; + } + + public void setModified() { + modified = true; + firePropertyChange(NOTIFY_MODEL_MODIFIED); + } + + public OrderedProperties getGradleProperties(File projectPath) throws FileNotFoundException, IOException { + OrderedProperties prop = new OrderedPropertiesBuilder().withSuppressDateInComment(true) + .withOrderingCaseSensitive().build(); + + prop.load(new FileReader(projectPath.getAbsolutePath() + "/gradle.properties")); + + return prop; + } + + public void saveGradleProperties(OrderedProperties prop, File projectPath) throws IOException { + FileOutputStream os = new FileOutputStream(projectPath.getAbsolutePath() + "/gradle.properties"); + + prop.store(os, null); + } + + public void toggleEditorVisibility(BaseActor a) { + String name = a.getInitScene() + "." + a.getId(); + + if (hiddenActors.contains(name)) { + hiddenActors.remove(name); + } else { + hiddenActors.add(name); + } + } + + public boolean isEditorVisible(BaseActor a) { + String name = a.getInitScene() + "." + a.getId(); + + return !hiddenActors.contains(name); + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/PropertyChange.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/model/PropertyChange.java similarity index 95% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/model/PropertyChange.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/model/PropertyChange.java index 4de281bf8..49da18a2d 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/model/PropertyChange.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/model/PropertyChange.java @@ -19,7 +19,7 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; -import com.bladecoder.engineeditor.utils.EditorLogger; +import com.bladecoder.engineeditor.common.EditorLogger; public class PropertyChange { @@ -55,7 +55,7 @@ protected void firePropertyChange(String propertyName, Object oldValue, protected void firePropertyChange(PropertyChangeEvent evt) { - //EngineLogger.debug(propertyName + "-> NEW: "+ newValue + " OLD:" + oldValue); + //EditorLogger.debug(propertyName + "-> NEW: "+ newValue + " OLD:" + oldValue); propertyChangeSupport.firePropertyChange(evt); } diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/ActionVisitor.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/ActionVisitor.java new file mode 100644 index 000000000..b923da9da --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/ActionVisitor.java @@ -0,0 +1,10 @@ +package com.bladecoder.engineeditor.qa; + +import com.bladecoder.engine.actions.Action; +import com.bladecoder.engine.model.InteractiveActor; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.Verb; + +public interface ActionVisitor extends Visitor { + public void visit(Scene scn, InteractiveActor a, Verb v, Action act); +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/ActorVisitor.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/ActorVisitor.java new file mode 100644 index 000000000..a84e652e0 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/ActorVisitor.java @@ -0,0 +1,7 @@ +package com.bladecoder.engineeditor.qa; + +import com.bladecoder.engine.model.BaseActor; + +public interface ActorVisitor extends Visitor { + public void visit(BaseActor a); +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/DialogOptionVisitor.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/DialogOptionVisitor.java new file mode 100644 index 000000000..7f346be31 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/DialogOptionVisitor.java @@ -0,0 +1,9 @@ +package com.bladecoder.engineeditor.qa; + +import com.bladecoder.engine.model.CharacterActor; +import com.bladecoder.engine.model.Dialog; +import com.bladecoder.engine.model.DialogOption; + +public interface DialogOptionVisitor extends Visitor { + public void visit(CharacterActor a, Dialog d, DialogOption o); +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/DialogVisitor.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/DialogVisitor.java new file mode 100644 index 000000000..5879035c8 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/DialogVisitor.java @@ -0,0 +1,8 @@ +package com.bladecoder.engineeditor.qa; + +import com.bladecoder.engine.model.CharacterActor; +import com.bladecoder.engine.model.Dialog; + +public interface DialogVisitor extends Visitor { + public void visit(CharacterActor a, Dialog d); +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/EndVisitor.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/EndVisitor.java new file mode 100644 index 000000000..1b09fb490 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/EndVisitor.java @@ -0,0 +1,7 @@ +package com.bladecoder.engineeditor.qa; + +import com.bladecoder.engine.model.World; + +public interface EndVisitor extends Visitor { + public void end(World w); +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/ModelWalker.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/ModelWalker.java new file mode 100644 index 000000000..4e2127f12 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/ModelWalker.java @@ -0,0 +1,132 @@ +package com.bladecoder.engineeditor.qa; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import com.bladecoder.engine.actions.Action; +import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.CharacterActor; +import com.bladecoder.engine.model.Dialog; +import com.bladecoder.engine.model.DialogOption; +import com.bladecoder.engine.model.InteractiveActor; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.Verb; +import com.bladecoder.engine.model.World; +import com.bladecoder.engineeditor.Ctx; + +public class ModelWalker { + + private final ArrayList sceneVisitors = new ArrayList(); + private final ArrayList endVisitors = new ArrayList(); + private final ArrayList startVisitors = new ArrayList(); + private final ArrayList actionVisitors = new ArrayList(); + private final ArrayList verbVisitors = new ArrayList(); + private final ArrayList actorVisitors = new ArrayList(); + private final ArrayList dialogVisitors = new ArrayList(); + private final ArrayList optionVisitors = new ArrayList(); + + public void addVisitor(Visitor v) { + if (v instanceof SceneVisitor) + sceneVisitors.add((SceneVisitor) v); + + if (v instanceof EndVisitor) + endVisitors.add((EndVisitor) v); + + if (v instanceof StartVisitor) + startVisitors.add((StartVisitor) v); + + if (v instanceof ActionVisitor) + actionVisitors.add((ActionVisitor) v); + + if (v instanceof VerbVisitor) + verbVisitors.add((VerbVisitor) v); + + if (v instanceof ActorVisitor) + actorVisitors.add((ActorVisitor) v); + + if (v instanceof DialogVisitor) + dialogVisitors.add((DialogVisitor) v); + + if (v instanceof DialogOptionVisitor) + optionVisitors.add((DialogOptionVisitor) v); + } + + public void walk(World w) { + Map scenes = Ctx.project.getWorld().getScenes(); + + for (StartVisitor sv : startVisitors) + sv.start(w); + + for (Scene scn : scenes.values()) { + for (SceneVisitor sv : sceneVisitors) + sv.visit(scn); + + Map actors = scn.getActors(); + + // SCENE VERBS + HashMap verbs = scn.getVerbManager().getVerbs(); + + for (Verb v : verbs.values()) { + + for (VerbVisitor vv : verbVisitors) + vv.visit(scn, null, v); + + ArrayList actions = v.getActions(); + + for (Action act : actions) { + for (ActionVisitor av : actionVisitors) + av.visit(scn, null, v, act); + } + } + + for (BaseActor a : actors.values()) { + for (ActorVisitor av : actorVisitors) + av.visit(a); + + if (a instanceof InteractiveActor) { + InteractiveActor ia = (InteractiveActor) a; + + // ACTOR VERBS + verbs = ia.getVerbManager().getVerbs(); + + for (Verb v : verbs.values()) { + + for (VerbVisitor vv : verbVisitors) + vv.visit(scn, ia, v); + + ArrayList actions = v.getActions(); + + for (Action act : actions) { + for (ActionVisitor av : actionVisitors) + av.visit(scn, ia, v, act); + } + } + } + + // DIALOGS + if (a instanceof CharacterActor) { + HashMap dialogs = ((CharacterActor) a).getDialogs(); + + if (dialogs != null) { + for (Dialog d : dialogs.values()) { + + for (DialogVisitor dv : dialogVisitors) + dv.visit((CharacterActor) a, d); + + ArrayList options = d.getOptions(); + + for (DialogOption o : options) { + for (DialogOptionVisitor ov : optionVisitors) + ov.visit((CharacterActor) a, d, o); + } + } + } + } + } + } + + for (EndVisitor ev : endVisitors) + ev.end(w); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/QA.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/QA.java new file mode 100644 index 000000000..4108de16e --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/QA.java @@ -0,0 +1,20 @@ +package com.bladecoder.engineeditor.qa; + +import com.bladecoder.engine.model.World; +import com.bladecoder.engineeditor.qa.rules.CheckCutmodeEnd; +import com.bladecoder.engineeditor.qa.rules.CheckDesc; +import com.bladecoder.engineeditor.qa.rules.CheckInteractionVerbs; +import com.bladecoder.engineeditor.qa.rules.Stats; + +public class QA { + public void run(World w) { + ModelWalker mw = new ModelWalker(); + + mw.addVisitor(new Stats()); + mw.addVisitor(new CheckInteractionVerbs()); + mw.addVisitor(new CheckDesc()); + mw.addVisitor(new CheckCutmodeEnd()); + + mw.walk(w); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/SceneVisitor.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/SceneVisitor.java new file mode 100644 index 000000000..d650ac87a --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/SceneVisitor.java @@ -0,0 +1,7 @@ +package com.bladecoder.engineeditor.qa; + +import com.bladecoder.engine.model.Scene; + +public interface SceneVisitor extends Visitor { + public void visit(Scene s); +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/StartVisitor.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/StartVisitor.java new file mode 100644 index 000000000..0650dd8bc --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/StartVisitor.java @@ -0,0 +1,7 @@ +package com.bladecoder.engineeditor.qa; + +import com.bladecoder.engine.model.World; + +public interface StartVisitor extends Visitor { + public void start(World w); +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/VerbVisitor.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/VerbVisitor.java new file mode 100644 index 000000000..2618aac87 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/VerbVisitor.java @@ -0,0 +1,9 @@ +package com.bladecoder.engineeditor.qa; + +import com.bladecoder.engine.model.InteractiveActor; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.Verb; + +public interface VerbVisitor extends Visitor { + public void visit(Scene s, InteractiveActor a, Verb v); +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/Visitor.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/Visitor.java new file mode 100644 index 000000000..546b5686e --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/Visitor.java @@ -0,0 +1,4 @@ +package com.bladecoder.engineeditor.qa; + +public interface Visitor { +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/rules/CheckCutmodeEnd.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/rules/CheckCutmodeEnd.java new file mode 100644 index 000000000..b472fba5e --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/rules/CheckCutmodeEnd.java @@ -0,0 +1,56 @@ +package com.bladecoder.engineeditor.qa.rules; + +import java.util.ArrayList; + +import com.bladecoder.engine.actions.Action; +import com.bladecoder.engine.actions.SetCutmodeAction; +import com.bladecoder.engine.model.InteractiveActor; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.Verb; +import com.bladecoder.engine.util.ActionUtils; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.qa.VerbVisitor; + +/** + * Checks that cutmode is set to false before ending the verb if it was previously set to true. + * @author rgarcia + */ +public class CheckCutmodeEnd implements VerbVisitor { + + + @Override + public void visit(Scene s, InteractiveActor a, Verb v) { + ArrayList actions = v.getActions(); + + if(actions.size() > 0) { + Action action = actions.get(actions.size() - 1); + + if (action instanceof SetCutmodeAction) { + try { + String val = ActionUtils.getStringValue(action, "value"); + + if("true".equals(val)) { + StringBuilder sb = new StringBuilder("CheckCutmodeEnd: Cutmode ends with value=true! - "); + + if(s != null) { + sb.append(s.getId()); + sb.append("."); + } + + if(a != null) { + sb.append(a.getId()); + sb.append("."); + } + + sb.append(v.getId()); + + EditorLogger.error(sb.toString()); + } + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + + } + } + } + } + +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/rules/CheckDesc.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/rules/CheckDesc.java new file mode 100644 index 000000000..8c1bf5e5b --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/rules/CheckDesc.java @@ -0,0 +1,57 @@ +package com.bladecoder.engineeditor.qa.rules; + +import java.util.HashMap; + +import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.InteractiveActor; +import com.bladecoder.engine.model.Verb; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.qa.ActorVisitor; + +/** + * Checks that all interactive actors have description. + * @author rgarcia + * + */ +public class CheckDesc implements ActorVisitor { + + private InteractiveActor ia; + + private boolean hasLeave; + private boolean hasEnterExit; + + @Override + public void visit(BaseActor a) { + if (a instanceof InteractiveActor) { + ia = (InteractiveActor) a; + + hasLeave = false; + hasEnterExit = false; + + if (ia.getInteraction()) { + + HashMap verbs = ia.getVerbManager().getVerbs(); + + for(Verb v:verbs.values()) + checkVerb(v); + + // TODO: check states and verbs for states. + + if (hasLeave || hasEnterExit) + return; + + if(ia.getDesc() == null || ia.getDesc().trim().isEmpty()) { + EditorLogger.error("CheckDesc: " + a.getScene().getId() + "." + a.getId()); + } + } + } + } + + public void checkVerb(Verb v) { + if (v.getId().equals("leave")) + hasLeave = true; + else if (v.getId().equals("enter") || v.getId().equals("exit")) + hasEnterExit = true; + } + +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/rules/CheckInteractionVerbs.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/rules/CheckInteractionVerbs.java new file mode 100644 index 000000000..94fcf1421 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/rules/CheckInteractionVerbs.java @@ -0,0 +1,106 @@ +package com.bladecoder.engineeditor.qa.rules; + +import java.util.HashMap; + +import com.bladecoder.engine.anim.AnimationDesc; +import com.bladecoder.engine.model.AtlasRenderer; +import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.InteractiveActor; +import com.bladecoder.engine.model.SpriteActor; +import com.bladecoder.engine.model.Verb; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.qa.ActorVisitor; + +/** + * Checks: + * - That inventory actors has the use verb. + * - Interactive actors have lookat and pickup/talkto verbs. + * - SpriteActors have at least one animation. + * + * @author rgarcia + * + */ +public class CheckInteractionVerbs implements ActorVisitor { + + private InteractiveActor ia; + private boolean hasLookat; + private boolean hasPickup; + private boolean hasTalkto; + private boolean hasLeave; + private boolean hasEnterExit; + private boolean hasUse; + + @Override + public void visit(BaseActor a) { + if (a instanceof InteractiveActor) { + ia = (InteractiveActor) a; + hasLookat = false; + hasPickup = false; + hasTalkto = false; + hasLeave = false; + hasEnterExit = false; + hasUse = false; + + if (ia.getInteraction()) { + + HashMap verbs = ia.getVerbManager().getVerbs(); + + for(Verb v:verbs.values()) + checkVerb(v); + + // TODO: check states and verbs for states. + + if (hasLeave || hasEnterExit) + return; + + // discard inventory actors + if(hasLookat) { + if(ia instanceof SpriteActor) { + SpriteActor sa = (SpriteActor)ia; + if(sa.getRenderer() instanceof AtlasRenderer) { + AtlasRenderer r = (AtlasRenderer)sa.getRenderer(); + HashMap animations = r.getAnimations(); + + if(animations.size() == 0) { + EditorLogger.error("CheckInteractionVerbs: Actor with no animations! - " + sa.getScene().getId() + "." + sa.getId()); + } + + if(animations.get(r.getInitAnimation()).source.contains("inventory")) { + if(!hasUse) + EditorLogger.msg("CheckInteractionVerbs: Inventory item should has default 'use' - " + sa.getScene().getId() + "." + sa.getId()); + + return; + } + } + } + } + + // check for lookat and pickup/talk verbs + if (!hasLookat || (!hasPickup && !hasTalkto)) { + String msg = "CheckInteractionVerbs: " + a.getScene().getId() + "." + a.getId(); + + if(!hasLookat) + EditorLogger.error(msg); + else + EditorLogger.msg(msg); + } + } + } + } + + public void checkVerb(Verb v) { + if (v.getId().equals("lookat")) + hasLookat = true; + else if (v.getId().equals("pickup")) + hasPickup = true; + else if (v.getId().equals("talkto")) + hasTalkto = true; + else if (v.getId().equals("leave")) + hasLeave = true; + else if (v.getId().equals("use")) + hasUse = true; + else if (v.getId().equals("enter") || v.getId().equals("exit")) + hasEnterExit = true; + } + +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/rules/Stats.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/rules/Stats.java new file mode 100644 index 000000000..bdfc5f091 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/qa/rules/Stats.java @@ -0,0 +1,23 @@ +package com.bladecoder.engineeditor.qa.rules; + +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.World; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.qa.EndVisitor; +import com.bladecoder.engineeditor.qa.SceneVisitor; + +public class Stats implements SceneVisitor, EndVisitor { + + int numScenes = 0; + + @Override + public void visit(Scene s) { + numScenes++; + } + + @Override + public void end(World w) { + EditorLogger.msg("Num Scenes: " + numScenes); + } + +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/AnimationDrawer.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/AnimationDrawer.java new file mode 100644 index 000000000..c138b983b --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/AnimationDrawer.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.scneditor; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.utils.Align; +import com.bladecoder.engine.anim.AnimationDesc; +import com.bladecoder.engine.anim.Tween; +import com.bladecoder.engine.model.*; +import com.bladecoder.engine.spine.SpineRenderer; +import com.bladecoder.engine.util.RectangleRenderer; + +/** + * Frame Animation renderer. + * + * @author rgarcia + */ +public class AnimationDrawer { + + public static final Color BG_COLOR = Color.MAGENTA; + private static final float HEIGHT = 200; + + AnimationDesc currentAnimation; + private AnimationRenderer renderer; + private float viewportW, viewportH; + + public void setViewport(float w, float h) { + viewportW = w; + viewportH = h; + } + + public void setActor(BaseActor a) { + if (renderer != null) { + renderer.dispose(); + renderer = null; + } + + if (a instanceof SpriteActor && ((SpriteActor) a).getRenderer() instanceof AnimationRenderer) { + ActorRenderer r = ((SpriteActor) a).getRenderer(); + + if (r instanceof SpineRenderer) { + renderer = new SpineRenderer(); + ((SpineRenderer) renderer).enableEvents(false); + ((SpineRenderer) renderer).setSkin(((SpineRenderer) r).getSkin()); + } else if (r instanceof ImageRenderer) { + renderer = new ImageRenderer(); + } else if (r instanceof AtlasRenderer) { + renderer = new AtlasRenderer(); + } + + renderer.setOrgAlign(Align.bottom); + } + } + + public void setAnimation(AnimationDesc fa) { + currentAnimation = fa; + + if (renderer != null) { + + renderer.getAnimations().clear(); + + if (fa != null) { + + renderer.addAnimation(fa); + + renderer.retrieveAssets(); + + renderer.startAnimation(fa.id, Tween.Type.REPEAT, Tween.INFINITY, null); + } + } + } + + public void draw(SpriteBatch batch) { + if (renderer != null && currentAnimation != null) { + + float width = HEIGHT / renderer.getHeight() * renderer.getWidth(); + float height = HEIGHT; + float scaleh = width / renderer.getWidth(); + + if (renderer.getWidth() > renderer.getHeight()) { + scaleh = HEIGHT / renderer.getWidth(); + width = HEIGHT; + height = renderer.getHeight() * scaleh; + } + + RectangleRenderer.draw(batch, viewportW - width - 5, viewportH + - height - 55, width + 10, height + 10, Color.BLACK); + RectangleRenderer.draw(batch, viewportW - width, viewportH - height + - 50, width, height, BG_COLOR); + + renderer.draw(batch, viewportW - width / 2, + viewportH - height - 50, scaleh, scaleh, 0f, null); + + } + } + + public void update(float delta) { + if (renderer != null && currentAnimation != null) { + try { + renderer.update(delta); + } catch (Exception e) { + + } + } + } + + public void dispose() { + if (renderer != null) + renderer.dispose(); + } + +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/AnimationWidget.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/AnimationWidget.java new file mode 100644 index 000000000..27bfa4874 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/AnimationWidget.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.scneditor; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.scenes.scene2d.ui.Widget; +import com.badlogic.gdx.utils.Align; +import com.bladecoder.engine.anim.AnimationDesc; +import com.bladecoder.engine.anim.AtlasAnimationDesc; +import com.bladecoder.engine.anim.Tween; +import com.bladecoder.engine.assets.EngineAssetManager; +import com.bladecoder.engine.model.ActorRenderer; +import com.bladecoder.engine.model.AnimationRenderer; +import com.bladecoder.engine.model.AtlasRenderer; +import com.bladecoder.engine.model.ImageRenderer; +import com.bladecoder.engine.spine.SpineRenderer; +import com.bladecoder.engine.util.RectangleRenderer; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.EditAnimationDialog; + +public class AnimationWidget extends Widget { + private AnimationDesc fa; + private ActorRenderer renderer; + EditAnimationDialog editFADialog; + + public AnimationWidget(EditAnimationDialog createEditFADialog) { + this.editFADialog = createEditFADialog; + } + + public void setSource(String type, AnimationDesc anim) { + fa = anim; + + if (renderer != null) { + renderer.dispose(); + renderer = null; + } + + if (type.equals(Project.SPINE_RENDERER_STRING)) { + renderer = new SpineRenderer(); + ((SpineRenderer) renderer).enableEvents(false); + } else if (type.equals(Project.IMAGE_RENDERER_STRING)) { + renderer = new ImageRenderer(); + } else { + renderer = new AtlasRenderer(); + } + + renderer.setOrgAlign(Align.bottom); + + try { + renderer.loadAssets(); + EngineAssetManager.getInstance().finishLoading(); + renderer.retrieveAssets(); + } catch (Exception e) { + EditorLogger.error("Error loading asset: " + e.getMessage()); + } + } + + public String[] getAnimations() { + try { + return ((AnimationRenderer) renderer).getInternalAnimations(fa); + } catch (Exception e) { + // Message.show(getStage(), + // "Error loading animations from selected source", 4); + EditorLogger.error("Error loading animations from selected source:" + fa.source + ": " + e.getMessage()); + return new String[0]; + } + + } + + public void setAnimation(String id, String speedStr, Tween.Type t) { + + if (fa != null && id != null && !id.isEmpty()) { + + if (fa instanceof AtlasAnimationDesc) + ((AtlasAnimationDesc) fa).regions = null; + + Tween.Type type = Tween.Type.REPEAT; + float speed = 2.0f; + + if (speedStr != null && !speedStr.isEmpty()) { + try { + speed = Float.parseFloat(speedStr); + } catch (NumberFormatException e) { + speed = 0; + } + } + + if (t == Tween.Type.YOYO) + type = Tween.Type.YOYO; + else if (t == Tween.Type.REVERSE) + type = Tween.Type.REVERSE_REPEAT; + + fa.id = id; + fa.duration = speed; + fa.animationType = type; + fa.count = -1; + + ((AnimationRenderer) renderer).getAnimations().clear(); + + ((AnimationRenderer) renderer).addAnimation(fa); + ((AnimationRenderer) renderer).startAnimation(fa.id, Tween.Type.SPRITE_DEFINED, 1, null); + } + } + + @Override + public void draw(Batch batch, float parentAlpha) { + super.draw(batch, parentAlpha); + + if (renderer == null || ((AnimationRenderer) renderer).getCurrentAnimation() == null) + return; + + float tmp = batch.getPackedColor(); + batch.setColor(Color.WHITE); + + renderer.update(Gdx.graphics.getDeltaTime()); + + RectangleRenderer.draw(batch, getX(), getY(), getWidth(), getHeight(), Color.MAGENTA); + + float scalew = getWidth() / renderer.getWidth(); + float scaleh = getHeight() / renderer.getHeight(); + float scale = scalew > scaleh ? scaleh : scalew; + renderer.draw((SpriteBatch) batch, getX() + renderer.getWidth() * scale / 2, getY(), scale, scale, 0f, null); + batch.setPackedColor(tmp); + } + + public void dispose() { + renderer.dispose(); + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/CanvasDrawer.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/CanvasDrawer.java similarity index 51% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/CanvasDrawer.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/CanvasDrawer.java index 86d365c35..32e7ddb26 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/scneditor/CanvasDrawer.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/CanvasDrawer.java @@ -20,54 +20,83 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.math.Polygon; import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.bladecoder.engine.model.AnchorActor; import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.InteractiveActor; +import com.bladecoder.engine.model.ObstacleActor; import com.bladecoder.engine.model.Scene; -import com.bladecoder.engine.model.SceneCamera; import com.bladecoder.engine.model.SpriteActor; -import com.bladecoder.engine.pathfinder.NavNode; +import com.bladecoder.engine.model.WalkZoneActor; import com.bladecoder.engine.polygonalpathfinder.NavNodePolygonal; -import com.bladecoder.engine.util.EngineLogger; import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; public class CanvasDrawer { public static final float CORNER_DIST = 20; - private static final Color MOUSESELECTION_FILL_COLOR = new Color(0.2f, - 0.2f, 0.8f, 0.4f); - private static final Color MOUSESELECTION_STROKE_COLOR = new Color(0.2f, - 0.2f, 0.8f, 1f); + private static final Color MOUSESELECTION_FILL_COLOR = new Color(0.2f, 0.2f, 0.8f, 0.4f); + private static final Color MOUSESELECTION_STROKE_COLOR = new Color(0.2f, 0.2f, 0.8f, 1f); private final ShapeRenderer drawer = new ShapeRenderer(); - private SceneCamera camera; + private OrthographicCamera camera; public CanvasDrawer() { } - public void setCamera(SceneCamera camera) { + public void setCamera(OrthographicCamera camera) { this.camera = camera; } - public void drawBBoxActors(Scene scn) { + public void drawBBoxActors(Scene scn, boolean showSpriteBounds) { drawer.setProjectionMatrix(camera.combined); drawer.setTransformMatrix(new Matrix4()); drawer.begin(ShapeType.Line); - drawer.setColor(Scene.ACTOR_BBOX_COLOR); for (BaseActor a : scn.getActors().values()) { + + if (!Ctx.project.isEditorVisible(a)) + continue; + Polygon p = a.getBBox(); if (p == null) { - EngineLogger.error("ERROR DRAWING BBOX FOR: " + a.getId()); + EditorLogger.error("ERROR DRAWING BBOX FOR: " + a.getId()); } // Rectangle r = a.getBBox().getBoundingRectangle(); - drawer.polygon(p.getTransformedVertices()); + if (a instanceof ObstacleActor) { + drawer.setColor(Scene.OBSTACLE_COLOR); + drawer.polygon(p.getTransformedVertices()); + } else if (a instanceof InteractiveActor) { + InteractiveActor iActor = (InteractiveActor) a; + + if (a instanceof SpriteActor && !showSpriteBounds) + continue; + + if (!scn.getLayer(iActor.getLayer()).isVisible()) + continue; + + drawer.setColor(Scene.ACTOR_BBOX_COLOR); + if (p.getTransformedVertices().length > 2) + drawer.polygon(p.getTransformedVertices()); + } else if (a instanceof WalkZoneActor) { + drawer.setColor(Scene.WALKZONE_COLOR); + if (p.getTransformedVertices().length > 2) + drawer.polygon(p.getTransformedVertices()); + } else if (a instanceof AnchorActor) { + drawer.setColor(Scene.ANCHOR_COLOR); + drawer.line(p.getX() - Scene.ANCHOR_RADIUS, p.getY(), p.getX() + Scene.ANCHOR_RADIUS, p.getY()); + drawer.line(p.getX(), p.getY() - Scene.ANCHOR_RADIUS, p.getX(), p.getY() + Scene.ANCHOR_RADIUS); + } + // drawer.rect(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } @@ -80,28 +109,17 @@ public void drawBBoxWalkZone(Scene scn, boolean lineOfSight) { drawer.setProjectionMatrix(camera.combined); drawer.setTransformMatrix(new Matrix4()); drawer.begin(ShapeType.Line); - - drawer.setColor(Scene.WALKZONE_COLOR); - drawer.polygon(scn.getPolygonalNavGraph().getWalkZone() - .getTransformedVertices()); - - ArrayList obstacles = scn.getPolygonalNavGraph() - .getObstacles(); - drawer.setColor(Scene.OBSTACLE_COLOR); - for (Polygon p : obstacles) { - drawer.polygon(p.getTransformedVertices()); - } + drawer.setColor(Scene.WALKZONE_COLOR); + drawer.polygon(scn.getPolygonalNavGraph().getWalkZone().getTransformedVertices()); // DRAW LINEs OF SIGHT if (lineOfSight) { drawer.setColor(Color.WHITE); - ArrayList nodes = scn.getPolygonalNavGraph() - .getGraphNodes(); + ArrayList nodes = scn.getPolygonalNavGraph().getGraphNodes(); for (NavNodePolygonal n : nodes) { - for (NavNode n2 : n.neighbors) { - drawer.line(n.x, n.y, ((NavNodePolygonal) n2).x, - ((NavNodePolygonal) n2).y); + for (NavNodePolygonal n2 : n.neighbors) { + drawer.line(n.x, n.y, n2.x, n2.y); } } } @@ -114,29 +132,50 @@ public void drawSelectedActor(BaseActor selectedActor) { Gdx.gl20.glEnable(GL20.GL_BLEND); // Gdx.gl20.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); - Rectangle rect = selectedActor.getBBox().getBoundingRectangle(); drawer.setProjectionMatrix(camera.combined); - drawer.setTransformMatrix(new Matrix4()); + // drawer.setTransformMatrix(new Matrix4()); - drawer.begin(ShapeRenderer.ShapeType.Filled); - drawer.setColor(MOUSESELECTION_FILL_COLOR); - drawer.rect(rect.x, rect.y, rect.width, rect.height); - drawer.end(); + if (selectedActor instanceof AnchorActor) { + drawer.begin(ShapeRenderer.ShapeType.Line); + drawer.setColor(MOUSESELECTION_STROKE_COLOR); + drawer.rect(selectedActor.getX() - Scene.ANCHOR_RADIUS, selectedActor.getY() - Scene.ANCHOR_RADIUS, + Scene.ANCHOR_RADIUS * 2, Scene.ANCHOR_RADIUS * 2); + drawer.end(); + } else { - drawer.begin(ShapeRenderer.ShapeType.Line); - drawer.setColor(MOUSESELECTION_STROKE_COLOR); - drawer.rect(rect.x, rect.y, rect.width, rect.height); - - // DRAW SELECTION BOUNDS - if (!(selectedActor instanceof SpriteActor) - || !((SpriteActor) selectedActor).isBboxFromRenderer()) { - float verts[] = selectedActor.getBBox().getTransformedVertices(); - for (int i = 0; i < verts.length; i += 2) - drawer.rect(verts[i] - CORNER_DIST / 2, verts[i + 1] - - CORNER_DIST / 2, CORNER_DIST, CORNER_DIST); + Polygon p = selectedActor.getBBox(); + + Rectangle rect = p.getBoundingRectangle(); + + drawer.begin(ShapeRenderer.ShapeType.Filled); + drawer.setColor(MOUSESELECTION_FILL_COLOR); + drawer.rect(rect.x, rect.y, rect.width, rect.height); + drawer.end(); + + drawer.begin(ShapeRenderer.ShapeType.Line); + drawer.setColor(MOUSESELECTION_STROKE_COLOR); + drawer.rect(rect.x, rect.y, rect.width, rect.height); + + // DRAW SELECTION BOUNDS + if ((!(selectedActor instanceof SpriteActor) || !((SpriteActor) selectedActor).isBboxFromRenderer()) + && !(selectedActor instanceof AnchorActor)) { + float verts[] = selectedActor.getBBox().getTransformedVertices(); + for (int i = 0; i < verts.length; i += 2) + drawer.rect(verts[i] - CORNER_DIST / 2, verts[i + 1] - CORNER_DIST / 2, CORNER_DIST, CORNER_DIST); + } + + // DRAW REFPOINT + if (selectedActor instanceof InteractiveActor) { + Vector2 refPoint = ((InteractiveActor) selectedActor).getRefPoint(); + float orgX = selectedActor.getX() + refPoint.x; + float orgY = selectedActor.getY() + refPoint.y; + drawer.line(orgX - Scene.ANCHOR_RADIUS, orgY, orgX + Scene.ANCHOR_RADIUS, orgY); + drawer.line(orgX, orgY - Scene.ANCHOR_RADIUS, orgX, orgY + Scene.ANCHOR_RADIUS); + } + + drawer.end(); } - drawer.end(); } public void drawBGBounds() { @@ -148,8 +187,7 @@ public void drawBGBounds() { drawer.begin(ShapeRenderer.ShapeType.Line); drawer.setColor(Color.MAGENTA); - drawer.rect(0, 0, Ctx.project.getWorld().getWidth(), Ctx.project - .getWorld().getHeight()); + drawer.rect(0, 0, Ctx.project.getWorld().getWidth(), Ctx.project.getWorld().getHeight()); drawer.end(); } @@ -163,8 +201,7 @@ public void drawPolygonVertices(Polygon p, Color c) { drawer.setColor(c); for (int i = 0; i < verts.length; i += 2) - drawer.rect(verts[i] - CORNER_DIST / 2, verts[i + 1] - CORNER_DIST - / 2, CORNER_DIST, CORNER_DIST); + drawer.rect(verts[i] - CORNER_DIST / 2, verts[i + 1] - CORNER_DIST / 2, CORNER_DIST, CORNER_DIST); drawer.end(); } diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/ScnEditor.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/ScnEditor.java new file mode 100644 index 000000000..724e75cfe --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/ScnEditor.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.scneditor; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.IOException; + +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Button; +import com.badlogic.gdx.scenes.scene2d.ui.ButtonGroup; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.Drawable; +import com.bladecoder.engine.util.Config; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.common.RunProccess; +import com.bladecoder.engineeditor.model.Project; + +public class ScnEditor extends Table { + + private ScnWidget scnWidget; + private TextButton testButton; + + private ButtonGroup

{ + + ScnWidget scnWidget; + com.bladecoder.engine.model.BaseActor actor; + + public ToolsWindow(Skin skin, ScnWidget sw) { + + scnWidget = sw; + + Table table = new Table(skin); + TextButton tmpButton = new TextButton("Temporal tool", skin, "no-toggled"); + TextButton testOnAndroidButton = new TextButton("Test on Android device", skin, "no-toggled"); + TextButton testOnIphoneEmulatorButton = new TextButton("Test on Iphone emulator", skin, "no-toggled"); + TextButton testOnIpadEmulatorButton = new TextButton("Test on Ipad emulator", skin, "no-toggled"); + TextButton testOnIOSDeviceButton = new TextButton("Test on IOS device", skin, "no-toggled"); + TextButton exportTSVButton = new TextButton("I18N - Export texts as .tsv", skin, "no-toggled"); + TextButton importTSVButton = new TextButton("I18N - Import.tsv file", skin, "no-toggled"); + + TextButton exportUIImages = new TextButton("Export UI Images", skin, "no-toggled"); + TextButton createUIAtlas = new TextButton("Create UI Atlas", skin, "no-toggled"); + TextButton particleEditor = new TextButton("Particle Editor", skin, "no-toggled"); + TextButton compileInk = new TextButton("Compile Ink Script", skin, "no-toggled"); + + table.defaults().left().expandX(); + table.top().pad(DPIUtils.getSpacing() / 2); + table.add(new Label("Tools", skin, "big")).center(); + + Drawable drawable = skin.getDrawable("trans"); + setBackground(drawable); + + table.row(); + table.add(testOnAndroidButton).expandX().fill(); + + table.row(); + table.add(testOnIphoneEmulatorButton).expandX().fill(); + + table.row(); + table.add(testOnIpadEmulatorButton).expandX().fill(); + + table.row(); + table.add(testOnIOSDeviceButton).expandX().fill(); + + // disable if not mac + if (!System.getProperty("os.name").toLowerCase().contains("mac")) { + testOnIphoneEmulatorButton.setDisabled(true); + testOnIpadEmulatorButton.setDisabled(true); + testOnIOSDeviceButton.setDisabled(true); + } + + table.row(); + table.add(exportTSVButton).expandX().fill(); + + table.row(); + table.add(importTSVButton).expandX().fill(); + + table.row(); + table.add(exportUIImages).expandX().fill(); + + table.row(); + table.add(createUIAtlas).expandX().fill(); + + table.row(); + table.add(particleEditor).expandX().fill(); + + table.row(); + table.add(compileInk).expandX().fill(); + + // table.row(); + // table.add(tmpButton).expandX().fill(); + + // ADD CUTMODE FOR VERBS THAT ONLY HAVE A LOOKAT OR SAY ACTION + tmpButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + ModelTools.fixSaySubtitleActor(); + + Message.showMsg(getStage(), "TOOL PROCESSED", 4); + } + + }); + + // TEST ON ANDROID DEVICE + testOnAndroidButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + testOnAndroid(); + } + + }); + + testOnIphoneEmulatorButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + testOnIphoneEmulator(); + } + + }); + + testOnIpadEmulatorButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + testOnIpadEmulator(); + } + + }); + + testOnIOSDeviceButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + testOnIOSDevice(); + } + + }); + + exportTSVButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + exportTSV(); + } + }); + + importTSVButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + importTSV(); + } + }); + + exportUIImages.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + exportUIImages(); + } + }); + + createUIAtlas.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + createUIAtlas(); + } + }); + + particleEditor.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + particleEditor(); + } + }); + + compileInk.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + compileInk(); + } + }); + + table.pack(); + setActor(table); + prefSize(table.getWidth(), Math.max(200, table.getHeight())); + setSize(table.getWidth(), Math.max(200, table.getHeight())); + } + + protected void compileInk() { + new CompileInkDialog(getActor().getSkin()).show(getStage()); + } + + protected void createUIAtlas() { + FileChooser fileChooser = new FileChooser(Mode.OPEN); + fileChooser.setSize(Gdx.graphics.getWidth() * 0.7f, Gdx.graphics.getHeight() * 0.7f); + fileChooser.setViewMode(ViewMode.LIST); + + fileChooser.setSelectionMode(SelectionMode.DIRECTORIES); + getStage().addActor(fileChooser); + + fileChooser.setListener(new FileChooserListener() { + + @Override + public void selected(Array files) { + + List res = Ctx.project.getResolutions(); + + for (String r : res) { + float scale = Float.parseFloat(r); + + try { + int maxWH = (int) (ImageUtils.getRecommendedAtlasSize() * scale); + + ImageUtils.createAtlas(files.get(0).file().getAbsolutePath(), + Ctx.project.getAssetPath() + Project.UI_PATH + "/" + r, "ui" + ".atlas", scale, maxWH, + maxWH, TextureFilter.Linear, TextureFilter.Nearest, "png", false); + } catch (IOException e) { + EditorLogger.error(e.getMessage()); + Message.showMsgDialog(getStage(), "Error creating atlas", e.getMessage()); + return; + } + } + + Message.showMsg(getStage(), "UI Atlas created sucessfully.", 4); + } + + @Override + public void canceled() { + + } + }); + + } + + protected void exportUIImages() { + FileChooser fileChooser = new FileChooser(Mode.OPEN); + fileChooser.setSize(Gdx.graphics.getWidth() * 0.7f, Gdx.graphics.getHeight() * 0.7f); + fileChooser.setViewMode(ViewMode.LIST); + + fileChooser.setSelectionMode(SelectionMode.DIRECTORIES); + getStage().addActor(fileChooser); + + fileChooser.setListener(new FileChooserListener() { + + @Override + public void selected(Array files) { + try { + // fileChooser.setTitle("Select the file to export the + // project texts"); + + ImageUtils.unpackAtlas(new File(Ctx.project.getAssetPath() + Project.UI_PATH + "/1/ui.atlas"), + files.get(0).file()); + + Message.showMsg(getStage(), "UI Atlas images exported sucessfully.", 4); + } catch (Exception e) { + Message.showMsg(getStage(), "There was a problem exporting images from UI Atlas.", 4); + EditorLogger.printStackTrace(e); + } + } + + @Override + public void canceled() { + + } + }); + + } + + private void exportTSV() { + + FileChooser fileChooser = new FileChooser(Mode.SAVE); + fileChooser.setSize(Gdx.graphics.getWidth() * 0.7f, Gdx.graphics.getHeight() * 0.7f); + fileChooser.setViewMode(ViewMode.LIST); + + fileChooser.setSelectionMode(SelectionMode.FILES); + getStage().addActor(fileChooser); + + fileChooser.setListener(new FileChooserListener() { + + @Override + public void selected(Array files) { + try { + // fileChooser.setTitle("Select the file to export the + // project texts"); + + I18NUtils.exportTSV(Ctx.project.getAssetPath() + Project.MODEL_PATH, + files.get(0).file().getAbsolutePath(), Ctx.project.getChapter().getId(), "default"); + + Message.showMsg(getStage(), files.get(0).file().getName() + " exported sucessfully.", 4); + } catch (IOException e) { + Message.showMsg(getStage(), "There was a problem generating the .tsv file.", 4); + EditorLogger.printStackTrace(e); + } + } + + @Override + public void canceled() { + + } + }); + } + + private void importTSV() { + + FileChooser fileChooser = new FileChooser(Mode.OPEN); + fileChooser.setSize(Gdx.graphics.getWidth() * 0.7f, Gdx.graphics.getHeight() * 0.7f); + fileChooser.setViewMode(ViewMode.LIST); + + fileChooser.setSelectionMode(SelectionMode.FILES); + getStage().addActor(fileChooser); + + fileChooser.setListener(new FileChooserListener() { + + @Override + public void selected(Array files) { + try { + // chooser.setTitle("Select the .tsv file to import"); + + I18NUtils.importTSV(Ctx.project.getAssetPath() + Project.MODEL_PATH, + files.get(0).file().getAbsolutePath(), Ctx.project.getChapter().getId(), "default"); + + // Reload texts + Ctx.project.getI18N().load(Ctx.project.getChapter().getId()); + + Message.showMsg(getStage(), files.get(0).file().getName() + " imported sucessfully.", 4); + + } catch (IOException e) { + Message.showMsg(getStage(), "There was a problem importing the .tsv file.", 4); + EditorLogger.printStackTrace(e); + } + } + + @Override + public void canceled() { + + } + }); + } + + private void testOnAndroid() { + if (Ctx.project.getSelectedScene() == null) { + String msg = "There are no scenes in this chapter."; + Message.showMsg(getStage(), msg, 3); + return; + } + + Ctx.project.getProjectConfig().setProperty(Config.CHAPTER_PROP, Ctx.project.getChapter().getId()); + Ctx.project.getProjectConfig().setProperty(Config.TEST_SCENE_PROP, Ctx.project.getSelectedScene().getId()); + Ctx.project.setModified(); + + try { + Ctx.project.saveProject(); + } catch (Exception ex) { + String msg = "Something went wrong while saving the project.\n\n" + ex.getClass().getSimpleName() + " - " + + ex.getMessage(); + Message.showMsgDialog(getStage(), "Error", msg); + return; + } + + new Thread(new Runnable() { + Stage stage = getStage(); + + @Override + public void run() { + Message.showMsg(stage, "Running scene on Android device...", 5); + + if (!RunProccess.runGradle(Ctx.project.getProjectDir(), + "android:uninstallFullDebug android:installFullDebug android:run")) { + Message.showMsg(stage, "There was a problem running the project", 4); + } + + Ctx.project.getProjectConfig().removeProperty(Config.CHAPTER_PROP); + Ctx.project.getProjectConfig().removeProperty(Config.TEST_SCENE_PROP); + Ctx.project.setModified(); + + try { + Ctx.project.saveProject(); + } catch (Exception ex) { + String msg = "Something went wrong while saving the project.\n\n" + ex.getClass().getSimpleName() + + " - " + ex.getMessage(); + EditorLogger.error(msg); + return; + } + + } + }).start(); + + } + + private void testOnIphoneEmulator() { + if (Ctx.project.getSelectedScene() == null) { + String msg = "There are no scenes in this chapter."; + Message.showMsg(getStage(), msg, 3); + return; + } + + Ctx.project.getProjectConfig().setProperty(Config.CHAPTER_PROP, Ctx.project.getChapter().getId()); + Ctx.project.getProjectConfig().setProperty(Config.TEST_SCENE_PROP, Ctx.project.getSelectedScene().getId()); + Ctx.project.setModified(); + + try { + Ctx.project.saveProject(); + } catch (Exception ex) { + String msg = "Something went wrong while saving the project.\n\n" + ex.getClass().getSimpleName() + " - " + + ex.getMessage(); + Message.showMsgDialog(getStage(), "Error", msg); + return; + } + + new Thread(new Runnable() { + Stage stage = getStage(); + + @Override + public void run() { + Message.showMsg(stage, "Running scene on Iphone emulator...", 5); + + if (!RunProccess.runGradle(Ctx.project.getProjectDir(), "ios:launchIPhoneSimulator")) { + Message.showMsg(stage, "There was a problem running the project", 4); + } + + Ctx.project.getProjectConfig().removeProperty(Config.CHAPTER_PROP); + Ctx.project.getProjectConfig().removeProperty(Config.TEST_SCENE_PROP); + Ctx.project.setModified(); + + try { + Ctx.project.saveProject(); + } catch (Exception ex) { + String msg = "Something went wrong while saving the project.\n\n" + ex.getClass().getSimpleName() + + " - " + ex.getMessage(); + EditorLogger.error(msg); + return; + } + + } + }).start(); + + } + + private void testOnIpadEmulator() { + if (Ctx.project.getSelectedScene() == null) { + String msg = "There are no scenes in this chapter."; + Message.showMsg(getStage(), msg, 3); + return; + } + + Ctx.project.getProjectConfig().setProperty(Config.CHAPTER_PROP, Ctx.project.getChapter().getId()); + Ctx.project.getProjectConfig().setProperty(Config.TEST_SCENE_PROP, Ctx.project.getSelectedScene().getId()); + Ctx.project.setModified(); + + try { + Ctx.project.saveProject(); + } catch (Exception ex) { + String msg = "Something went wrong while saving the project.\n\n" + ex.getClass().getSimpleName() + " - " + + ex.getMessage(); + Message.showMsgDialog(getStage(), "Error", msg); + return; + } + + new Thread(new Runnable() { + Stage stage = getStage(); + + @Override + public void run() { + Message.showMsg(stage, "Running scene on Ipad simulator...", 5); + + if (!RunProccess.runGradle(Ctx.project.getProjectDir(), "ios:launchIPadSimulator")) { + Message.showMsg(stage, "There was a problem running the project", 4); + } + + Ctx.project.getProjectConfig().removeProperty(Config.CHAPTER_PROP); + Ctx.project.getProjectConfig().removeProperty(Config.TEST_SCENE_PROP); + Ctx.project.setModified(); + + try { + Ctx.project.saveProject(); + } catch (Exception ex) { + String msg = "Something went wrong while saving the project.\n\n" + ex.getClass().getSimpleName() + + " - " + ex.getMessage(); + EditorLogger.error(msg); + return; + } + + } + }).start(); + + } + + private void testOnIOSDevice() { + if (Ctx.project.getSelectedScene() == null) { + String msg = "There are no scenes in this chapter."; + Message.showMsg(getStage(), msg, 3); + return; + } + + Ctx.project.getProjectConfig().setProperty(Config.CHAPTER_PROP, Ctx.project.getChapter().getId()); + Ctx.project.getProjectConfig().setProperty(Config.TEST_SCENE_PROP, Ctx.project.getSelectedScene().getId()); + Ctx.project.setModified(); + + try { + Ctx.project.saveProject(); + } catch (Exception ex) { + String msg = "Something went wrong while saving the project.\n\n" + ex.getClass().getSimpleName() + " - " + + ex.getMessage(); + Message.showMsgDialog(getStage(), "Error", msg); + return; + } + + new Thread(new Runnable() { + Stage stage = getStage(); + + @Override + public void run() { + Message.showMsg(stage, "Running scene on IOS device...", 5); + + if (!RunProccess.runGradle(Ctx.project.getProjectDir(), "ios:launchIOSDevice")) { + Message.showMsg(stage, "There was a problem running the project", 4); + } + + Ctx.project.getProjectConfig().removeProperty(Config.CHAPTER_PROP); + Ctx.project.getProjectConfig().removeProperty(Config.TEST_SCENE_PROP); + Ctx.project.setModified(); + + try { + Ctx.project.saveProject(); + } catch (Exception ex) { + String msg = "Something went wrong while saving the project.\n\n" + ex.getClass().getSimpleName() + + " - " + ex.getMessage(); + EditorLogger.error(msg); + return; + } + + } + }).start(); + + } + + private void particleEditor() { + // Open the particle editor + List cp = new ArrayList<>(); + // check that particle editor exists + String[] particleEditorPaths = { + "../thirdparty/gdx-particle-editor.jar", + "./adventure-editor/thirdparty/gdx-particle-editor.jar", + "./thirdparty/gdx-particle-editor.jar" + }; + + String particleEditorPath = null; + + boolean found = false; + + for (String path : particleEditorPaths) { + File f = new File(path); + if (f.exists()) { + particleEditorPath = path; + found = true; + break; + } + } + + if (!found) { + Message.showMsgDialog(getStage(), "Error", "Particle Editor not found."); + return; + } + + cp.add(particleEditorPath); + try { + RunProccess.runJavaProccess("com.ray3k.gdxparticleeditor.lwjgl3.Lwjgl3Launcher", cp, null); + } catch (IOException e) { + Message.showMsgDialog(getStage(), "Error", "Error launching Particle Editor."); + EditorLogger.printStackTrace(e); + } + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/ViewWindow.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/ViewWindow.java new file mode 100644 index 000000000..a75db61c5 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/scneditor/ViewWindow.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.scneditor; + +import com.badlogic.gdx.scenes.scene2d.ui.CheckBox; +import com.badlogic.gdx.scenes.scene2d.ui.Container; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.Drawable; +import com.bladecoder.engine.util.DPIUtils; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; + +public class ViewWindow extends Container
{ + ScnWidget scnWidget; + + CheckBox spriteBounds; + + public ViewWindow(Skin skin, ScnWidget sw) { + + scnWidget = sw; + + Table table = new Table(skin); + table.defaults().left().expandX(); + table.top().pad(DPIUtils.getSpacing() / 2); + table.top(); + table.add(new Label("View", skin, "big")).center(); + + Drawable drawable = skin.getDrawable("trans"); + setBackground(drawable); + table.row(); + + final CheckBox inSceneCb = new CheckBox("Animations in scene", skin); + inSceneCb.setChecked(scnWidget.getInSceneSprites()); + table.add(inSceneCb); + + table.row(); + final CheckBox animCb = new CheckBox("Show Animations", skin); + animCb.setChecked(scnWidget.getAnimation()); + table.add(animCb); + + table.row(); + spriteBounds = new CheckBox("Show Sprite Bounds", skin); + spriteBounds.setChecked(scnWidget.getShowSpriteBounds()); + table.add(spriteBounds); + + table.row(); + final CheckBox console = new CheckBox("Show Debug Console", skin); + console.setChecked(EditorLogger.console.isVisible()); + table.add(console); + + table.row(); + final CheckBox fullscreen = new CheckBox("Play in fullscreen", skin); + fullscreen.setChecked( + Boolean.parseBoolean(Ctx.project.getEditorConfig().getProperty("view.fullscreenPlay", "false"))); + table.add(fullscreen); + + inSceneCb.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, com.badlogic.gdx.scenes.scene2d.Actor actor) { + scnWidget.setInSceneSprites(inSceneCb.isChecked()); + } + }); + + animCb.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, com.badlogic.gdx.scenes.scene2d.Actor actor) { + scnWidget.setAnimation(animCb.isChecked()); + } + }); + + spriteBounds.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, com.badlogic.gdx.scenes.scene2d.Actor actor) { + scnWidget.setShowSpriteBounds(spriteBounds.isChecked()); + } + }); + + console.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, com.badlogic.gdx.scenes.scene2d.Actor actor) { + EditorLogger.console.setVisible(console.isChecked()); + } + }); + + fullscreen.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, com.badlogic.gdx.scenes.scene2d.Actor actor) { + Ctx.project.getEditorConfig().setProperty("view.fullscreenPlay", + Boolean.toString(fullscreen.isChecked())); + } + }); + + table.pack(); + setActor(table); + + prefSize(table.getWidth(), Math.max(200, table.getHeight())); + setSize(table.getWidth(), Math.max(200, table.getHeight())); + } + + public void showWalkZone() { + scnWidget.setShowSpriteBounds(true); + spriteBounds.setChecked(true); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/setup/BladeEngineSetup.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/setup/BladeEngineSetup.java new file mode 100644 index 000000000..d9c11fd35 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/setup/BladeEngineSetup.java @@ -0,0 +1,446 @@ +/******************************************************************************* + * Copyright 2011 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 com.bladecoder.engineeditor.setup; + +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.RunProccess; +import com.bladecoder.engineeditor.common.Versions; + +import java.io.*; +import java.util.HashMap; +import java.util.Map; + +/** + * Command line tool to generate libgdx projects + * + * @author rgarcia + */ +public class BladeEngineSetup { + public static boolean isSdkLocationValid(String sdkLocation) { + return new File(sdkLocation, "platforms").exists(); + } + + public static boolean isEmptyDirectory(String destination) { + if (new File(destination).exists()) { + return new File(destination).list().length == 0; + } else { + return true; + } + } + + public static boolean isSdkUpToDate(String sdkLocation) { + + File apis = new File(sdkLocation, "platforms"); + if (!apis.exists()) { + EditorLogger.error("You have no Android APIs!\nUpdate your Android SDK with API level: " + + Versions.getAndroidAPILevel()); + return false; + } + + int newestLocalApi = getLatestApi(apis); + if (newestLocalApi > Integer.parseInt(Versions.getAndroidAPILevel())) { + + // ALWAYS USE THE CURRENT API + Versions.setAndroidAPILevel(Integer.toString(newestLocalApi)); + + EditorLogger.error("Using API level: " + Versions.getAndroidAPILevel()); + } else { + if (!hasFileInDirectory(apis, "android-" + Versions.getAndroidAPILevel())) { + EditorLogger.error( + "Please update your Android SDK, you need the Android API: " + Versions.getAndroidAPILevel()); + return false; + } + } + return true; + } + + private static boolean hasFileInDirectory(File file, String fileName) { + for (String name : file.list()) { + if (name.equals(fileName)) + return true; + } + return false; + } + + private static int getLatestApi(File apis) { + int apiLevel = 0; + for (File api : apis.listFiles()) { + int level = readAPIVersion(api); + if (level > apiLevel) + apiLevel = level; + } + return apiLevel; + } + + private static int readAPIVersion(File parentFile) { + File properties = new File(parentFile, "source.properties"); + FileReader reader; + BufferedReader buffer; + try { + reader = new FileReader(properties); + buffer = new BufferedReader(reader); + + String line = null; + + while ((line = buffer.readLine()) != null) { + if (line.contains("AndroidVersion.ApiLevel")) { + + String versionString = line.split("\\=")[1]; + int apiLevel = Integer.parseInt(versionString); + + buffer.close(); + reader.close(); + + return apiLevel; + } + } + } catch (IOException | NumberFormatException e) { + EditorLogger.printStackTrace(e); + } + + return 0; + } + + public void build(String outputDir, String appName, String packageName, String mainClass, String sdkLocation, + boolean spinePlugin) throws IOException { + ProjectSetup project = new ProjectSetup(); + + String packageDir = packageName.replace('.', '/'); + String sdkPath = null; + + if (sdkLocation != null && !sdkLocation.isEmpty()) + sdkPath = sdkLocation.replace('\\', '/'); + + if (!isSdkLocationValid(sdkLocation)) { + EditorLogger.error("Android SDK location '" + sdkLocation + "' doesn't contain an SDK"); + } else if (!isSdkUpToDate(sdkLocation)) { + // SHOW THE ANDROID SDK MANAGER?? + } + + // root dir/gradle files + project.files.add(new ProjectFile("gitignore", ".gitignore", false)); + project.files.add(new ProjectFile("settings.gradle", false)); + project.files.add(new ProjectFile("gradlew", false)); + project.files.add(new ProjectFile("gradlew.bat", false)); + project.files.add(new ProjectFile("gradle/wrapper/gradle-wrapper.jar", false)); + project.files.add(new ProjectFile("gradle/wrapper/gradle-wrapper.properties", false)); + project.files.add(new ProjectFile("gradle.properties")); + project.files.add(new ProjectFile("build.gradle", false)); + + // core project + project.files.add(new ProjectFile("core/build.gradle")); + new File(outputDir + "/core/src/main/java").mkdirs(); + + // DESKTOP project + project.files.add(new ProjectFile("desktop/build.gradle")); + project.files.add(new ProjectFile("desktop/src/DesktopLauncher", + "desktop/src/main/java/com/bladecoder/engine/DesktopLauncher.java", true)); + + project.files.add( + new ProjectFile("desktop/src/icons/icon16.png", "desktop/src/main/resources/icons/icon16.png", false)); + project.files.add( + new ProjectFile("desktop/src/icons/icon32.png", "desktop/src/main/resources/icons/icon32.png", false)); + project.files.add(new ProjectFile("desktop/src/icons/icon128.png", + "desktop/src/main/resources/icons/icon128.png", false)); + + // Assets + String assetPath = "assets"; + + // CREATE ASSETS EMPTY FOLDERS + new File(outputDir + "/" + assetPath + "/atlases/1").mkdirs(); + new File(outputDir + "/" + assetPath + "/images/1").mkdirs(); + new File(outputDir + "/" + assetPath + "/model").mkdirs(); + new File(outputDir + "/" + assetPath + "/music").mkdirs(); + new File(outputDir + "/" + assetPath + "/sounds").mkdirs(); + new File(outputDir + "/" + assetPath + "/spine").mkdirs(); + new File(outputDir + "/" + assetPath + "/voices").mkdirs(); + new File(outputDir + "/" + assetPath + "/particles").mkdirs(); + new File(outputDir + "/" + assetPath + "/tests").mkdirs(); + new File(outputDir + "/" + assetPath + "/ui/1").mkdirs(); + new File(outputDir + "/" + assetPath + "/ui/fonts").mkdirs(); + + project.files.add(new ProjectFile("assets/model/00.chapter.json", assetPath + "/model/00.chapter.json", false)); + project.files.add(new ProjectFile("assets/model/00.properties", assetPath + "/model/00.properties", false)); + project.files + .add(new ProjectFile("assets/model/world.properties", assetPath + "/model/world.properties", false)); + project.files.add(new ProjectFile("assets/model/world", assetPath + "/model/world", false)); + project.files.add( + new ProjectFile("assets/model/world_es.properties", assetPath + "/model/world_es.properties", false)); + + project.files.add(new ProjectFile("assets/ui/credits.txt", assetPath + "/ui/credits.txt", false)); + project.files + .add(new ProjectFile("assets/ui/fonts/PaytoneOne.ttf", assetPath + "/ui/fonts/PaytoneOne.ttf", false)); + project.files.add(new ProjectFile("assets/ui/fonts/ArchitectsDaughter.ttf", + assetPath + "/ui/fonts/ArchitectsDaughter.ttf", false)); + project.files.add( + new ProjectFile("assets/ui/fonts/Roboto-Black.ttf", assetPath + "/ui/fonts/Roboto-Black.ttf", false)); + project.files.add(new ProjectFile("assets/ui/fonts/Roboto-Regular.ttf", + assetPath + "/ui/fonts/Roboto-Regular.ttf", false)); + project.files.add( + new ProjectFile("assets/ui/fonts/Roboto-Thin.ttf", assetPath + "/ui/fonts/Roboto-Thin.ttf", false)); + project.files.add(new ProjectFile("assets/ui/fonts/Ubuntu-M.ttf", assetPath + "/ui/fonts/Ubuntu-M.ttf", false)); + project.files.add(new ProjectFile("assets/ui/ui.json", assetPath + "/ui/ui.json", false)); + + project.files.add(new ProjectFile("assets/ui/1/blade_logo.png", assetPath + "/ui/1/blade_logo.png", false)); + project.files.add(new ProjectFile("assets/ui/1/helpDesktop.png", assetPath + "/ui/1/helpDesktop.png", false)); + project.files + .add(new ProjectFile("assets/ui/1/helpDesktop_es.png", assetPath + "/ui/1/helpDesktop_es.png", false)); + project.files.add(new ProjectFile("assets/ui/1/helpPie.png", assetPath + "/ui/1/helpPie.png", false)); + project.files.add(new ProjectFile("assets/ui/1/helpPie_es.png", assetPath + "/ui/1/helpPie_es.png", false)); + project.files.add(new ProjectFile("assets/ui/1/libgdx_logo.png", assetPath + "/ui/1/libgdx_logo.png", false)); + project.files.add(new ProjectFile("assets/ui/1/ui.atlas", assetPath + "/ui/1/ui.atlas", false)); + project.files.add(new ProjectFile("assets/ui/1/ui.png", assetPath + "/ui/1/ui.png", false)); + + project.files + .add(new ProjectFile("assets/BladeEngine.properties", assetPath + "/BladeEngine.properties", false)); + + // ANDROID project + project.files.add(new ProjectFile("android/res/values/strings.xml")); + project.files.add(new ProjectFile("android/res/values/styles.xml", false)); + project.files.add(new ProjectFile("android/res/drawable-hdpi/ic_launcher.png", false)); + project.files.add(new ProjectFile("android/res/drawable-mdpi/ic_launcher.png", false)); + project.files.add(new ProjectFile("android/res/drawable-xhdpi/ic_launcher.png", false)); + project.files.add(new ProjectFile("android/res/drawable-xxhdpi/ic_launcher.png", false)); + project.files.add(new ProjectFile("android/res/drawable-xxxhdpi/ic_launcher.png", false)); + project.files.add(new ProjectFile("android/src/AndroidLauncher", + "android/src/main/java/com/bladecoder/engine/AndroidLauncher.java", true)); + project.files.add(new ProjectFile("android/AndroidManifest.xml")); + project.files.add(new ProjectFile("android/src/expansion/AndroidManifest.xml")); + project.files.add(new ProjectFile("android/build.gradle", true)); + project.files.add(new ProjectFile("android/ic_launcher-web.png", false)); + project.files.add(new ProjectFile("android/proguard-rules.pro", false)); + + if (sdkLocation != null) + project.files.add(new ProjectFile("local.properties", true)); + + // IOS ROBOVM + project.files.add(new ProjectFile("ios/src/IOSLauncher", + "ios/src/main/java/com/bladecoder/engine/IOSLauncher.java", true)); + project.files.add(new ProjectFile("ios/data/Default.png", false)); + project.files.add(new ProjectFile("ios/data/Default@2x.png", false)); + project.files.add(new ProjectFile("ios/data/Default@2x~ipad.png", false)); + project.files.add(new ProjectFile("ios/data/Default-568h@2x.png", false)); + project.files.add(new ProjectFile("ios/data/Default~ipad.png", false)); + project.files.add(new ProjectFile("ios/data/Default-375w-667h@2x.png", false)); + project.files.add(new ProjectFile("ios/data/Default-414w-736h@3x.png", false)); + project.files.add(new ProjectFile("ios/data/Default-1024w-1366h@2x~ipad.png", false)); + project.files.add(new ProjectFile("ios/data/Default-375w-812h@3x.png", false)); + + project.files.add(new ProjectFile("ios/data/Media.xcassets/Contents.json", false)); + project.files + .add(new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/app-store-icon-1024@1x.png", false)); + project.files.add(new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/Contents.json", false)); + project.files.add(new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/ipad-app-icon-76@1x.png", false)); + project.files.add(new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/ipad-app-icon-76@2x.png", false)); + project.files.add( + new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/ipad-notifications-icon-20@1x.png", false)); + project.files.add( + new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/ipad-notifications-icon-20@2x.png", false)); + project.files.add( + new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/ipad-pro-app-icon-83.5@2x.png", false)); + project.files + .add(new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/ipad-settings-icon-29@1x.png", false)); + project.files + .add(new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/ipad-settings-icon-29@2x.png", false)); + project.files.add( + new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/ipad-spotlight-icon-40@1x.png", false)); + project.files.add( + new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/ipad-spotlight-icon-40@2x.png", false)); + project.files + .add(new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/iphone-app-icon-60@2x.png", false)); + project.files + .add(new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/iphone-app-icon-60@3x.png", false)); + project.files.add(new ProjectFile( + "ios/data/Media.xcassets/AppIcon.appiconset/iphone-notification-icon-20@2x.png", false)); + project.files.add(new ProjectFile( + "ios/data/Media.xcassets/AppIcon.appiconset/iphone-notification-icon-20@3x.png", false)); + project.files.add( + new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-icon-40@2x.png", false)); + project.files.add( + new ProjectFile("ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-icon-40@3x.png", false)); + project.files.add(new ProjectFile( + "ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-settings-icon-29@2x.png", false)); + project.files.add(new ProjectFile( + "ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-settings-icon-29@3x.png", false)); + + project.files.add(new ProjectFile("ios/build.gradle", true)); + project.files.add(new ProjectFile("ios/Info.plist.xml", false)); + project.files.add(new ProjectFile("ios/robovm.properties")); + project.files.add(new ProjectFile("ios/robovm.xml", true)); + + Map values = new HashMap<>(); + values.put("%APP_NAME%", appName); + values.put("%APP_NAME_ESCAPED%", appName.replace("'", "\\'")); + values.put("%PACKAGE%", packageName); + values.put("%PACKAGE_DIR%", packageDir); + values.put("%MAIN_CLASS%", mainClass); + values.put("%USE_SPINE%", Boolean.toString(spinePlugin)); + + if (sdkPath != null) + values.put("%ANDROID_SDK%", sdkPath); + + values.put("%ASSET_PATH%", assetPath); + values.put("%API_LEVEL%", Versions.getAndroidAPILevel()); + + values.put("%BLADE_ENGINE_VERSION%", Versions.getVersion()); + values.put("%LIBGDX_VERSION%", Versions.getLibgdxVersion()); + values.put("%ROBOVM_VERSION%", Versions.getRoboVMVersion()); + + values.put("%ANDROID_GRADLE_PLUGIN_VERSION%", Versions.getAndroidGradlePluginVersion()); + + values.put("%BLADE_INK_VERSION%", Versions.getBladeInkVersion()); + + copyAndReplace(outputDir, project, values); + + // HACK executable flag isn't preserved for whatever reason... + new File(outputDir, "gradlew").setExecutable(true); + + RunProccess.runGradle(new File(outputDir), "desktop:clean"); + } + + private void copyAndReplace(String outputDir, ProjectSetup project, Map values) throws IOException { + File out = new File(outputDir); + if (!out.exists() && !out.mkdirs()) { + throw new RuntimeException("Couldn't create output directory '" + out.getAbsolutePath() + "'"); + } + + for (ProjectFile file : project.files) { + copyFile(file, out, values); + } + } + + private byte[] readResource(String resource, String path) { + InputStream in = null; + try { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024 * 10]; + in = BladeEngineSetup.class.getResourceAsStream(path + resource); + if (in == null) + throw new RuntimeException("Couldn't read resource '" + resource + "'"); + int read = 0; + while ((read = in.read(buffer)) > 0) { + bytes.write(buffer, 0, read); + } + return bytes.toByteArray(); + } catch (IOException e) { + throw new RuntimeException("Couldn't read resource '" + resource + "'", e); + } finally { + if (in != null) + try { + in.close(); + } catch (IOException e) { + } + } + } + + private byte[] readResource(File file) throws IOException { + InputStream in = null; + try { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024 * 10]; + in = new FileInputStream(file); + int read = 0; + while ((read = in.read(buffer)) > 0) { + bytes.write(buffer, 0, read); + } + return bytes.toByteArray(); + } catch (Exception e) { + throw new IOException("Couldn't read resource '" + file.getAbsoluteFile() + "'", e); + } finally { + if (in != null) + try { + in.close(); + } catch (IOException e) { + } + } + } + + private String readResourceAsString(String resource, String path) { + try { + return new String(readResource(resource, path), "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + private String readResourceAsString(File file) throws IOException { + try { + return new String(readResource(file), "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + private void writeFile(File outFile, byte[] bytes) { + OutputStream out = null; + + try { + out = new BufferedOutputStream(new FileOutputStream(outFile)); + out.write(bytes); + } catch (IOException e) { + throw new RuntimeException("Couldn't write file '" + outFile.getAbsolutePath() + "'", e); + } finally { + if (out != null) + try { + out.close(); + } catch (IOException e) { + } + } + } + + private void writeFile(File outFile, String text) { + try { + writeFile(outFile, text.getBytes("UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + private void copyFile(ProjectFile file, File out, Map values) throws IOException { + File outFile = new File(out, file.outputName); + if (!outFile.getParentFile().exists() && !outFile.getParentFile().mkdirs()) { + throw new RuntimeException("Couldn't create dir '" + outFile.getAbsolutePath() + "'"); + } + + boolean isTemp = file instanceof TemporaryProjectFile; + + if (file.isTemplate) { + String txt; + if (isTemp) { + txt = readResourceAsString(((TemporaryProjectFile) file).file); + } else { + txt = readResourceAsString(file.resourceName, file.resourceLoc); + } + txt = replace(txt, values); + writeFile(outFile, txt); + } else { + if (isTemp) { + writeFile(outFile, readResource(((TemporaryProjectFile) file).file)); + } else { + writeFile(outFile, readResource(file.resourceName, file.resourceLoc)); + } + } + } + + private String replace(String txt, Map values) { + for (String key : values.keySet()) { + String value = values.get(key); + txt = txt.replace(key, value); + } + return txt; + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/ProjectFile.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/setup/ProjectFile.java similarity index 96% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/ProjectFile.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/setup/ProjectFile.java index 3fd6b1f1d..c19aea56e 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/ProjectFile.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/setup/ProjectFile.java @@ -17,7 +17,7 @@ package com.bladecoder.engineeditor.setup; /** - * A file in a {@link Project}, the resourceName specifies the location + * A file in a {@link ProjectSetup}, the resourceName specifies the location * of the template file, the outputName specifies the final name of the * file relative to its project, the isTemplate field specifies if * values need to be replaced in this file or not. diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/Project.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/setup/ProjectSetup.java similarity index 97% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/Project.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/setup/ProjectSetup.java index feac73741..7143d09b4 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/Project.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/setup/ProjectSetup.java @@ -1,17 +1,17 @@ -/******************************************************************************* - * Copyright 2011 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. +/******************************************************************************* + * Copyright 2011 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 com.bladecoder.engineeditor.setup; @@ -27,7 +27,7 @@ * @author badlogic * */ -public class Project { +public class ProjectSetup { /** list of files, relative to project directory **/ public List files = new ArrayList(); } \ No newline at end of file diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/TemporaryProjectFile.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/setup/TemporaryProjectFile.java similarity index 98% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/TemporaryProjectFile.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/setup/TemporaryProjectFile.java index 62c10a25d..f4059cab7 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/setup/TemporaryProjectFile.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/setup/TemporaryProjectFile.java @@ -19,7 +19,7 @@ import java.io.File; /** - * A temporary file that wraps {@link ProjectFile} for use in a {@link Project} + * A temporary file that wraps {@link ProjectFile} for use in a {@link ProjectSetup} * @author Tomski * */ diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ActionList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ActionList.java new file mode 100644 index 000000000..24b6ad217 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ActionList.java @@ -0,0 +1,755 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.reflect.Field; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.utils.Array; +import com.bladecoder.engine.actions.AbstractControlAction; +import com.bladecoder.engine.actions.AbstractIfAction; +import com.bladecoder.engine.actions.Action; +import com.bladecoder.engine.actions.ActorAnimationRef; +import com.bladecoder.engine.actions.CommentAction; +import com.bladecoder.engine.actions.DisableActionAction; +import com.bladecoder.engine.actions.EndAction; +import com.bladecoder.engine.actions.SceneActorRef; +import com.bladecoder.engine.model.Verb; +import com.bladecoder.engine.util.ActionUtils; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.ElementUtils; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.CellRenderer; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.ModelList; +import com.bladecoder.engineeditor.ui.panels.ScopePanel; +import com.bladecoder.engineeditor.undo.UndoDeleteAction; + +public class ActionList extends ModelList { + private static final String CONTROL_ACTION_ID_ATTR = "caID"; + + Skin skin; + + private ImageButton upBtn; + private ImageButton downBtn; + + private ImageButton disableBtn; + + private String scope; + + private final List multiClipboard = new ArrayList(); + + public ActionList(Skin skin) { + super(skin, false); + this.skin = skin; + + setCellRenderer(listCellRenderer); + + disableBtn = new ImageButton(skin); + toolbar.addToolBarButton(disableBtn, "ic_eye", "Enable/Disable", "Enable/Disable"); + + disableBtn.setDisabled(false); + + disableBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + toggleEnabled(); + } + }); + + upBtn = new ImageButton(skin); + downBtn = new ImageButton(skin); + + toolbar.addToolBarButton(upBtn, "ic_up", "Move up", "Move up"); + toolbar.addToolBarButton(downBtn, "ic_down", "Move down", "Move down"); + toolbar.pack(); + + list.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + int pos = list.getSelectedIndex(); + + toolbar.disableEdit(pos == -1); + disableBtn.setDisabled(pos == -1); + upBtn.setDisabled(pos == -1 || pos == 0); + downBtn.setDisabled(pos == -1 || pos == list.getItems().size - 1); + } + }); + + list.getSelection().setMultiple(true); + + upBtn.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + up(); + } + }); + + downBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + down(); + } + }); + + Ctx.project.addPropertyChangeListener(Project.NOTIFY_ELEMENT_CREATED, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getNewValue() instanceof Action && !(evt.getSource() instanceof EditActionDialog)) { + addElements(parent, parent.getActions()); + } + } + }); + } + + private void toggleEnabled() { + + if (list.getSelection().size() <= 0) + return; + + Array sel = new Array(); + + for (Action a : list.getSelection().toArray()) { + + // CONTROL ACTIONS CAN'T BE DISABLED + if (a == null || isControlAction(a)) + continue; + + Array items = list.getItems(); + int pos = items.indexOf(a, true); + + if (a instanceof DisableActionAction) { + Action a2 = ((DisableActionAction) a).getAction(); + parent.getActions().set(pos, a2); + items.set(pos, a2); + sel.add(a2); + } else { + DisableActionAction a2 = new DisableActionAction(); + a2.setAction(a); + parent.getActions().set(pos, a2); + items.set(pos, a2); + sel.add(a2); + } + } + + Ctx.project.setModified(); + list.getSelection().clear(); + list.getSelection().addAll(sel); + } + + @Override + protected EditModelDialog getEditElementDialogInstance(Action e) { + EditActionDialog editActionDialog = new EditActionDialog(skin, parent, e, scope, list.getSelectedIndex()); + + return editActionDialog; + } + + public void setScope(String scope) { + this.scope = scope; + } + + @Override + protected void create() { + EditModelDialog dialog = getEditElementDialogInstance(null); + dialog.show(getStage()); + dialog.setListener(new ChangeListener() { + @SuppressWarnings("unchecked") + @Override + public void changed(ChangeEvent event, Actor actor) { + int pos = list.getSelectedIndex() + 1; + + Action e = ((EditModelDialog) actor).getElement(); + list.getItems().insert(pos, e); + parent.getActions().add(pos, e); + + list.getSelection().choose(list.getItems().get(pos)); + + if (isControlAction(e)) { + insertEndAction(pos + 1, getOrCreateControlActionId((AbstractControlAction) e)); + + if (e instanceof AbstractIfAction) + insertEndAction(pos + 2, getOrCreateControlActionId((AbstractControlAction) e)); + } + + list.invalidateHierarchy(); + } + }); + } + + private Action editedElement; + + @Override + protected void edit() { + + Action e = list.getSelected(); + + if (e == null || e instanceof EndAction || e instanceof DisableActionAction) + return; + + editedElement = (Action) ElementUtils.cloneElement(e); + + EditModelDialog dialog = getEditElementDialogInstance(e); + dialog.show(getStage()); + dialog.setListener(new ChangeListener() { + @SuppressWarnings("unchecked") + @Override + public void changed(ChangeEvent event, Actor actor) { + Action e = ((EditModelDialog) actor).getElement(); + int pos = list.getSelectedIndex(); + list.getItems().set(pos, e); + parent.getActions().set(pos, e); + + Ctx.project.setModified(); + + if (isControlAction(editedElement)) { + if (!editedElement.getClass().getName().equals(e.getClass().getName())) { + + deleteControlAction(pos, (AbstractControlAction) editedElement); + + if (isControlAction(e)) { + insertEndAction(pos + 1, + getOrCreateControlActionId((AbstractControlAction) e)); + + if (e instanceof AbstractIfAction) + insertEndAction(pos + 2, + getOrCreateControlActionId((AbstractControlAction) e)); + } + } else { + // insert previous caId + try { + ActionUtils.setParam(e, CONTROL_ACTION_ID_ATTR, + getOrCreateControlActionId((AbstractControlAction) editedElement)); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e1) { + EditorLogger.error(e1.getMessage()); + } + } + } + } + }); + } + + private String getOrCreateControlActionId(AbstractControlAction a) { + String id = a.getControlActionID(); + + if (id == null || id.isEmpty()) { + id = Integer.toString(MathUtils.random(1, Integer.MAX_VALUE)); + try { + ActionUtils.setParam(a, CONTROL_ACTION_ID_ATTR, id); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + EditorLogger.error(e.getMessage()); + } + } + + return id; + } + + private void insertEndAction(int pos, String id) { + final Action e = new EndAction(); + + try { + ActionUtils.setParam(e, CONTROL_ACTION_ID_ATTR, id); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e1) { + EditorLogger.error(e1.getMessage()); + } + + list.getItems().insert(pos, e); + parent.getActions().add(pos, e); + } + + @Override + protected void copy() { + if (parent == null || list.getSelection().size() == 0) + return; + + multiClipboard.clear(); + + for (Action e : getSortedSelection()) { + + if (e == null || e instanceof EndAction) + return; + + Action cloned = (Action) ElementUtils.cloneElement(e); + multiClipboard.add(cloned); + toolbar.disablePaste(false); + + // TRANSLATIONS + if (scope.equals(ScopePanel.WORLD_SCOPE)) + Ctx.project.getI18N().putTranslationsInElement(cloned, true); + else + Ctx.project.getI18N().putTranslationsInElement(cloned, false); + } + } + + @Override + protected void paste() { + + if (parent == null || multiClipboard.size() == 0) + return; + + Array sel = new Array(); + + for (int i = multiClipboard.size() - 1; i >= 0; i--) { + Action newElement = (Action) ElementUtils.cloneElement(multiClipboard.get(i)); + + int pos = list.getSelectedIndex() + 1; + + list.getItems().insert(pos, newElement); + parent.getActions().add(pos, newElement); + + if (scope.equals(ScopePanel.WORLD_SCOPE)) + Ctx.project.getI18N().extractStrings(null, null, parent.getHashKey(), pos, newElement); + else if (scope.equals(ScopePanel.SCENE_SCOPE)) + Ctx.project.getI18N().extractStrings(Ctx.project.getSelectedScene().getId(), null, parent.getHashKey(), + pos, newElement); + else + Ctx.project.getI18N().extractStrings(Ctx.project.getSelectedScene().getId(), + Ctx.project.getSelectedActor().getId(), parent.getHashKey(), pos, newElement); + + list.invalidateHierarchy(); + + if (isControlAction(newElement)) { + try { + ActionUtils.setParam(newElement, CONTROL_ACTION_ID_ATTR, null); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + EditorLogger.error(e.getMessage()); + } + + insertEndAction(pos + 1, getOrCreateControlActionId((AbstractControlAction) newElement)); + + if (newElement instanceof AbstractIfAction) + insertEndAction(pos + 2, getOrCreateControlActionId((AbstractControlAction) newElement)); + } + + sel.add(newElement); + } + + list.getSelection().clear(); + list.getSelection().addAll(sel); + Ctx.project.setModified(); + } + + @Override + protected void delete() { + if (list.getSelection().size() == 0) + return; + + multiClipboard.clear(); + + int pos = list.getSelectedIndex(); + + for (Action e : getSortedSelection()) { + + if (e instanceof EndAction) + continue; + + int pos2 = list.getItems().indexOf(e, true); + list.getItems().removeValue(e, true); + + int idx = parent.getActions().indexOf(e); + + parent.getActions().remove(e); + + multiClipboard.add(e); + + // TRANSLATIONS + if (scope.equals(ScopePanel.WORLD_SCOPE)) + Ctx.project.getI18N().putTranslationsInElement(e, true); + else + Ctx.project.getI18N().putTranslationsInElement(e, false); + + // UNDO + Ctx.project.getUndoStack().add(new UndoDeleteAction(parent, e, idx)); + + if (isControlAction(e)) + deleteControlAction(pos2, (AbstractControlAction) e); + + } + + if (list.getItems().size == 0) { + list.getSelection().clear(); + } else if (pos >= list.getItems().size) { + list.getSelection().choose(list.getItems().get(list.getItems().size - 1)); + } else { + list.getSelection().choose(list.getItems().get(pos)); + } + + toolbar.disablePaste(false); + + Ctx.project.setModified(); + } + + private Array getSortedSelection() { + Array array = list.getSelection().toArray(); + + array.sort(new Comparator() { + + @Override + public int compare(Action arg0, Action arg1) { + Integer i0 = list.getItems().indexOf(arg0, true); + Integer i1 = list.getItems().indexOf(arg1, true); + + return i0.compareTo(i1); + } + + }); + + return array; + } + + private boolean isControlAction(Action e) { + return e instanceof AbstractControlAction; + } + + private void deleteControlAction(int pos, final AbstractControlAction e) { + final String id = getOrCreateControlActionId(e); + + if (e instanceof AbstractIfAction) { + pos = deleteFirstActionNamed(pos, id); + } + + deleteFirstActionNamed(pos, id); + } + + private int deleteFirstActionNamed(int pos, String actionId) { + while (!(list.getItems().get(pos) instanceof AbstractControlAction + && getOrCreateControlActionId((AbstractControlAction) list.getItems().get(pos)).equals(actionId))) + pos++; + + Action e2 = list.getItems().removeIndex(pos); + parent.getActions().remove(e2); + + return pos; + } + + private void up() { + if (parent == null || list.getSelection().size() == 0) + return; + + Array sel = new Array(); + + for (Action a : getSortedSelection()) { + + int pos = list.getItems().indexOf(a, true); + + if (pos == -1 || pos == 0) + return; + + Array items = list.getItems(); + Action e = items.get(pos); + Action e2 = items.get(pos - 1); + + sel.add(e); + + if (isControlAction(e) && isControlAction(e2)) { + continue; + } + + parent.getActions().set(pos - 1, e); + parent.getActions().set(pos, e2); + + items.set(pos - 1, e); + items.set(pos, e2); + } + + list.getSelection().clear(); + list.getSelection().addAll(sel); + upBtn.setDisabled(list.getSelectedIndex() == 0); + downBtn.setDisabled(list.getSelectedIndex() == list.getItems().size - 1); + + Ctx.project.setModified(); + } + + private void down() { + if (parent == null || list.getSelection().size() == 0) + return; + + Array sel = new Array(); + + Array sortedSelection = getSortedSelection(); + + for (int i = sortedSelection.size - 1; i >= 0; i--) { + + int pos = list.getItems().indexOf(sortedSelection.get(i), true); + + Array items = list.getItems(); + + if (pos == -1 || pos == items.size - 1) + return; + + Action e = items.get(pos); + Action e2 = items.get(pos + 1); + + sel.add(e); + + if (isControlAction(e) && isControlAction(e2)) { + continue; + } + + parent.getActions().set(pos + 1, e); + parent.getActions().set(pos, e2); + + items.set(pos + 1, e); + items.set(pos, e2); + } + + list.getSelection().clear(); + list.getSelection().addAll(sel); + upBtn.setDisabled(list.getSelectedIndex() == 0); + downBtn.setDisabled(list.getSelectedIndex() == list.getItems().size - 1); + + Ctx.project.setModified(); + } + + // ------------------------------------------------------------------------- + // ListCellRenderer + // ------------------------------------------------------------------------- + private final CellRenderer listCellRenderer = new CellRenderer() { + + @Override + protected String getCellTitle(Action a) { + boolean enabled = true; + + if (a instanceof CommentAction) { + String comment = null; + + try { + comment = ActionUtils.getStringValue(a, "comment"); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + EditorLogger.error(e.getMessage()); + } + + if(comment == null) + comment = "COMMENT"; + else if(comment.indexOf('\n') != -1) { + comment = comment.substring(0, comment.indexOf('\n')); + } + + return "[YELLOW]" + comment + "[]"; + } + + if (a instanceof DisableActionAction) { + a = ((DisableActionAction) a).getAction(); + enabled = false; + } + + String id = ActionUtils.getName(a.getClass()); + + if (id == null) + id = a.getClass().getCanonicalName(); + + Field field = ActionUtils.getField(a.getClass(), "actor"); + String actor = null; + + if (field != null) { + try { + field.setAccessible(true); + Object v = field.get(a); + if (v != null) + actor = v.toString(); + } catch (IllegalArgumentException | IllegalAccessException e) { + EditorLogger.error(e.getMessage()); + } + } + + boolean animationAction = id.equals("Animation"); + boolean controlAction = isControlAction(a); + + if (!enabled && !controlAction) { + if (actor != null && !animationAction) { + SceneActorRef sa = new SceneActorRef(actor); + + if (sa.getSceneId() != null) + id = MessageFormat.format("[GRAY]{0} {1}.{2}[]", sa.getSceneId(), sa.getActorId(), id); + else + id = MessageFormat.format("[GRAY]{0}.{1}[]", sa.getActorId(), id); + } else if (animationAction) { + field = ActionUtils.getField(a.getClass(), "animation"); + String animation = null; + + if (field != null) { + try { + field.setAccessible(true); + animation = field.get(a).toString(); + } catch (IllegalArgumentException | IllegalAccessException e) { + EditorLogger.error(e.getMessage()); + } + } + + ActorAnimationRef aa = new ActorAnimationRef(animation); + + if (aa.getActorId() != null) + id = MessageFormat.format("[GRAY]{0}.{1} {2}[]", aa.getActorId(), id, aa.getAnimationId()); + else + id = MessageFormat.format("[GRAY]{0} {1}[]", id, aa.getAnimationId()); + } else { + id = MessageFormat.format("[GRAY]{0}[]", id); + } + + } else if (actor != null && !animationAction && !controlAction) { + SceneActorRef sa = new SceneActorRef(actor); + + if (sa.getSceneId() != null) + id = MessageFormat.format("[GREEN]{0}[] {1}.{2}", sa.getSceneId(), sa.getActorId(), id); + else + id = MessageFormat.format("{0}.{1}", sa.getActorId(), id); + } else if (animationAction) { + field = ActionUtils.getField(a.getClass(), "animation"); + String animation = null; + + if (field != null) { + try { + field.setAccessible(true); + animation = field.get(a).toString(); + } catch (IllegalArgumentException | IllegalAccessException e) { + EditorLogger.error(e.getMessage()); + } + } + + ActorAnimationRef aa = new ActorAnimationRef(animation); + + if (aa.getActorId() != null) + id = MessageFormat.format("[GREEN]{0}.{1} {2}[]", aa.getActorId(), id, aa.getAnimationId()); + else + id = MessageFormat.format("[GREEN]{0} {1}[]", id, aa.getAnimationId()); + } else if (controlAction) { + if (a instanceof EndAction) { + Action parentAction = findParentAction((EndAction) a); + + if (parentAction instanceof AbstractIfAction + && isElse((AbstractIfAction) parentAction, (EndAction) a)) { + id = "Else"; + } else { + id = "End" + ActionUtils.getName(parentAction.getClass()); + } + } + + if (actor != null) { + SceneActorRef sa = new SceneActorRef(actor); + + if (sa.getSceneId() != null) + id = MessageFormat.format("[GREEN]{0}[] [BLUE]{1}.{2}[]", sa.getSceneId(), sa.getActorId(), id); + else + id = MessageFormat.format("[BLUE]{0}.{1}[BLUE]", sa.getActorId(), id); + } else + id = MessageFormat.format("[BLUE]{0}[]", id); + } + + if(ActionUtils.isDeprecated(a.getClass())) + id = "[RED]D[] " + id; + + return id; + } + + private boolean isElse(AbstractIfAction parentAction, EndAction ea) { + final String caID = ea.getControlActionID(); + ArrayList actions = parent.getActions(); + + int idx = actions.indexOf(parentAction); + + for (int i = idx + 1; i < actions.size(); i++) { + Action aa = actions.get(i); + + if (isControlAction(aa) && ((AbstractControlAction) aa).getControlActionID().equals(caID)) { + if (aa == ea) + return true; + + return false; + } + } + + return false; + } + + private Action findParentAction(EndAction a) { + final String caID = a.getControlActionID(); + ArrayList actions = parent.getActions(); + + for (Action a2 : actions) { + if (isControlAction(a2) && ((AbstractControlAction) a2).getControlActionID().equals(caID)) { + return a2; + } + } + + return null; + } + + @Override + protected String getCellSubTitle(Action a) { + if (a instanceof CommentAction) + return ""; + + if (a instanceof DisableActionAction) + a = ((DisableActionAction) a).getAction(); + + StringBuilder sb = new StringBuilder(); + + String[] params = ActionUtils.getFieldNames(a); + String actionName = ActionUtils.getName(a.getClass()); + + for (String p : params) { + + if (p.equals("actor") + || (actionName != null && actionName.equals("Animation") && p.equals("animation"))) + continue; + + if(p.equals("caID")) + continue; + + Field f = ActionUtils.getField(a.getClass(), p); + + try { + final boolean accessible = f.isAccessible(); + f.setAccessible(true); + Object o = f.get(a); + if (o == null) + continue; + String v = o.toString(); + + // Check world Scope for translations + if (scope.equals(ScopePanel.WORLD_SCOPE)) + sb.append(p).append(": ") + .append(Ctx.project.getI18N().getWorldTranslation(v).replace("\n", "|")).append(' '); + else + sb.append(p).append(": ").append(Ctx.project.translate(v).replace("\n", "|")).append(' '); + + f.setAccessible(accessible); + } catch (IllegalArgumentException | IllegalAccessException e) { + EditorLogger.error(e.getMessage()); + } + } + + return sb.toString(); + } + + @Override + protected boolean hasSubtitle() { + return true; + } + }; +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ActorList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ActorList.java new file mode 100644 index 000000000..813b556dd --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ActorList.java @@ -0,0 +1,385 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.Event; +import com.badlogic.gdx.scenes.scene2d.EventListener; +import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextField; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.bladecoder.engine.assets.EngineAssetManager; +import com.bladecoder.engine.model.*; +import com.bladecoder.engine.spine.SpineRenderer; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.ElementUtils; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.CellRenderer; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.ModelList; +import com.bladecoder.engineeditor.undo.UndoDeleteActor; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +public class ActorList extends ModelList { + + private ImageButton playerBtn; + private ImageButton visibilityBtn; + private String filterText; + + public ActorList(Skin skin) { + super(skin, true); + + // Eye button + visibilityBtn = new ImageButton(skin); + toolbar.addToolBarButton(visibilityBtn, "ic_eye", "Toggle Visibility", "Toggle Visibility in editor"); + visibilityBtn.setDisabled(false); + visibilityBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + toggleVisibility(); + } + }); + + // Player button + playerBtn = new ImageButton(skin); + toolbar.addToolBarButton(playerBtn, "ic_player_small", "Set player", "Set player"); + playerBtn.setDisabled(true); + playerBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + setPlayer(); + } + }); + + TextField tf = toolbar.addFilterBox(new EventListener() { + + @Override + public boolean handle(Event e) { + if (((TextField) e.getTarget()).getText() != filterText) { + filterText = ((TextField) e.getTarget()).getText(); + + addFilteredElements(); + } + + return false; + } + + }); + + filterText = tf.getText(); + + list.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + // EditorLogger.debug("ACTOR LIST ELEMENT SELECTED"); + int pos = list.getSelectedIndex(); + + if (pos == -1) { + Ctx.project.setSelectedActor((BaseActor) null); + } else { + BaseActor a = list.getItems().get(pos); + Ctx.project.setSelectedActor(a); + } + + toolbar.disableEdit(pos == -1); + playerBtn.setDisabled(pos == -1); + } + }); + + list.setCellRenderer(listCellRenderer); + + Ctx.project.addPropertyChangeListener(Project.NOTIFY_ACTOR_SELECTED, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent e) { + int pos = list.getSelectedIndex(); + + // Element newActor = (Element) e.getNewValue(); + BaseActor newActor = Ctx.project.getSelectedActor(); + + if (newActor == null) + return; + + if (pos != -1) { + BaseActor oldActor = list.getItems().get(pos); + + if (oldActor == newActor) { + return; + } + } + + int i = list.getItems().indexOf(newActor, true); + + if (i >= 0) { + list.setSelectedIndex(i); + + container.getActor().setScrollPercentY(i / (float) list.getItems().size); + } + } + }); + + Ctx.project.addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + if (evt.getPropertyName().equals(Project.NOTIFY_ELEMENT_DELETED)) { + if (evt.getNewValue() instanceof BaseActor) { + addFilteredElements(); + } + } else if (evt.getPropertyName().equals(Project.NOTIFY_ELEMENT_CREATED)) { + if (evt.getNewValue() instanceof BaseActor && !(evt.getSource() instanceof EditActorDialog)) { + addFilteredElements(); + } + } + } + }); + } + + private void addFilteredElements() { + + List filtered = new ArrayList<>(); + + for (BaseActor a : Ctx.project.getSelectedScene().getActors().values()) { + if (filterText == null || filterText.isEmpty() || a.getId().contains(filterText)) { + filtered.add(a); + } + } + + addElements(Ctx.project.getSelectedScene(), filtered); + + } + + private void toggleVisibility() { + + BaseActor e = list.getSelected(); + + if (e == null) + return; + + Ctx.project.toggleEditorVisibility(e); + } + + @Override + protected void delete() { + BaseActor a = removeSelected(); + + parent.removeActor(a); + + // delete player attr if the actor to delete is the player + if (parent.getPlayer() == a) { + parent.setPlayer(null); + } + + if (a.getId().equals(parent.getWalkZone())) { + parent.setWalkZone(null); + } + + // TRANSLATIONS + Ctx.project.getI18N().putTranslationsInElement(a); + + // UNDO + Ctx.project.getUndoStack().add(new UndoDeleteActor(parent, a)); + + Ctx.project.setModified(); + } + + @Override + protected EditModelDialog getEditElementDialogInstance(BaseActor a) { + return new EditActorDialog(skin, parent, a); + } + + @Override + protected void edit() { + BaseActor e = list.getSelected(); + + if (e == null) + return; + + EditModelDialog dialog = getEditElementDialogInstance(e); + dialog.show(getStage()); + + dialog.setListener(new ChangeListener() { + @SuppressWarnings("unchecked") + @Override + public void changed(ChangeEvent event, Actor actor) { + BaseActor e = ((EditModelDialog) actor).getElement(); + + // When the type is changed, a new element is created and it is needed to + // replace the previous element. + if (e != list.getSelected()) { + int i = list.getSelectedIndex(); + getItems().set(i, e); + list.setSelectedIndex(i); + list.invalidateHierarchy(); + } + } + }); + } + + private void setPlayer() { + + int pos = list.getSelectedIndex(); + + if (pos == -1) + return; + + BaseActor a = list.getItems().get(pos); + + if (a instanceof CharacterActor) { + Ctx.project.getSelectedScene().setPlayer((CharacterActor) a); + Ctx.project.setModified(); + } + } + + @Override + protected void copy() { + BaseActor e = list.getSelected(); + + if (e == null) + return; + + clipboard = (BaseActor) ElementUtils.cloneElement(e); + toolbar.disablePaste(false); + + // TRANSLATIONS + Ctx.project.getI18N().putTranslationsInElement(clipboard); + } + + @Override + protected void paste() { + BaseActor newElement = (BaseActor) ElementUtils.cloneElement(clipboard); + + newElement.setId( + ElementUtils.getCheckedId(newElement.getId(), parent.getActors().keySet().toArray(new String[0]))); + + int pos = list.getSelectedIndex() + 1; + + list.getItems().insert(pos, newElement); + + parent.addActor(newElement); + Ctx.project.getI18N().extractStrings(parent.getId(), newElement); + + if (newElement instanceof SpriteActor) { + SpriteActor ia = (SpriteActor) newElement; + ia.loadAssets(); + EngineAssetManager.getInstance().finishLoading(); + ia.retrieveAssets(); + } + + list.setSelectedIndex(pos); + list.invalidateHierarchy(); + + Ctx.project.setModified(); + } + + // ------------------------------------------------------------------------- + // ListCellRenderer + // ------------------------------------------------------------------------- + private final CellRenderer listCellRenderer = new CellRenderer() { + + @Override + protected String getCellTitle(BaseActor e) { + boolean enabled = Ctx.project.isEditorVisible(e); + + String text = e.getId(); + + if (!enabled) { + text = MessageFormat.format("[GRAY]{0}[]", text); + } + + return text; + } + + @Override + protected String getCellSubTitle(BaseActor e) { + boolean enabled = Ctx.project.isEditorVisible(e); + + String text = ""; + + if (e instanceof SpriteActor && ((SpriteActor) e).getRenderer() instanceof TextRenderer + && ((TextRenderer) ((SpriteActor) e).getRenderer()).getText() != null) { + text = Ctx.project.translate(((TextRenderer) ((SpriteActor) e).getRenderer()).getText()).replace("\n", + "|"); + } + + if (e instanceof InteractiveActor) { + text = Ctx.project.translate(((InteractiveActor) e).getDesc()); + } + + if (!enabled && text != null && !text.isEmpty()) { + text = MessageFormat.format("[GRAY]{0}[]", text); + } + + return text; + } + + @Override + public TextureRegion getCellImage(BaseActor a) { + + boolean isPlayer = (a.getScene().getPlayer() == a); + String u = null; + + if (isPlayer) { + u = "ic_player"; + } else if (a instanceof CharacterActor) { + u = "ic_character_actor"; + } else if (a instanceof SpriteActor) { + ActorRenderer r = ((SpriteActor) a).getRenderer(); + + if (r instanceof ImageRenderer) { + u = "ic_sprite_actor"; + } else if (r instanceof AtlasRenderer) { + u = "ic_sprite_actor"; + } else if (r instanceof SpineRenderer) { + u = "ic_spine"; + } else if (r instanceof ParticleRenderer) { + u = "ic_particles"; + } else if (r instanceof TextRenderer) { + u = "ic_text"; + } + } else if (a instanceof InteractiveActor) { + u = "ic_base_actor"; + } else if (a instanceof ObstacleActor) { + u = "ic_obstacle_actor"; + } else if (a instanceof AnchorActor) { + u = "ic_anchor"; + } else if (a instanceof WalkZoneActor) { + u = "ic_walkzone"; + } else { + u = "ic_base_actor"; + } + + return Ctx.assetManager.getIcon(u); + } + + @Override + protected boolean hasSubtitle() { + return true; + } + + @Override + protected boolean hasImage() { + return true; + } + }; +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ActorPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ActorPanel.java new file mode 100644 index 000000000..4aa4c1d01 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ActorPanel.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Arrays; +import java.util.HashMap; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.bladecoder.engine.anim.AnimationDesc; +import com.bladecoder.engine.model.AnimationRenderer; +import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.CharacterActor; +import com.bladecoder.engine.model.Dialog; +import com.bladecoder.engine.model.SpriteActor; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.HeaderPanel; +import com.bladecoder.engineeditor.ui.panels.TabPanel; + +public class ActorPanel extends HeaderPanel { + + private TabPanel tabPanel; + private VerbList verbList; + private DialogList dialogList; + private SpriteList faList; + + public ActorPanel(Skin skin) { + super(skin, "ACTOR"); + tabPanel = new TabPanel(skin); + verbList = new VerbList(skin); + dialogList = new DialogList(skin); + faList = new SpriteList(skin); +// props = new ActorProps(skin); + + setContent(tabPanel); + tabPanel.addTab("Verbs", verbList); + + Ctx.project.addPropertyChangeListener(Project.NOTIFY_ACTOR_SELECTED, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent e) { + BaseActor a = (BaseActor) e.getNewValue(); + + String selTitle = tabPanel.getSelectedIndex() == -1 ? null + : tabPanel.getTitleAt(tabPanel.getSelectedIndex()); + tabPanel.clear(); + + tabPanel.addTab("Verbs", verbList); + + if (a != null) { + + if (a instanceof SpriteActor && ((SpriteActor) a).getRenderer() instanceof AnimationRenderer) + tabPanel.addTab("Animations", faList); + + if (a instanceof CharacterActor) { + tabPanel.addTab("Simple Dialogs", dialogList); + } + +// tabPanel.addTab("Actor Props", props); + setTile("ACTOR " + a.getId()); + + // select previous selected tab + if (selTitle != null) { + for (int i = 0; i < tabPanel.getTabCount(); i++) { + if (tabPanel.getTitleAt(i).equals(selTitle)) { + tabPanel.setTab(i); + } + } + } + } else { + setTile("ACTOR"); + } + + if (a instanceof SpriteActor && ((SpriteActor) a).getRenderer() instanceof AnimationRenderer) { + HashMap anims = ((AnimationRenderer) ((SpriteActor) a).getRenderer()) + .getAnimations(); + if (anims != null) + faList.addElements((SpriteActor) a, + Arrays.asList(anims.values().toArray(new AnimationDesc[0]))); + else + faList.addElements((SpriteActor) a, null); + } else { + faList.addElements(null, null); + } + + verbList.changeActor(); + + if (a instanceof CharacterActor) { + + HashMap dialogs = ((CharacterActor) a).getDialogs(); + if (dialogs != null) + dialogList.addElements((CharacterActor) a, + Arrays.asList(dialogs.values().toArray(new Dialog[0]))); + else + dialogList.addElements((CharacterActor) a, null); + } else { + dialogList.addElements(null, null); + } + +// props.setActorDocument(a); + + } + + }); + + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ActorProps.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ActorProps.java new file mode 100644 index 000000000..9c3bb5cdf --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ActorProps.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.InteractiveActor; +import com.bladecoder.engine.model.SpriteActor; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.PropertyTable; + +public class ActorProps extends PropertyTable { + + public static final String DESC_PROP = "Description"; + public static final String POS_X_PROP = "pos X"; + public static final String POS_Y_PROP = "pos Y"; + public static final String VISIBLE_PROP = "visible"; + public static final String INTERACTION_PROP = "interaction"; + public static final String STATE_PROP = "state"; + public static final String BBOX_FROM_RENDERER_PROP = "Set BBOX from renderer"; + + private BaseActor actor; + + // TableModelListener tableModelListener = new TableModelListener() { + // @Override + // public void tableChanged(TableModelEvent e) { + // if (e.getType() == TableModelEvent.UPDATE) { + // int row = e.getFirstRow(); + // updateModel((String) propertyTable.getModel().getValueAt(row, 0), + // (String) propertyTable.getModel().getValueAt(row, 1)); + // } + // } + // }; + + PropertyChangeListener propertyChangeListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + EditorLogger.debug("Actor Props Listener: " + evt.getPropertyName()); + + updateField(evt.getPropertyName()); + } + }; + + public ActorProps(Skin skin) { + super(skin); + } + + private void updateField(String modelProperty) { + + if (actor == null) + return; + + if (modelProperty.equals("desc")) { + setProperty(DESC_PROP, ((InteractiveActor) actor).getDesc()); + } else if (modelProperty.equals(Project.POSITION_PROPERTY)) { + setProperty(POS_X_PROP, Float.toString(actor.getX())); + setProperty(POS_Y_PROP, Float.toString(actor.getY())); + } else if (modelProperty.equals("visible")) { + setProperty(VISIBLE_PROP, Boolean.toString(actor.isVisible())); + } else if (modelProperty.equals("interaction")) { + setProperty(INTERACTION_PROP, Boolean.toString(((InteractiveActor) actor).getInteraction())); + } else if (modelProperty.equals("state")) { + setProperty(STATE_PROP, ((InteractiveActor) actor).getState()); + } else if (modelProperty.equals("bbox")) { + + // TODO Conflict with scnwidget + +// boolean v = value.isEmpty(); + +// setProperty(BBOX_FROM_RENDERER_PROP, Boolean.toString(v)); + } + } + + public void setActorDocument(BaseActor a) { + this.actor = a; + clearProps(); + + if (a != null) { + addProperty(POS_X_PROP, Float.toString(actor.getX()), Types.FLOAT); + addProperty(POS_Y_PROP, Float.toString(actor.getY()), Types.FLOAT); + addProperty(VISIBLE_PROP, Boolean.toString(actor.isVisible()), Types.BOOLEAN); + + if (a instanceof InteractiveActor) { + addProperty(DESC_PROP, ((InteractiveActor) actor).getDesc()); + + addProperty(INTERACTION_PROP, Boolean.toString(((InteractiveActor) actor).getInteraction()), + Types.BOOLEAN); + addProperty(STATE_PROP, ((InteractiveActor) actor).getState()); + } + + if (a instanceof SpriteActor) { + boolean v = ((SpriteActor) a).isBboxFromRenderer(); + + addProperty(BBOX_FROM_RENDERER_PROP, Boolean.toString(v), Types.BOOLEAN); + } + + Ctx.project.addPropertyChangeListener(propertyChangeListener); + + invalidateHierarchy(); + } + } + + @Override + protected void updateModel(String property, String value) { + if (property.equals(DESC_PROP)) { + ((InteractiveActor) actor).setDesc(value); + } else if (property.equals(POS_X_PROP)) { + + // TODO UNDO +// UndoOp undoOp = new UndoSetAttr(Ctx.project.getSelectedChapter(), Ctx.project.getSelectedActor(), XMLConstants.POS_ATTR, +// Param.toStringParam(pos)); +// Ctx.project.getUndoStack().add(undoOp); + + try { + actor.setPosition(Float.parseFloat(value), actor.getY()); + } catch (NumberFormatException e) { + + } + } else if (property.equals(POS_Y_PROP)) { +// UndoOp undoOp = new UndoSetAttr(Ctx.project.getSelectedChapter(), Ctx.project.getSelectedActor(),XMLConstants.POS_ATTR, +// Param.toStringParam(pos)); +// Ctx.project.getUndoStack().add(undoOp); + try { + actor.setPosition(actor.getX(), Float.parseFloat(value)); + } catch (NumberFormatException e) { + + } + + } else if (property.equals(VISIBLE_PROP)) { + actor.setVisible(Boolean.parseBoolean(value)); + } else if (property.equals(INTERACTION_PROP)) { + ((InteractiveActor) actor).setInteraction(Boolean.parseBoolean(value)); + } else if (property.equals(STATE_PROP)) { + ((InteractiveActor) actor).setState(value); + } else if (property.equals(BBOX_FROM_RENDERER_PROP)) { + boolean v = true; + v = Boolean.parseBoolean(value); + + ((SpriteActor) actor).setBboxFromRenderer(v); + } + + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/AssetPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/AssetPanel.java similarity index 92% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/AssetPanel.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/AssetPanel.java index f2015916a..f3a705440 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/AssetPanel.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/AssetPanel.java @@ -21,8 +21,8 @@ import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.bladecoder.engineeditor.Ctx; import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.ui.components.HeaderPanel; -import com.bladecoder.engineeditor.ui.components.TabPanel; +import com.bladecoder.engineeditor.ui.panels.HeaderPanel; +import com.bladecoder.engineeditor.ui.panels.TabPanel; public class AssetPanel extends HeaderPanel { private TabPanel tabPanel; diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/AssetsList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/AssetsList.java new file mode 100644 index 000000000..5115bbac7 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/AssetsList.java @@ -0,0 +1,376 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Container; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.utils.Array; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.ImageUtils; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.common.RunProccess; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.CustomList; +import com.bladecoder.engineeditor.ui.panels.EditToolbar; +import com.kotcrab.vis.ui.widget.file.FileChooser; +import com.kotcrab.vis.ui.widget.file.FileChooser.Mode; +import com.kotcrab.vis.ui.widget.file.FileChooser.SelectionMode; +import com.kotcrab.vis.ui.widget.file.FileChooser.ViewMode; +import com.kotcrab.vis.ui.widget.file.FileChooserListener; +import com.kotcrab.vis.ui.widget.file.FileTypeFilter; + +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class AssetsList extends Table { + private static final String[] ASSET_TYPES = {"atlases", "music", "sounds", "images", "spine", "particles", "voices"}; + + private SelectBox assetTypes; + protected EditToolbar toolbar; + protected CustomList list; + protected Skin skin; + protected Container container; + + private File lastDir; + + public AssetsList(Skin skin) { + super(skin); + + assetTypes = new SelectBox<>(skin); + assetTypes.setItems(ASSET_TYPES); + + this.skin = skin; + + list = new CustomList<>(skin); + + Array items = new Array(); + list.setItems(items); + + ScrollPane scrollPane = new ScrollPane(list, skin); + container = new Container<>(scrollPane); + container.fill(); + container.prefHeight(1000); + + toolbar = new EditToolbar(skin); + // debug(); + add(assetTypes).expandX().fillX(); + row(); + add(toolbar).expandX().fillX(); + row(); + add(container).expand().fill(); + + toolbar.addCreateListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + create(); + } + }); + + toolbar.addEditListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + edit(); + } + }); + + toolbar.addDeleteListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + delete(); + } + }); + + list.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + toolbar.disableEdit(false); + } + }); + + Ctx.project.addPropertyChangeListener(Project.NOTIFY_PROJECT_LOADED, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent arg0) { + toolbar.disableCreate(!Ctx.project.isLoaded()); + addAssets(); + } + }); + + assetTypes.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + addAssets(); + } + }); + } + + private void addAssets() { + list.getItems().clear(); + + if (Ctx.project.isLoaded()) { + String type = assetTypes.getSelected(); + String dir = getAssetDir(type); + + if (type.equals("images") || type.equals("atlases")) + dir += "/1"; + + String[] files = new File(dir).list(new FilenameFilter() { + @Override + public boolean accept(File arg0, String arg1) { + String type = assetTypes.getSelected(); + + return !type.equals("atlases") || arg1.endsWith(".atlas"); + } + }); + + if (files != null) { + Arrays.sort(files); + + for (String f : files) + list.getItems().add(f); + } + + if (list.getItems().size > 0) { + list.setSelectedIndex(0); + } + } + + toolbar.disableCreate(!Ctx.project.isLoaded()); + list.invalidateHierarchy(); + } + + private String getAssetDir(String type) { + String dir; + + if (type.equals("atlases")) { + dir = Ctx.project.getAssetPath() + Project.ATLASES_PATH; + } else if (type.equals("music")) { + dir = Ctx.project.getAssetPath() + Project.MUSIC_PATH; + } else if (type.equals("sounds")) { + dir = Ctx.project.getAssetPath() + Project.SOUND_PATH; + } else if (type.equals("images")) { + dir = Ctx.project.getAssetPath() + Project.IMAGE_PATH; + dir = Ctx.project.getAssetPath() + Project.IMAGE_PATH; + } else if (type.equals("spine")) { + dir = Ctx.project.getAssetPath() + Project.SPINE_PATH; + } else if (type.equals("particles")) { + dir = Ctx.project.getAssetPath() + Project.PARTICLE_PATH; + } else if (type.equals("voices")) { + dir = Ctx.project.getAssetPath() + Project.VOICE_PATH; + } else { + dir = Ctx.project.getAssetPath(); + } + + return dir; + } + + private void create() { + final String type = assetTypes.getSelected(); + + if (type.equals("atlases")) { + new CreateAtlasDialog(skin).show(getStage()); + +// addAssets(); + + } else if (type.equals("particles")) { + // Open the particle editor + List cp = new ArrayList(); + cp.add(System.getProperty("java.class.path")); + try { + RunProccess.runJavaProccess("com.badlogic.gdx.tools.particleeditor.ParticleEditor", cp, null); + } catch (IOException e) { + Message.showMsgDialog(getStage(), "Error", "Error launching Particle Editor."); + EditorLogger.printStackTrace(e); + } + } else { + + FileChooser fileChooser = new FileChooser(Mode.OPEN); + + fileChooser.setSelectionMode(SelectionMode.FILES); + fileChooser.setMultiSelectionEnabled(true); + + fileChooser.setSize(Gdx.graphics.getWidth() * 0.7f, Gdx.graphics.getHeight() * 0.7f); + fileChooser.setViewMode(ViewMode.LIST); + + getStage().addActor(fileChooser); + if (lastDir != null) + fileChooser.setDirectory(lastDir); +// chooser.setTitle("Select the '" + type + "' asset files"); + + + FileTypeFilter typeFilter = new FileTypeFilter(true); //allow "All Types" mode where all files are shown + + switch (type) { + case "images": + typeFilter.addRule("Images (*.png, *.jpg, *.etc1)", "jpg", "png", "etc1"); + break; + case "music": + case "sounds": + case "voices": + typeFilter.addRule("Sound (*.mp3, *.wav, *.ogg)", "wav", "mp3", "ogg"); + break; + case "spine": + typeFilter.addRule("Spine (*.skel, *.json)", "skel", "json"); + break; + default: + typeFilter.addRule("All", ""); + break; + } + + fileChooser.setFileTypeFilter(typeFilter); + + fileChooser.setListener(new FileChooserListener() { + + @Override + public void selected(Array files) { + + try { + String dirName = getAssetDir(type); + lastDir = files.get(0).parent().file(); + + // Si no existe la carpeta la creamos + File dir = new File(dirName); + if (!dir.exists()) + dir.mkdir(); + + for (FileHandle f : files) { + if (type.equals("images")) { + List res = Ctx.project.getResolutions(); + + for (String r : res) { + File destFile = new File(dirName + "/" + r + "/" + f.file().getName()); + float scale = Float.parseFloat(r); + + if (scale != 1.0f) { + + ImageUtils.scaleImageFile(f.file(), destFile, scale); + } else { + Files.copy(f.file().toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + } + } else { + File destFile = new File(dir, f.file().getName()); + Files.copy(f.file().toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + + } + + addAssets(); + } catch (Exception ex) { + String msg = "Something went wrong while getting the assets.\n\n" + + ex.getClass().getSimpleName() + " - " + ex.getMessage(); + Message.showMsgDialog(getStage(), "Error", msg); + EditorLogger.printStackTrace(ex); + } + } + + @Override + public void canceled() { + + } + }); + } + } + + private void edit() { + if (Desktop.isDesktopSupported()) { + String type = assetTypes.getSelected(); + String dir = getAssetDir(type); + + if (type.equals("images") || type.equals("atlases")) + dir += "/1"; + + try { + Desktop.getDesktop().open(new File(dir)); + } catch (IOException e1) { + String msg = "Something went wrong while opening assets folder.\n\n" + e1.getClass().getSimpleName() + + " - " + e1.getMessage(); + Message.showMsgDialog(getStage(), "Error", msg); + } + } + } + + private void delete() { + String type = assetTypes.getSelected(); + String dir = getAssetDir(type); + + String name = list.getSelected(); + try { + if (type.equals("images") || type.equals("atlases")) { + List res = Ctx.project.getResolutions(); + + for (String r : res) { + File file = new File(dir + "/" + r + "/" + name); + + file.delete(); + + // delete pages on atlases + if (type.equals("atlases")) { + File atlasDir = new File(dir + "/" + r); + + File[] files = atlasDir.listFiles(); + + if (files != null) + for (File f : files) { + String destName = f.getName(); + String nameWithoutExt = name.substring(0, name.lastIndexOf('.')); + String destNameWithoutExt = destName.substring(0, destName.lastIndexOf('.')); + + if (destNameWithoutExt.length() < nameWithoutExt.length()) + continue; + + String suffix = destNameWithoutExt.substring(nameWithoutExt.length()); + + if (!suffix.isEmpty() && !suffix.matches("[0-9]+")) + continue; + + if (destName.startsWith(nameWithoutExt) && destName.toLowerCase().endsWith(".png")) + Files.delete(f.toPath()); + } + } + } + } else { + File file = new File(dir + "/" + name); + file.delete(); + } + + addAssets(); + } catch (Exception ex) { + String msg = "Something went wrong while deleting the asset.\n\n" + ex.getClass().getSimpleName() + " - " + + ex.getMessage(); + Message.showMsgDialog(getStage(), "Error", msg); + EditorLogger.printStackTrace(ex); + } + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ChapterList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ChapterList.java similarity index 66% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ChapterList.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ChapterList.java index 8c1835618..41f60f20c 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ChapterList.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ChapterList.java @@ -22,14 +22,14 @@ import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.WorldDocument; -import com.bladecoder.engineeditor.ui.components.CellRenderer; -import com.bladecoder.engineeditor.ui.components.EditList; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.CellRenderer; +import com.bladecoder.engineeditor.ui.panels.EditList; public class ChapterList extends EditList { - WorldDocument doc; - private ImageButton initBtn; public ChapterList(Skin skin) { @@ -38,8 +38,7 @@ public ChapterList(Skin skin) { list.setCellRenderer(listCellRenderer); initBtn = new ImageButton(skin); - toolbar.addToolBarButton(initBtn, "ic_check", "Set init chapter", - "Set init chapter"); + toolbar.addToolBarButton(initBtn, "ic_check", "Set init chapter", "Set init chapter"); initBtn.setDisabled(false); toolbar.hideCopyPaste(); @@ -54,14 +53,13 @@ public void changed(ChangeEvent event, Actor actor) { } private void setDefault() { - WorldDocument w = (WorldDocument) doc; - String e = list.getSelected(); if (e == null) return; - w.setRootAttr(doc.getElement(), "init_chapter", e); + Ctx.project.getWorld().setInitChapter(e); + Ctx.project.setModified(); } @Override @@ -74,32 +72,35 @@ protected void delete() { if (list.getItems().size < 2) { String msg = "The chapter will not be deleted, at least one chapter must exists"; - Ctx.msg.show(getStage(), msg, 3); + Message.showMsg(getStage(), msg, 4); return; } String e = list.getItems().removeIndex(pos); - if (e.equals(Ctx.project.getWorld().getInitChapter())) { + if (e.equals(Ctx.project.getChapter().getInitChapter())) { Ctx.project.getWorld().setInitChapter(list.getItems().get(0)); + Ctx.project.setModified(); } try { - ((WorldDocument) doc).removeChapter(e); - Ctx.project.saveProject(); + Ctx.project.getChapter().deleteChapter(e); } catch (Exception ex) { - String msg = "Something went wrong while deleting the chapter.\n\n" - + ex.getClass().getSimpleName() + " - " + ex.getMessage(); - Ctx.msg.show(getStage(), msg, 3); + String msg = "Something went wrong.\n\n" + ex.getClass().getSimpleName() + " - " + ex.getMessage(); + Message.showMsgDialog(getStage(), "Error deleting chapter", msg); - ex.printStackTrace(); + EditorLogger.printStackTrace(ex); } + + list.setSelectedIndex(0); + + Ctx.project.notifyPropertyChange(Project.CHAPTER_PROPERTY); } @Override protected void create() { - EditChapterDialog dialog = new EditChapterDialog(skin, doc, null); + EditChapterDialog dialog = new EditChapterDialog(skin, Ctx.project.getChapter(), null); dialog.show(getStage()); dialog.setListener(new ChangeListener() { @Override @@ -111,6 +112,8 @@ public void changed(ChangeEvent event, Actor actor) { list.setSelectedIndex(i); list.invalidateHierarchy(); + + Ctx.project.notifyPropertyChange(Project.CHAPTER_PROPERTY); } }); } @@ -123,7 +126,7 @@ protected void edit() { if (e == null) return; - EditChapterDialog dialog = new EditChapterDialog(skin, doc, e); + EditChapterDialog dialog = new EditChapterDialog(skin, Ctx.project.getChapter(), e); dialog.show(getStage()); dialog.setListener(new ChangeListener() { @Override @@ -132,6 +135,7 @@ public void changed(ChangeEvent event, Actor actor) { list.getItems().removeIndex(list.getSelectedIndex()); list.getItems().add(e); list.setSelectedIndex(list.getItems().indexOf(e, true)); + Ctx.project.notifyPropertyChange(Project.CHAPTER_PROPERTY); } }); } @@ -143,32 +147,36 @@ protected void copy() { @Override protected void paste() { } - - public void addElements(WorldDocument w) { - this.doc = w; + public void addElements() { list.getItems().clear(); list.getSelection().clear(); - toolbar.disableCreate(false); - String nl[] = w.getChapters(); + if (Ctx.project.isLoaded()) { + toolbar.disableCreate(false); - for (int i = 0; i < nl.length; i++) { - addItem(nl[i]); - } + String nl[] = Ctx.project.getChapter().getChapters(); - if (getItems().size > 0) - list.setSelectedIndex(0); + for (int i = 0; i < nl.length; i++) { + addItem(nl[i]); + } - toolbar.disableEdit(list.getSelectedIndex() < 0); + if (getItems().size > 0) + list.setSelectedIndex(0); - list.getItems().sort(new Comparator() { - @Override - public int compare(String o1, String o2) { - return o1.compareTo(o2); - } - }); + toolbar.disableEdit(list.getSelectedIndex() < 0); + + list.getItems().sort(new Comparator() { + @Override + public int compare(String o1, String o2) { + return o1.compareTo(o2); + } + }); + + } else { + toolbar.disableCreate(true); + } invalidateHierarchy(); } @@ -182,7 +190,7 @@ public int compare(String o1, String o2) { protected String getCellTitle(String e) { String id = e; - String init = ((WorldDocument) doc).getInitChapter(); + String init = Ctx.project.getWorld().getInitChapter(); if (init.equals(id)) id += " "; diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CompileInkDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CompileInkDialog.java new file mode 100644 index 000000000..11051e352 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CompileInkDialog.java @@ -0,0 +1,248 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.ui.Cell; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.SharedLibraryLoader; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.HttpUtils; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.common.ModelTools; +import com.bladecoder.engineeditor.common.RunProccess; +import com.bladecoder.engineeditor.common.ZipUtils; +import com.bladecoder.engineeditor.ui.panels.EditDialog; +import com.bladecoder.engineeditor.ui.panels.FileInputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; +import com.kotcrab.vis.ui.widget.file.FileChooser; +import com.kotcrab.vis.ui.widget.file.FileChooserListener; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +public class CompileInkDialog extends EditDialog { + + private static final String FILE_PROP = "compileink.file"; + private static final String INKLECATE_PROP = "compileink.inklecate"; + private static final String LANG_PROP = "compileink.lang"; + private static final String EXTRACT_TEXTS_PROP = "compileink.extractTexts"; + + private static final String INFO = "Compile the ink script using Inklecate.\n Inklecate must be installed in your computer."; + + private InputPanel inklecatePath; + private InputPanel file; + private InputPanel extractTexts; + private InputPanel lang; + + public CompileInkDialog(Skin skin) { + super("COMPILE INK SCRIPT", skin); + + inklecatePath = new FileInputPanel(skin, "Select the inklecate folder", + "Select the folder where the inklecate is installed", FileInputPanel.DialogType.DIRECTORY); + + file = new FileInputPanel(skin, "Select the Ink script", "Select the Ink source script for your chapter", + FileInputPanel.DialogType.OPEN_FILE); + + extractTexts = InputPanelFactory.createInputPanel(skin, "Extract texts", + "Extracts all texts in a .properties for I18N.", Param.Type.BOOLEAN, true, "true"); + + lang = InputPanelFactory.createInputPanel(skin, "Lang code", + "The languaje code (ex. 'fr') where the texts are extracted. Empty for default.", false); + + addInputPanel(inklecatePath); + addInputPanel(file); + addInputPanel(extractTexts); + addInputPanel(lang); + + setInfo(INFO); + + if (Ctx.project.getEditorConfig().getProperty(FILE_PROP) != null) + file.setText(Ctx.project.getEditorConfig().getProperty(FILE_PROP)); + + if (Ctx.project.getEditorConfig().getProperty(INKLECATE_PROP) != null) + inklecatePath.setText(Ctx.project.getEditorConfig().getProperty(INKLECATE_PROP)); + + lang.setText(Ctx.project.getEditorConfig().getProperty(LANG_PROP)); + + if (Ctx.project.getEditorConfig().getProperty(EXTRACT_TEXTS_PROP) != null) + extractTexts.setText(Ctx.project.getEditorConfig().getProperty(EXTRACT_TEXTS_PROP)); + + // Add the 'download' button to the Path field. + TextButton downloadButton = new TextButton("Download Inklecate", skin, "no-toggled"); + + downloadButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + + if (SharedLibraryLoader.isWindows) { + download( + "https://github.com/inkle/ink/releases/download/v1.1.1/inklecate_windows.zip", + "inklecate.zip"); + } else if (SharedLibraryLoader.isLinux) { + download("https://github.com/inkle/ink/releases/download/v1.1.1/inklecate_linux.zip", + "inklecate.zip"); + } else if (SharedLibraryLoader.isMac) { + download("https://github.com/inkle/ink/releases/download/v1.1.1/inklecate_mac.zip", + "inklecate.zip"); + } + } + }); + + Table t2 = new Table(); + Actor a2 = inklecatePath.getField(); + Cell c2 = inklecatePath.getCell(a2); + t2.add(a2); + t2.add(downloadButton); + c2.setActor(t2); + } + + @Override + protected void ok() { + compileInk(); + + Ctx.project.getEditorConfig().setProperty(FILE_PROP, file.getText()); + Ctx.project.getEditorConfig().setProperty(INKLECATE_PROP, inklecatePath.getText()); + + if (lang.getText() != null) + Ctx.project.getEditorConfig().setProperty(LANG_PROP, lang.getText()); + + Ctx.project.getEditorConfig().setProperty(EXTRACT_TEXTS_PROP, extractTexts.getText()); + } + + @Override + protected boolean validateFields() { + boolean ok = true; + + if (!inklecatePath.validateField()) + ok = false; + + if (!file.validateField()) + ok = false; + + return ok; + } + + private void compileInk() { + String outfile = Ctx.project.getModelPath() + "/" + new File(file.getText()).getName() + ".json"; + List params = new ArrayList<>(); + params.add("-o"); + params.add(outfile); + params.add(file.getText()); + boolean ok = RunProccess.runInklecate(new File(inklecatePath.getText()), params); + + if (!ok) { + Message.showMsgDialog(getStage(), "Error", "Error compiling Ink script."); + return; + } + + if (extractTexts.getText().equals("true")) { + try { + ModelTools.extractInkTexts(outfile, lang.getText()); + } catch (IOException e) { + Message.showMsgDialog(getStage(), "Error extracting Ink texts.", e.getMessage()); + return; + } + } + + Message.showMsg(getStage(), "Ink script compiled successfully", 2); + } + + private void download(String url, String fileName) { + FileChooser fileChooser = new FileChooser(FileChooser.Mode.OPEN); + fileChooser.setSize(Gdx.graphics.getWidth() * 0.7f, Gdx.graphics.getHeight() * 0.7f); + fileChooser.setViewMode(FileChooser.ViewMode.LIST); + + fileChooser.setSelectionMode(FileChooser.SelectionMode.DIRECTORIES); + getStage().addActor(fileChooser); + + fileChooser.setListener(new FileChooserListener() { + + @Override + public void selected(Array files) { + try { + File zipFile = new File(files.get(0).file(), fileName); + HttpUtils.downloadAsync(new URL(url), new FileOutputStream(zipFile), new HttpUtils.Callback() { + @Override + public void updated(int length, int totalLength) { + final int progress = ((int) (((double) length / (double) totalLength) * 100)); + Message.showMsg(getStage(), "Downloading JDK... " + progress + "%", true); + } + + @Override + public void completed() { + File outputFolder = new File(files.get(0).file(), "inklecate"); + try { + // create output folder + outputFolder.mkdirs(); + + ZipUtils.unzip(zipFile, outputFolder.toPath()); + zipFile.delete(); + // add execution permission to the inklecate file + if (SharedLibraryLoader.isLinux || SharedLibraryLoader.isMac) { + File inklecateFile = new File(outputFolder, "inklecate"); + inklecateFile.setExecutable(true); + } + } catch (IOException e) { + Message.showMsg(getStage(), "Error uncompressing .zip: " + e.getMessage(), true); + return; + } + Gdx.app.postRunnable(new Runnable() { + @Override + public void run() { + Message.hideMsg(); + inklecatePath.setText(outputFolder.getAbsolutePath()); + } + }); + } + + @Override + public void canceled() { + Message.showMsgDialog(getStage(), "Error", "Download cancelled."); + } + + @Override + public void error(IOException ex) { + Message.showMsgDialog(getStage(), "Error", "Download error: " + ex.getMessage()); + } + }); + } catch (FileNotFoundException | MalformedURLException e) { + Message.showMsgDialog(getStage(), "Error", "Download error: " + e.getMessage()); + } + } + + @Override + public void canceled() { + + } + }); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CreateAndroidKeystoreDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CreateAndroidKeystoreDialog.java new file mode 100644 index 000000000..fdc65c226 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CreateAndroidKeystoreDialog.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.util.Arrays; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.ChangeEvent; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.common.RunProccess; +import com.bladecoder.engineeditor.ui.panels.EditDialog; +import com.bladecoder.engineeditor.ui.panels.FileInputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; + +public class CreateAndroidKeystoreDialog extends EditDialog { + + private static final String INFO = "Create the keystore needed to sign Android packages."; + + private InputPanel keyStoreFile; + private InputPanel androidKeyAlias; + private InputPanel androidKeyStorePassword; + private InputPanel androidKeyAliasPassword; + + protected ChangeListener listener; + + public CreateAndroidKeystoreDialog(Skin skin) { + super("CREATE KEY STORE FOR ANDROID", skin); + + keyStoreFile = new FileInputPanel(skin, "Select the key store", "Select the key store file name and location", + FileInputPanel.DialogType.SAVE_FILE); + + androidKeyAlias = InputPanelFactory.createInputPanel(skin, "KeyAlias", "Select the Key ID/Alias", true); + + androidKeyStorePassword = InputPanelFactory.createInputPanel(skin, "KeyStorePasswd", "Key Store Password", + true); + androidKeyAliasPassword = InputPanelFactory.createInputPanel(skin, "KeyAliasPasswd", "Key Alias Password", + true); + + addInputPanel(keyStoreFile); + addInputPanel(androidKeyAlias); + addInputPanel(androidKeyStorePassword); + addInputPanel(androidKeyAliasPassword); + + setInfo(INFO); + } + + @Override + protected void ok() { + createKeyStore(); + } + + @Override + protected boolean validateFields() { + boolean ok = true; + + if (!keyStoreFile.validateField()) + ok = false; + + if (!androidKeyAlias.validateField()) + ok = false; + + if (androidKeyStorePassword.getText() == null || androidKeyStorePassword.getText().length() < 6) { + Message.showMsgDialog(getStage(), "Error", "Keystore password must be at least 6 character long"); + ok = false; + + return false; + } + + if (androidKeyAliasPassword.getText() == null || androidKeyAliasPassword.getText().length() < 6) { + Message.showMsgDialog(getStage(), "Error", "Key password must be at least 6 character long"); + ok = false; + } + + return ok; + } + + private void createKeyStore() { + // keytool -genkey -v -keystore my-release-key.keystore -alias alias_name + // -keyalg RSA -keysize 2048 -validity 10000 + + String[] args = { "-genkey", "-noprompt", "-v", "-keystore", getKeyStorePath(), "-alias", getKeyAlias(), + "-keyalg", "RSA", "-keysize", "2048", "-validity", "10000", "-storepass", getKeyStorePassword(), + "-dname", "CN=bladeengine.com", "-keypass", getKeyAliasPassword() }; + + try { + Process p = RunProccess.runJavaHomeBin("keytool", Arrays.asList(args)); + p.waitFor(); + + if (p.exitValue() == 0) { + if (listener != null) + listener.changed(new ChangeEvent(), this); + } else { + Message.showMsgDialog(getStage(), "Error", "Error generating key"); + cancel(); + } + } catch (Exception e) { + Message.showMsgDialog(getStage(), "Error", e.getMessage()); + cancel(); + } + + } + + public String getKeyStorePath() { + return keyStoreFile.getText(); + } + + public String getKeyAlias() { + return androidKeyAlias.getText(); + } + + public String getKeyStorePassword() { + return androidKeyStorePassword.getText(); + } + + public String getKeyAliasPassword() { + return androidKeyAliasPassword.getText(); + } + + public void setListener(ChangeListener l) { + listener = l; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CreateAtlasDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CreateAtlasDialog.java new file mode 100644 index 000000000..d314bd325 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CreateAtlasDialog.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.io.IOException; +import java.util.List; + +import com.badlogic.gdx.graphics.Texture.TextureFilter; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.utils.Timer; +import com.badlogic.gdx.utils.Timer.Task; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.ImageUtils; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.EditDialog; +import com.bladecoder.engineeditor.ui.panels.FileInputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; + +public class CreateAtlasDialog extends EditDialog { + + private static final String INFO = "Package all the images in the selected dir to a new atlas"; + + private static final String[] FILTERS = { "Linear", "Nearest", "MipMap", "MipMapLinearLinear", + "MipMapLinearNearest", "MipMapNearestLinear", "MipMapNearestNearest" }; + + private static final String[] OUTPUT_FORMATS = { "png", "jpg" }; + + private InputPanel name; + private InputPanel dir; + private InputPanel filterMin; + private InputPanel filterMag; + private InputPanel maxWidth; + private InputPanel maxHeight; + private InputPanel outputFormat; + + public CreateAtlasDialog(Skin skin) { + super("CREATE ATLAS", skin); + + name = InputPanelFactory.createInputPanel(skin, "Atlas Name", "The name of the sprite atlas", true); + dir = new FileInputPanel(skin, "Input Image Directory", + "Select the output directory with the images to create the Atlas", FileInputPanel.DialogType.DIRECTORY); + + filterMin = InputPanelFactory.createInputPanel(skin, "Min Filter", "The filter when the texture is scaled down", + FILTERS, true); + filterMag = InputPanelFactory.createInputPanel(skin, "Mag Filter", "The filter when the texture is scaled up", + FILTERS, true); + maxWidth = InputPanelFactory.createInputPanel(skin, "Max Width", + "The atlas max page width. Be careful, some devices has a 4096px limit.", Param.Type.INTEGER, true); + maxHeight = InputPanelFactory.createInputPanel(skin, "Max Height", + "The atlas max page height. Be careful, some devices has a 4096px limit.", Param.Type.INTEGER, true); + + outputFormat = InputPanelFactory.createInputPanel(skin, "Output format", + "The output format of the image. Note that 'jpg' doesn't support transparency.", OUTPUT_FORMATS, true); + + addInputPanel(name); + addInputPanel(dir); + addInputPanel(filterMin); + addInputPanel(filterMag); + addInputPanel(maxWidth); + addInputPanel(maxHeight); + addInputPanel(outputFormat); + + String maxWH = Integer.toString(ImageUtils.getRecommendedAtlasSize()); + + maxWidth.setText(maxWH); + maxHeight.setText(maxWH); + filterMin.setText(FILTERS[0]); + filterMag.setText(FILTERS[0]); + outputFormat.setText(OUTPUT_FORMATS[0]); + + setInfo(INFO); + } + + @Override + protected void ok() { + Message.showMsg(getStage(), "Generating atlas...", true); + + Timer.schedule(new Task() { + @Override + public void run() { + genAtlas(); + } + }, 1); + } + + @Override + protected boolean validateFields() { + boolean ok = true; + + if (!dir.validateField()) + ok = false; + + if (!name.validateField()) + ok = false; + + return ok; + } + + private void genAtlas() { + String outdir = Ctx.project.getAssetPath() + Project.ATLASES_PATH; + List res = Ctx.project.getResolutions(); + String name = this.name.getText(); + String fMin = filterMin.getText(); + String fMag = filterMag.getText(); + + TextureFilter filterMin = null, filterMag = null; + + if (fMin.equals("Linear")) + filterMin = TextureFilter.Linear; + else if (fMin.equals("Nearest")) + filterMin = TextureFilter.Nearest; + else if (fMin.equals("MipMap")) + filterMin = TextureFilter.MipMap; + else if (fMin.equals("MipMapLinearLinear")) + filterMin = TextureFilter.MipMapLinearLinear; + else if (fMin.equals("MipMapLinearNearest")) + filterMin = TextureFilter.MipMapLinearNearest; + else if (fMin.equals("MipMapNearestLinear")) + filterMin = TextureFilter.MipMapNearestLinear; + else if (fMin.equals("MipMapNearestNearest")) + filterMin = TextureFilter.MipMapNearestNearest; + + if (fMag.equals("Linear")) + filterMag = TextureFilter.Linear; + else if (fMag.equals("Nearest")) + filterMag = TextureFilter.Nearest; + else if (fMag.equals("MipMap")) + filterMag = TextureFilter.MipMap; + else if (fMag.equals("MipMapLinearLinear")) + filterMag = TextureFilter.MipMapLinearLinear; + else if (fMag.equals("MipMapLinearNearest")) + filterMag = TextureFilter.MipMapLinearNearest; + else if (fMag.equals("MipMapNearestLinear")) + filterMag = TextureFilter.MipMapNearestLinear; + else if (fMag.equals("MipMapNearestNearest")) + filterMag = TextureFilter.MipMapNearestNearest; + + int maxW = Integer.parseInt(maxWidth.getText()); + int maxH = Integer.parseInt(maxHeight.getText()); + + for (String r : res) { + float scale = Float.parseFloat(r); + + try { + ImageUtils.createAtlas(dir.getText(), outdir + "/" + r, name + ".atlas", scale, (int) (maxW * scale), + (int) (maxH * scale), filterMin, filterMag, outputFormat.getText(), true); + } catch (IOException e) { + EditorLogger.error(e.getMessage()); + Message.showMsgDialog(getStage(), "Error creating atlas", e.getMessage()); + return; + } + } + + Message.hideMsg(); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CreateProjectDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CreateProjectDialog.java new file mode 100644 index 000000000..140d05e3d --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CreateProjectDialog.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.io.File; + +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.utils.Timer; +import com.badlogic.gdx.utils.Timer.Task; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.ui.panels.EditDialog; +import com.bladecoder.engineeditor.ui.panels.FileInputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; + +public class CreateProjectDialog extends EditDialog { + + public static final String INFO = "A project folder with the proper structure will be created in the selected location."; + + private static final String ANDROID_SDK_PROP = "package.SDK"; + + private InputPanel projectName; + private InputPanel pkg; + private InputPanel spinePlugin; + private FileInputPanel location; + private FileInputPanel androidSdk; + + public CreateProjectDialog(Skin skin) { + super("CREATE PROJECT", skin); + + setInfo(INFO); + + projectName = InputPanelFactory.createInputPanel(skin, "Project Name", "Set the name of the project", true); + + pkg = InputPanelFactory.createInputPanel(skin, "Package", + "The package will be used as package ID in Android and IOS. The launchers will be in this package too.", + Param.Type.STRING, true, "com.myadv.game"); + + spinePlugin = InputPanelFactory.createInputPanel(skin, "Spine animation support", + "The game can use Spine animations, require Spine License to distribute the game. See http://www.esotericsoftware.com for more info.", + Param.Type.BOOLEAN, true, "false"); + + location = new FileInputPanel(skin, "Location", "Select the folder location for the project", + FileInputPanel.DialogType.DIRECTORY); + + androidSdk = new FileInputPanel(skin, "Android SDK", + "Select the Android SDK folder to create the Android package. If empty, the ANDROID_HOME variable will be used.", + FileInputPanel.DialogType.DIRECTORY, false); + + addInputPanel(projectName); + addInputPanel(pkg); + addInputPanel(location); + addInputPanel(spinePlugin); + addInputPanel(androidSdk); + + String sdkprop = Ctx.project.getEditorConfig().getProperty(ANDROID_SDK_PROP); + + if (sdkprop != null && new File(sdkprop).exists()) { + androidSdk.setText(sdkprop); + } + + // getStage().setKeyboardFocus(projectName.getField()); + } + + @Override + protected void ok() { + try { + Ctx.project.getEditorConfig().setProperty(ANDROID_SDK_PROP, androidSdk.getText()); + Ctx.project.saveProject(); + } catch (Exception ex) { + String msg = ex.getClass().getSimpleName() + + " - " + ex.getMessage(); + Message.showMsgDialog(getStage(), "Error saving project", msg); + } + + final Stage stage = getStage(); + + Message.showMsg(getStage(), "Creating project...", true); + Timer.schedule(new Task() { + @Override + public void run() { + createProject(stage); + } + },1); + } + + private void createProject(Stage stage) { + + try { + Ctx.project.createProject(location.getText(), projectName.getText(), pkg.getText(), androidSdk.getText(), + Boolean.parseBoolean(spinePlugin.getText())); + + Message.showMsg(stage, "Project successfully created", 3); + } catch (Exception e) { + String msg = e.getClass().getSimpleName() + " - " + + e.getMessage(); + Message.showMsgDialog(stage, "Error creating project", msg); + EditorLogger.error(msg, e); + return; + } + } + + @Override + protected boolean validateFields() { + boolean isOk = true; + + if (!projectName.validateField()) { + isOk = false; + } + + if (!pkg.validateField()) { + isOk = false; + } + + if (location.getFile() != null) { + location.setError(false); + } else { + location.setError(true); + isOk = false; + } + +// if (System.getenv("ANDROID_HOME") == null && androidSdk.getFile() == null) { +// androidSdk.setError(true); +// isOk = false; +// } else { +// androidSdk.setError(false); +// } + + return isOk; + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/CreateResolutionDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CreateResolutionDialog.java similarity index 60% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/CreateResolutionDialog.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CreateResolutionDialog.java index 4d167f8af..4dfdd6b4a 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/CreateResolutionDialog.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/CreateResolutionDialog.java @@ -22,87 +22,94 @@ import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.ChangeEvent; +import com.badlogic.gdx.utils.Timer; +import com.badlogic.gdx.utils.Timer.Task; import com.bladecoder.engine.actions.Param; import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.ImageUtils; +import com.bladecoder.engineeditor.common.Message; import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.ui.components.EditDialog; -import com.bladecoder.engineeditor.ui.components.InputPanel; -import com.bladecoder.engineeditor.utils.ImageUtils; +import com.bladecoder.engineeditor.ui.panels.EditDialog; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; public class CreateResolutionDialog extends EditDialog { - private static final String INFO = "Create a new resolution. Scale backgrounds and overlays from the world resolution."; + private static final String INFO = "Create a new resolution. Scale all atlases and images of the game."; private InputPanel scale; - + protected ChangeListener listener; - - String atlasDir = Ctx.project.getProjectPath() + "/" + Project.ATLASES_PATH; - String bgDir = Ctx.project.getProjectPath() + "/" + Project.BACKGROUNDS_PATH; - String uiDir = Ctx.project.getProjectPath() + "/" + Project.UI_PATH; - String imageDir = Ctx.project.getProjectPath() + "/" + Project.IMAGE_PATH; + + String atlasDir = Ctx.project.getAssetPath() + Project.ATLASES_PATH; + String uiDir = Ctx.project.getAssetPath() + Project.UI_PATH; + String imageDir = Ctx.project.getAssetPath() + Project.IMAGE_PATH; public CreateResolutionDialog(Skin skin) { super("CREATE RESOLUTION", skin); - - scale = new InputPanel(skin, "Scale", - "Scale relative to the world resolution", Param.Type.FLOAT, true); + + scale = InputPanelFactory.createInputPanel(skin, "Scale", "Scale relative to the world resolution", + Param.Type.FLOAT, true); addInputPanel(scale); - + setInfo(INFO); } @Override protected void ok() { - new Thread(new Runnable() { - Stage stage = getStage(); - + + final Stage stage = getStage(); + + Message.showMsg(stage, "Creating resolution...", true); + + Timer.schedule(new Task() { @Override public void run() { - Ctx.msg.show(stage, "Creating resolution...", true); - createResolution(); - String msg = scaleImages(); - - if(listener != null) + String msg = scaleImages(); + + if (listener != null) listener.changed(new ChangeEvent(), CreateResolutionDialog.this); - - Ctx.msg.hide(); - - if(msg != null) - Ctx.msg.show(stage, msg, 2); + + Message.hideMsg(); + + if (msg != null) + Message.showMsgDialog(stage, "Error creating resolution", msg); } - }).start(); + }, 1); } - + private void createResolution() { - float s = Float.parseFloat(scale.getText()); - String prefix = (int)(Ctx.project.getWorld().getWidth() * s) + "_" + (int)(Ctx.project.getWorld().getHeight() * s); - +// float s = Float.parseFloat(scale.getText()); +// String prefix = (int)(Ctx.project.getWorld().getWidth() * s) + "_" + (int)(Ctx.project.getWorld().getHeight() * s); + String prefix = scale.getText().trim(); + new File(atlasDir + "/" + prefix).mkdir(); - new File(bgDir + "/" + prefix).mkdir(); new File(uiDir + "/" + prefix).mkdir(); - new File(imageDir + "/" + prefix).mkdir(); + new File(imageDir + "/" + prefix).mkdir(); } private String scaleImages() { - + float s = Float.parseFloat(scale.getText()); - String prefix = (int)(Ctx.project.getWorld().getWidth() * s) + "_" + (int)(Ctx.project.getWorld().getHeight() * s); - +// String prefix = (int)(Ctx.project.getWorld().getWidth() * s) + "_" + (int)(Ctx.project.getWorld().getHeight() * s); + String prefix = scale.getText().trim(); + // COPY ASSETS FROM WORLD RESOLUTION SCALED String wPrefix = Ctx.project.getResDir(); - + try { ImageUtils.scaleDirFiles(new File(uiDir + "/" + wPrefix), new File(uiDir + "/" + prefix), s); - ImageUtils.scaleDirFiles(new File(bgDir + "/" + wPrefix), new File(bgDir + "/" + prefix), s); ImageUtils.scaleDirFiles(new File(imageDir + "/" + wPrefix), new File(imageDir + "/" + prefix), s); + + ImageUtils.scaleDirAtlases(new File(atlasDir + "/" + wPrefix), new File(atlasDir + "/" + prefix), s); + ImageUtils.scaleDirAtlases(new File(uiDir + "/" + wPrefix), new File(uiDir + "/" + prefix), s); } catch (IOException e) { return e.getMessage(); } - + return null; } diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/DialogList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/DialogList.java new file mode 100644 index 000000000..0c6089c33 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/DialogList.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Arrays; +import java.util.List; + +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.bladecoder.engine.model.CharacterActor; +import com.bladecoder.engine.model.Dialog; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.ElementUtils; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.CellRenderer; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.ModelList; +import com.bladecoder.engineeditor.undo.UndoDeleteDialog; + +public class DialogList extends ModelList { + + private OptionList options; + + @Override + protected EditModelDialog getEditElementDialogInstance(Dialog e) { + return new EditDialogDialog(skin, parent, e); + } + + public DialogList(Skin skin) { + super(skin, true); + + options = new OptionList(skin); + row(); + add(options).expand().fill(); + + list.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + int pos = list.getSelectedIndex(); + + addOptions(); + + toolbar.disableEdit(pos == -1); + } + }); + + list.setCellRenderer(listCellRenderer); + listCellRenderer.layout(list.getStyle()); + container.minHeight(listCellRenderer.getItemHeight() * 5); + container.maxHeight(listCellRenderer.getItemHeight() * 5); + + Ctx.project.addPropertyChangeListener(Project.NOTIFY_ELEMENT_CREATED, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getNewValue() instanceof Dialog && !(evt.getSource() instanceof EditDialogDialog) && parent instanceof CharacterActor) { + addElements(parent, Arrays.asList(parent.getDialogs().values().toArray(new Dialog[0]))); + } + } + }); + } + + public void addOptions() { + int pos = list.getSelectedIndex(); + + Dialog d = null; + + if (pos != -1) { + d = list.getItems().get(pos); + options.addElements(d, d.getOptions()); + } else { + options.addElements(null, null); + } + } + + + @Override + public void addElements(CharacterActor a, List elements) { + super.addElements(a, elements); + addOptions(); + } + + @Override + protected void delete() { + + Dialog d = removeSelected(); + + parent.getDialogs().remove(d.getId()); + + // TRANSLATIONS + Ctx.project.getI18N().putTranslationsInElement(d); + + // UNDO + Ctx.project.getUndoStack().add(new UndoDeleteDialog(parent, d)); + + // Clear options here because change event doesn't call when deleting + // the last element + if (list.getSelectedIndex() == -1) + addOptions(); + + Ctx.project.setModified(); + } + + @Override + protected void copy() { + Dialog e = list.getSelected(); + + if (e == null) + return; + + clipboard = (Dialog)ElementUtils.cloneElement(e); + toolbar.disablePaste(false); + + // TRANSLATIONS + Ctx.project.getI18N().putTranslationsInElement(clipboard); + } + + @Override + protected void paste() { + Dialog newElement = (Dialog)ElementUtils.cloneElement(clipboard); + + newElement.setId(ElementUtils.getCheckedId(newElement.getId(), parent.getDialogs().keySet().toArray(new String[0]))); + + int pos = list.getSelectedIndex() + 1; + + list.getItems().insert(pos, newElement); + + parent.addDialog(newElement); + Ctx.project.getI18N().extractStrings(Ctx.project.getSelectedScene().getId(),parent.getId(), newElement); + + list.setSelectedIndex(pos); + list.invalidateHierarchy(); + + Ctx.project.setModified(); + } + + + // ------------------------------------------------------------------------- + // ListCellRenderer + // ------------------------------------------------------------------------- + private final CellRenderer listCellRenderer = new CellRenderer() { + + @Override + protected String getCellTitle(Dialog e) { + return e.getId(); + } + + @Override + public TextureRegion getCellImage(Dialog e) { + return Ctx.assetManager.getIcon("ic_talkto"); + } + + @Override + protected boolean hasSubtitle() { + return false; + } + + @Override + protected boolean hasImage() { + return true; + } + }; + +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditActionDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditActionDialog.java new file mode 100644 index 000000000..a4c5f48ab --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditActionDialog.java @@ -0,0 +1,191 @@ +/******************************************************************************* + + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.util.Arrays; + +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextField; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.bladecoder.engine.actions.Action; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engine.i18n.I18N; +import com.bladecoder.engine.model.Verb; +import com.bladecoder.engine.util.ActionUtils; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.ActionDetector; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.FilteredSelectBox; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; +import com.bladecoder.engineeditor.ui.panels.ScopePanel; + +public class EditActionDialog extends EditModelDialog { + private InputPanel actionPanel; + private String scope; + private int pos; + + @SuppressWarnings("unchecked") + public EditActionDialog(Skin skin, Verb parent, Action e, String scope, int pos) { + super(skin); + + this.scope = scope; + this.pos = e == null ? pos + 1 : pos; + + String[] actions = ActionDetector.getActionNames(); + Arrays.sort(actions); + + actionPanel = InputPanelFactory.createInputPanel(skin, "Action", "Select the action to create.", actions, true); + + ((FilteredSelectBox) actionPanel.getField()).addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + setAction(); + } + }); + + if (e != null) { + String id = ActionUtils.getName(e.getClass()); + + if (id != null) { + actionPanel.setText(id); + } + + } + + init(parent, e, new InputPanel[0]); + + setAction(); + + if (e != null) + modelToInputs(); + + } + + private void setAction() { + String id = actionPanel.getText(); + + getCenterPanel().clear(); + addInputPanel(actionPanel); + + Action tmp = null; + + tmp = ActionDetector.create(id, null); + + String info = ActionUtils.getInfo(tmp.getClass()); + + if(ActionUtils.isDeprecated(tmp.getClass())) + info = "[RED]DEPRECATED[]\n" + info; + + setInfo(info); + + if (e == null || tmp == null || !(e.getClass().getName().equals(tmp.getClass().getName()))) + e = tmp; + + if (e != null) { + Param[] params = ActionUtils.getParams(e); + + i = new InputPanel[params.length]; + + for (int j = 0; j < params.length; j++) { + if (params[j].options instanceof Enum[]) { + i[j] = InputPanelFactory.createInputPanel(getSkin(), params[j].name, params[j].desc, params[j].type, + params[j].mandatory, params[j].defaultValue, (Enum[]) params[j].options); + } else { + i[j] = InputPanelFactory.createInputPanel(getSkin(), params[j].name, params[j].desc, params[j].type, + params[j].mandatory, params[j].defaultValue, (String[]) params[j].options); + } + + addInputPanel(i[j]); + + if ((i[j].getField() instanceof TextField && params[j].name.toLowerCase().endsWith("text")) + || i[j].getField() instanceof ScrollPane) { + i[j].getCell(i[j].getField()).fillX(); + } + } + } else { + i = new InputPanel[0]; + } + } + + @Override + protected void inputsToModel(boolean create) { + for (int j = 0; j < i.length; j++) { + String v = i[j].getText(); + try { + if (i[j].getTitle().toLowerCase().endsWith("text")) { + + String key = ActionUtils.getStringValue(e, i[j].getTitle()); + + if (scope.equals(ScopePanel.WORLD_SCOPE)) { + if (key == null || key.isEmpty() || key.charAt(0) != I18N.PREFIX) + key = Ctx.project.getI18N().genKey(null, null, parent.getHashKey(), pos, i[j].getTitle()); + + Ctx.project.getI18N().setWorldTranslation(key, v); + } else if (scope.equals(ScopePanel.SCENE_SCOPE)) { + if (key == null || key.isEmpty() || key.charAt(0) != I18N.PREFIX) + key = Ctx.project.getI18N().genKey(Ctx.project.getSelectedScene().getId(), null, + parent.getHashKey(), pos, i[j].getTitle()); + + Ctx.project.getI18N().setTranslation(key, v); + } else { + if (key == null || key.isEmpty() || key.charAt(0) != I18N.PREFIX) + key = Ctx.project.getI18N().genKey(Ctx.project.getSelectedScene().getId(), + Ctx.project.getSelectedActor().getId(), parent.getHashKey(), pos, i[j].getTitle()); + + Ctx.project.getI18N().setTranslation(key, v); + } + + if (v != null && !v.isEmpty()) + v = key; + else + v = null; + } + + ActionUtils.setParam(e, i[j].getTitle(), v); + + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + EditorLogger.error(e.getMessage()); + } + } + + Ctx.project.setModified(); + } + + @Override + protected void modelToInputs() { + for (int j = 0; j < i.length; j++) { + + try { + String v = ActionUtils.getStringValue(e, i[j].getTitle()); + + if (scope.equals(ScopePanel.WORLD_SCOPE)) + v = Ctx.project.getI18N().getWorldTranslation(v); + else + v = Ctx.project.translate(v); + + i[j].setText(v); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + EditorLogger.error(e.getMessage()); + } + } + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditActorDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditActorDialog.java new file mode 100644 index 000000000..666f75720 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditActorDialog.java @@ -0,0 +1,682 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import com.badlogic.gdx.math.Polygon; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engine.actions.Param.Type; +import com.bladecoder.engine.i18n.I18N; +import com.bladecoder.engine.model.*; +import com.bladecoder.engine.spine.SpineRenderer; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.AlignUtils; +import com.bladecoder.engineeditor.common.ElementUtils; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.FilteredSelectBox; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; +import com.bladecoder.engineeditor.ui.panels.OptionsInputPanel; + +import java.util.HashMap; + +public class EditActorDialog extends EditModelDialog { + + private final static float DEFAULT_DIM = 200; + + private final static String BACKGROUND_TYPE_STR = "background"; + private final static String SPRITE_TYPE_STR = "sprite"; + private final static String CHARACTER_TYPE_STR = "character"; + private final static String OBSTACLE_TYPE_STR = "obstacle"; + private final static String ANCHOR_TYPE_STR = "anchor"; + private final static String WALKZONE_TYPE_STR = "walkzone"; + + private static final String ACTOR_TYPES[] = {BACKGROUND_TYPE_STR, SPRITE_TYPE_STR, CHARACTER_TYPE_STR, + ANCHOR_TYPE_STR, WALKZONE_TYPE_STR, OBSTACLE_TYPE_STR}; + + private static final String ACTOR_RENDERERS[] = {Project.ATLAS_RENDERER_STRING, Project.SPINE_RENDERER_STRING, + Project.IMAGE_RENDERER_STRING, Project.PARTICLE_RENDERER_STRING, + Project.TEXT_RENDERER_STRING}; + + private static final String TYPES_INFO[] = { + "Background actors don't have sprites or animations. They are used to interact with objects drawn in the " + + "background", + "Sprite actors have one or several sprites or animations", + "Character actors have dialogs and stand, walk and talk animations", + "Anchor actors are used as reference for positioning other actors", + "Define the walkable area for characters", "Obstacle actors forbids zones for walking actors"}; + + private static final String TEXT_ALIGN[] = {"left", "center", "right"}; + private static final String ORG_ALIGN[] = {"bottom", "center", "left", "right", "top", "bottom-right", + "bottom-left", "top-right", "top-left"}; + + private InputPanel typePanel; + private InputPanel id; + private InputPanel layer; + private InputPanel visible; + private InputPanel interaction; + private InputPanel desc; + private InputPanel state; + private InputPanel renderer; + private InputPanel fakeDepth; + private InputPanel pos; + private InputPanel refPoint; + private InputPanel scale; + private InputPanel rot; + private InputPanel tint; + private InputPanel bboxFromRenderer; + private InputPanel zIndex; + private InputPanel walkingSpeed; + private InputPanel talkingTextPos; + + private InputPanel orgAlign; + + private InputPanel textColor; + private InputPanel textStyle; + + // Spine Renderer + private InputPanel spineSkin; + + // Particle Renderer + private InputPanel particleName; + private InputPanel particleAtlas; + + // Text Renderer + private InputPanel text; + private InputPanel font; + private InputPanel size; + private InputPanel textAlign; + + private InputPanel textMaxWidth; + private InputPanel borderWidth; + private InputPanel borderColor; + private InputPanel borderStraight; + private InputPanel shadowOffsetX; + private InputPanel shadowOffsetY; + private InputPanel shadowColor; + + @SuppressWarnings("unchecked") + public EditActorDialog(Skin skin, Scene parent, BaseActor e) { + super(skin); + + typePanel = InputPanelFactory.createInputPanel(skin, "Actor Type", "Actors can be from different types", + ACTOR_TYPES, true); + + id = InputPanelFactory.createInputPanel(skin, "Actor ID", "IDs can not contain '.' character.", true); + + layer = InputPanelFactory.createInputPanel(skin, "Actor Layer", "The layer for drawing order", + getLayers(parent), true); + + visible = InputPanelFactory.createInputPanel(skin, "Visible", "The actor visibility.", Param.Type.BOOLEAN, true, + "true"); + + interaction = InputPanelFactory.createInputPanel(skin, "Interaction", + "True when the actor reacts to the user input.", Param.Type.BOOLEAN, true, "true"); + + desc = InputPanelFactory.createInputPanel(skin, "Description", + "The text showed when the cursor is over the actor."); + state = InputPanelFactory.createInputPanel(skin, "State", + "Initial state of the actor. Actors can be in several states along the game."); + + renderer = InputPanelFactory.createInputPanel(skin, "Actor Renderer", + "Actors can be renderer from several sources", ACTOR_RENDERERS, true); + + fakeDepth = InputPanelFactory.createInputPanel(skin, "Fake Depth", "Scene fake depth for scaling", + Param.Type.BOOLEAN, true, "false"); + + pos = InputPanelFactory.createInputPanel(skin, "Position", "The sprite position.", Param.Type.VECTOR2, true, + "0,0"); + refPoint = InputPanelFactory.createInputPanel(skin, "Ref. Point", + "Point of reference to relative position other actors.", Param.Type.VECTOR2, true, "0,0"); + scale = InputPanelFactory.createInputPanel(skin, "Scale", "The sprite scale.", Param.Type.VECTOR2, true, "1,1"); + + rot = InputPanelFactory.createInputPanel(skin, "Rotation", "The sprite rotation.", Param.Type.FLOAT, true, "0"); + + tint = InputPanelFactory.createInputPanel(skin, "Tint", "Draw the actor with the specified color (RRGGBBAA).", + Param.Type.COLOR, false); + + bboxFromRenderer = InputPanelFactory.createInputPanel(skin, "BBox From Renderer", + "Sets the actor bounding box automatically from the sprite dimensions.", Param.Type.BOOLEAN, true, + "true"); + + zIndex = InputPanelFactory.createInputPanel(skin, "zIndex", "The order to draw.", Param.Type.FLOAT, false, "0"); + + orgAlign = InputPanelFactory.createInputPanel(skin, "orgAlign", + "Alignment of the origin for rotation and scale.", ORG_ALIGN, true); + + walkingSpeed = InputPanelFactory.createInputPanel(skin, "Walking Speed", + "The walking speed in pix/sec. Default 700.", Param.Type.FLOAT, true, + Float.toString(CharacterActor.DEFAULT_WALKING_SPEED)); + + spineSkin = InputPanelFactory.createInputPanel(skin, "Skin", "The initial skin."); + + textColor = InputPanelFactory.createInputPanel(skin, "Text Color", + "The text color (RRGGBBAA) when the actor talks.", Param.Type.COLOR, false); + + textStyle = InputPanelFactory.createInputPanel(skin, "Text Style", + "The style to use (an entry in your `ui.json` in the `com.bladecoder.engine.ui" + + ".TextManagerUI$TextManagerUIStyle` section).", + Param.Type.STRING, false); + + talkingTextPos = InputPanelFactory.createInputPanel(skin, "Talking Text Pos", + "Position of the text when talking. Relative to the character position.", Param.Type.VECTOR2, false); + + particleName = InputPanelFactory.createInputPanel(skin, "Particle Name", "The name of the particle system.", + Type.PARTICLE_ASSET, true); + + particleAtlas = InputPanelFactory.createInputPanel(skin, "Particle Atlas", + "The atlas used by the particle system.", Type.ATLAS_ASSET, true); + + text = InputPanelFactory.createInputPanel(skin, "Text", "The text to draw.", Type.SMALL_TEXT, true); + text.getCell(text.getField()).fillX(); + + font = InputPanelFactory.createInputPanel(skin, "Font", "Select the font name.", Type.FONT_ASSET, true); + size = InputPanelFactory.createInputPanel(skin, "Size", "The size of the text.", Type.INTEGER, true, "20"); + textAlign = InputPanelFactory.createInputPanel(skin, "Text Align", "The alignment of the text.", TEXT_ALIGN, + true); + textMaxWidth = InputPanelFactory.createInputPanel(skin, "Max Width", "The max width of the text block.", + Type.INTEGER, + true, "0"); + borderWidth = InputPanelFactory.createInputPanel(skin, "Border Width", "Zero for no border.", Type.INTEGER, + true, "0"); + borderColor = InputPanelFactory.createInputPanel(skin, "Border Color", "The Border Color.", Type.COLOR, true, + "black"); + borderStraight = InputPanelFactory.createInputPanel(skin, "Border Straigh", "Is the border straight?", + Type.BOOLEAN, true); + shadowOffsetX = InputPanelFactory.createInputPanel(skin, "Shadow Offset X", "The Shadow X offset.", + Type.INTEGER, true, "0"); + shadowOffsetY = InputPanelFactory.createInputPanel(skin, "Shadow Offset Y", "The Shadow Y offset.", + Type.INTEGER, true, "0"); + shadowColor = InputPanelFactory.createInputPanel(skin, "Shadow Color", "The shadow Color.", Type.COLOR, true, + "black"); + + setInfo(TYPES_INFO[0]); + + ((FilteredSelectBox) typePanel.getField()).addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + typeChanged(); + } + }); + + ((FilteredSelectBox) renderer.getField()).addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + rendererChanged(); + } + }); + + init(parent, e, + new InputPanel[]{typePanel, id, renderer, particleName, particleAtlas, layer, visible, interaction, + desc, state, fakeDepth, pos, refPoint, scale, rot, tint, text, font, size, textAlign, + textMaxWidth, + borderWidth, borderColor, borderStraight, shadowOffsetX, shadowOffsetY, shadowColor, + bboxFromRenderer, zIndex, orgAlign, walkingSpeed, talkingTextPos, spineSkin, textColor, + textStyle}); + + typeChanged(); + + } + + private String[] getLayers(Scene parent) { + String[] result = new String[parent.getLayers().size()]; + + for (int i = 0; i < parent.getLayers().size(); i++) { + result[i] = parent.getLayers().get(i).getName(); + } + + return result; + } + + private void typeChanged() { + int i = ((OptionsInputPanel) typePanel).getSelectedIndex(); + + setInfo(TYPES_INFO[i]); + + hideAllInputs(); + + setVisible(pos, true); + + if (!ACTOR_TYPES[i].equals(ANCHOR_TYPE_STR) && !ACTOR_TYPES[i].equals(WALKZONE_TYPE_STR)) { + setVisible(visible, true); + } + + if (!ACTOR_TYPES[i].equals(OBSTACLE_TYPE_STR) && !ACTOR_TYPES[i].equals(ANCHOR_TYPE_STR) + && !ACTOR_TYPES[i].equals(WALKZONE_TYPE_STR)) { + setVisible(layer, true); + setVisible(interaction, true); + setVisible(desc, true); + setVisible(state, true); + setVisible(zIndex, true); + setVisible(refPoint, true); + } + + if (ACTOR_TYPES[i].equals(SPRITE_TYPE_STR) || ACTOR_TYPES[i].equals(CHARACTER_TYPE_STR)) { + setVisible(renderer, true); + setVisible(fakeDepth, true); + setVisible(scale, true); + setVisible(rot, true); + setVisible(tint, true); + setVisible(bboxFromRenderer, true); + setVisible(orgAlign, true); + } + + if (ACTOR_TYPES[i].equals(CHARACTER_TYPE_STR)) { + setVisible(walkingSpeed, true); + setVisible(textColor, true); + setVisible(textStyle, true); + setVisible(talkingTextPos, true); + } + + rendererChanged(); + } + + private void rendererChanged() { + int i = ((OptionsInputPanel) renderer).getSelectedIndex(); + + // setInfo(RENDERERS_INFO[i]); + + setVisible(spineSkin, false); + + setVisible(particleName, false); + setVisible(particleAtlas, false); + + setVisible(text, false); + setVisible(font, false); + setVisible(size, false); + setVisible(textAlign, false); + setVisible(textMaxWidth, false); + setVisible(borderWidth, false); + setVisible(borderColor, false); + setVisible(borderStraight, false); + setVisible(shadowOffsetX, false); + setVisible(shadowOffsetY, false); + setVisible(shadowColor, false); + + if (renderer.isVisible()) { + if (ACTOR_RENDERERS[i].equals(Project.SPINE_RENDERER_STRING)) { + setVisible(spineSkin, true); + } else if (ACTOR_RENDERERS[i].equals(Project.PARTICLE_RENDERER_STRING)) { + setVisible(particleName, true); + setVisible(particleAtlas, true); + } else if (ACTOR_RENDERERS[i].equals(Project.TEXT_RENDERER_STRING)) { + setVisible(text, true); + setVisible(font, true); + setVisible(size, true); + setVisible(textAlign, true); + setVisible(textMaxWidth, true); + setVisible(borderWidth, true); + setVisible(borderColor, true); + setVisible(borderStraight, true); + setVisible(shadowOffsetX, true); + setVisible(shadowOffsetY, true); + setVisible(shadowColor, true); + } + } + } + + private void hideAllInputs() { + + for (int idx = 2; idx < i.length; idx++) { + InputPanel ip = i[idx]; + + setVisible(ip, false); + } + } + + @Override + protected void inputsToModel(boolean create) { + + String type = typePanel.getText(); + boolean typeChanged = false; + BaseActor oldElement = e; + String oldId = null; + + boolean isPlayer = false; + + if (!create) { + + typeChanged = (type.equals(CHARACTER_TYPE_STR) && !(e instanceof CharacterActor)) + || (type.equals(SPRITE_TYPE_STR) && (!(e instanceof SpriteActor) || e instanceof CharacterActor)) + || (type.equals(BACKGROUND_TYPE_STR) + && (!(e instanceof InteractiveActor) || e instanceof SpriteActor)) + || (type.equals(OBSTACLE_TYPE_STR) && !(e instanceof ObstacleActor)) + || (type.equals(ANCHOR_TYPE_STR) && !(e instanceof AnchorActor)) + || (type.equals(WALKZONE_TYPE_STR) && !(e instanceof WalkZoneActor)); + + isPlayer = parent.getPlayer() == e; + + // remove to allow id, zindex and layer change + parent.removeActor(e); + + oldId = e.getId(); + } + + if (create || typeChanged) { + if (type.equals(BACKGROUND_TYPE_STR)) { + e = new InteractiveActor(); + } else if (type.equals(SPRITE_TYPE_STR)) { + e = new SpriteActor(); + } else if (type.equals(CHARACTER_TYPE_STR)) { + e = new CharacterActor(); + } else if (type.equals(OBSTACLE_TYPE_STR)) { + e = new ObstacleActor(); + } else if (type.equals(WALKZONE_TYPE_STR)) { + e = new WalkZoneActor(); + } else if (type.equals(ANCHOR_TYPE_STR)) { + e = new AnchorActor(); + } + + if (!(e instanceof SpriteActor) && !(e instanceof AnchorActor)) { + Polygon bbox = e.getBBox(); + + bbox.setVertices(new float[8]); + + float[] verts = bbox.getVertices(); + + verts[0] = -DEFAULT_DIM / 2; + verts[1] = 0f; + verts[2] = -DEFAULT_DIM / 2; + verts[3] = DEFAULT_DIM; + verts[4] = DEFAULT_DIM / 2; + verts[5] = DEFAULT_DIM; + verts[6] = DEFAULT_DIM / 2; + verts[7] = 0f; + bbox.dirty(); + } + } + + if (typeChanged) { + // Put sounds, verbs and animations in the new element + + if (oldElement instanceof InteractiveActor && e instanceof InteractiveActor) { + HashMap verbs = ((InteractiveActor) e).getVerbManager().getVerbs(); + HashMap oldVerbs = ((InteractiveActor) oldElement).getVerbManager().getVerbs(); + + for (String k : oldVerbs.keySet()) { + Verb v = oldVerbs.get(k); + verbs.put(k, v); + } + } + + if (oldElement instanceof SpriteActor && e instanceof SpriteActor) { + ((SpriteActor) e).setRenderer(((SpriteActor) oldElement).getRenderer()); + } + } + + e.setId(ElementUtils.getCheckedId(id.getText(), parent.getActors().keySet().toArray(new String[0]))); + e.setVisible(Boolean.parseBoolean(visible.getText())); + + Vector2 p = Param.parseVector2(pos.getText()); + + e.setPosition(p.x, p.y); + + if (e instanceof InteractiveActor) { + InteractiveActor ia = (InteractiveActor) e; + + ia.setLayer(layer.getText()); + ia.setInteraction(Boolean.parseBoolean(interaction.getText())); + + Vector2 rp = Param.parseVector2(refPoint.getText()); + + ia.setRefPoint(rp.x, rp.y); + + String key = ia.getDesc(); + + if (key == null || key.isEmpty() || key.charAt(0) != I18N.PREFIX || !e.getId().equals(oldId)) + key = Ctx.project.getI18N().genKey(parent.getId(), e.getId(), "desc"); + + Ctx.project.getI18N().setTranslation(key, desc.getText()); + + if (desc.getText() != null) + ia.setDesc(key); + else + ia.setDesc(null); + + ia.setState(state.getText()); + + float zi = 0f; + + try { + zi = Float.parseFloat(zIndex.getText() == null ? "0" : zIndex.getText()); + } catch (NumberFormatException e) { + } + + ia.setZIndex(zi); + + if (e instanceof SpriteActor) { + SpriteActor sa = (SpriteActor) e; + + String rendererType = renderer.getText(); + + if (Project.ATLAS_RENDERER_STRING.equals(rendererType)) { + if (sa.getRenderer() == null || !(sa.getRenderer() instanceof AtlasRenderer)) + sa.setRenderer(new AtlasRenderer()); + } else if (Project.IMAGE_RENDERER_STRING.equals(rendererType)) { + if (sa.getRenderer() == null || !(sa.getRenderer() instanceof ImageRenderer)) + sa.setRenderer(new ImageRenderer()); + } else if (Project.PARTICLE_RENDERER_STRING.equals(rendererType)) { + ParticleRenderer r; + + if (sa.getRenderer() == null || !(sa.getRenderer() instanceof ParticleRenderer)) { + r = new ParticleRenderer(); + sa.setRenderer(r); + } else { + r = (ParticleRenderer) sa.getRenderer(); + } + + r.setParticleName(particleName.getText()); + r.setAtlasName(particleAtlas.getText()); + + } else if (Project.TEXT_RENDERER_STRING.equals(rendererType)) { + TextRenderer r; + + if (sa.getRenderer() == null || !(sa.getRenderer() instanceof TextRenderer)) { + r = new TextRenderer(); + sa.setRenderer(r); + } else { + r = (TextRenderer) sa.getRenderer(); + } + + key = text.getText(); + + if (key == null || key.isEmpty() || key.charAt(0) != I18N.PREFIX || !e.getId().equals(oldId)) + key = Ctx.project.getI18N().genKey(parent.getId(), e.getId(), "text"); + + Ctx.project.getI18N().setTranslation(key, text.getText()); + + if (text.getText() != null) + r.setText(key, text.getText()); + else + r.setText(null, null); + + r.setFontSize(Integer.parseInt(size.getText())); + r.setFontName(font.getText()); + r.setAlign(AlignUtils.getAlign(textAlign.getText())); + r.setMaxWidth(Integer.parseInt(textMaxWidth.getText())); + r.setBorderWidth(Integer.parseInt(borderWidth.getText())); + r.setBorderColor(Param.parseColor(borderColor.getText())); + r.setBorderStraight(Boolean.parseBoolean(borderStraight.getText())); + r.setShadowOffsetX(Integer.parseInt(shadowOffsetX.getText())); + r.setShadowOffsetY(Integer.parseInt(shadowOffsetY.getText())); + r.setShadowColor(Param.parseColor(shadowColor.getText())); + + // dispose to force reload the text attributes + sa.dispose(); + } else if (Project.SPINE_RENDERER_STRING.equals(rendererType)) { + SpineRenderer r; + + if (sa.getRenderer() == null || !(sa.getRenderer() instanceof SpineRenderer)) { + r = new SpineRenderer(); + sa.setRenderer(r); + } else { + r = (SpineRenderer) sa.getRenderer(); + } + + try { + r.setSkin(spineSkin.getText()); + } catch (Exception e) { + r.setSkin(null); + Message.showMsgDialog(getStage(), "Error setting skin.", e.getMessage()); + } + } + + sa.getRenderer().setWorld(parent.getWorld()); + boolean bbfr = Boolean.parseBoolean(bboxFromRenderer.getText()); + + if (bbfr != sa.isBboxFromRenderer()) + sa.setBboxFromRenderer(bbfr); + + // Bbox always has to be valid + if (sa.getBBox().getVertices().length < 4) { + sa.getRenderer().updateBboxFromRenderer(sa.getBBox()); + + if (!sa.isBboxFromRenderer()) + sa.getRenderer().updateBboxFromRenderer(null); + } + + sa.setFakeDepth(Boolean.parseBoolean(fakeDepth.getText())); + + Vector2 ps = Param.parseVector2(scale.getText()); + sa.setScale(ps.x, ps.y); + sa.setRot(Float.parseFloat(rot.getText())); + sa.getRenderer().setOrgAlign(AlignUtils.getAlign(orgAlign.getText())); + sa.setTint(Param.parseColor(tint.getText())); + + if (e instanceof CharacterActor) { + CharacterActor ca = (CharacterActor) e; + + ca.setWalkingSpeed(Float.parseFloat(walkingSpeed.getText())); + ca.setTextColor(Param.parseColor(textColor.getText())); + ca.setTextStyle(textStyle.getText()); + ca.setTalkingTextPos(Param.parseVector2(talkingTextPos.getText())); + } + } + } + + parent.addActor(e); + + if (isPlayer && !typeChanged) + parent.setPlayer((CharacterActor) e); + + if (e instanceof InteractiveActor) { + SceneLayer l = parent.getLayer(((InteractiveActor) e).getLayer()); + l.orderByZIndex(); + } + + if (e instanceof SpriteActor) + ((SpriteActor) e).retrieveAssets(); + + if (create && e instanceof WalkZoneActor && parent.getWalkZone() == null) + parent.setWalkZone(e.getId()); + + // TODO UNDO OP + // UndoOp undoOp = new UndoAddElement(doc, e); + // Ctx.project.getUndoStack().add(undoOp); + + Ctx.project.setModified(); + } + + @Override + protected void modelToInputs() { + + id.setText(e.getId()); + visible.setText(Boolean.toString(e.isVisible())); + pos.setText(Param.toStringParam(new Vector2(e.getX(), e.getY()))); + + if (e instanceof InteractiveActor) { + InteractiveActor ia = (InteractiveActor) e; + layer.setText(ia.getLayer()); + interaction.setText(Boolean.toString(ia.getInteraction())); + refPoint.setText(Param.toStringParam(ia.getRefPoint())); + desc.setText(Ctx.project.translate(ia.getDesc())); + state.setText(ia.getState()); + zIndex.setText(Float.toString(ia.getZIndex())); + + if (e instanceof SpriteActor) { + SpriteActor sa = (SpriteActor) e; + + ActorRenderer r = sa.getRenderer(); + + if (r instanceof AtlasRenderer) { + renderer.setText(Project.ATLAS_RENDERER_STRING); + } else if (r instanceof ImageRenderer) { + renderer.setText(Project.IMAGE_RENDERER_STRING); + } else if (r instanceof ParticleRenderer) { + renderer.setText(Project.PARTICLE_RENDERER_STRING); + ParticleRenderer pr = (ParticleRenderer) r; + + particleName.setText(pr.getParticleName()); + particleAtlas.setText(pr.getAtlasName()); + } else if (r instanceof TextRenderer) { + renderer.setText(Project.TEXT_RENDERER_STRING); + TextRenderer tr = (TextRenderer) r; + + text.setText(Ctx.project.translate(tr.getText())); + size.setText(Integer.toString(tr.getFontSize())); + font.setText(tr.getFontName()); + borderWidth.setText(Integer.toString(tr.getBorderWidth())); + textAlign.setText(AlignUtils.getAlign(tr.getAlign())); + textMaxWidth.setText(Integer.toString(tr.getMaxWidth())); + borderColor.setText(tr.getBorderColor().toString()); + borderStraight.setText(Boolean.toString(tr.isBorderStraight())); + shadowOffsetX.setText(Integer.toString(tr.getShadowOffsetX())); + shadowOffsetY.setText(Integer.toString(tr.getShadowOffsetY())); + shadowColor.setText(tr.getShadowColor().toString()); + + } else if (r instanceof SpineRenderer) { + renderer.setText(Project.SPINE_RENDERER_STRING); + spineSkin.setText(((SpineRenderer) r).getSkin()); + } + + fakeDepth.setText(Boolean.toString(sa.getFakeDepth())); + scale.setText(Param.toStringParam(new Vector2(sa.getScaleX(), sa.getScaleY()))); + rot.setText(Float.toString(sa.getRot())); + tint.setText(sa.getTint() == null ? null : sa.getTint().toString()); + bboxFromRenderer.setText(Boolean.toString(sa.isBboxFromRenderer())); + orgAlign.setText(AlignUtils.getAlign(sa.getRenderer().getOrgAlign())); + + if (e instanceof CharacterActor) { + CharacterActor ca = (CharacterActor) e; + + walkingSpeed.setText(Float.toString(ca.getWalkingSpeed())); + textColor.setText(ca.getTextColor() == null ? null : ca.getTextColor().toString()); + textStyle.setText(ca.getTextStyle()); + talkingTextPos.setText(Param.toStringParam(ca.getTalkingTextPos())); + typePanel.setText(CHARACTER_TYPE_STR); + } else { + typePanel.setText(SPRITE_TYPE_STR); + } + } else { + typePanel.setText(BACKGROUND_TYPE_STR); + } + } else if (e instanceof AnchorActor) { + typePanel.setText(ANCHOR_TYPE_STR); + } else if (e instanceof WalkZoneActor) { + typePanel.setText(WALKZONE_TYPE_STR); + } else if (e instanceof ObstacleActor) { + typePanel.setText(OBSTACLE_TYPE_STR); + } + + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditAnimationDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditAnimationDialog.java new file mode 100644 index 000000000..d83db4803 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditAnimationDialog.java @@ -0,0 +1,492 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextField; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.ChangeEvent; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engine.anim.AnimationDesc; +import com.bladecoder.engine.anim.AtlasAnimationDesc; +import com.bladecoder.engine.anim.SpineAnimationDesc; +import com.bladecoder.engine.anim.Tween; +import com.bladecoder.engine.anim.Tween.Type; +import com.bladecoder.engine.assets.EngineAssetManager; +import com.bladecoder.engine.i18n.I18N; +import com.bladecoder.engine.model.*; +import com.bladecoder.engine.spine.SpineRenderer; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.scneditor.AnimationWidget; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.FilteredSelectBox; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.Arrays; +import java.util.HashMap; + +public class EditAnimationDialog extends EditModelDialog { + + public static final String ANIMATION_TYPES[] = {Tween.Type.NO_REPEAT.toString(), Tween.Type.REPEAT.toString(), + Tween.Type.YOYO.toString(), Tween.Type.REVERSE.toString()}; + + public static final String INFO = "Define sprites and animations"; + + InputPanel source; + InputPanel atlas; + InputPanel id; + InputPanel localizable; + InputPanel repeat; + InputPanel speed; + InputPanel count; + InputPanel in; + InputPanel out; + InputPanel sound; + InputPanel preload; + InputPanel dispose; + + AnimationWidget spriteWidget = new AnimationWidget(this); + + @SuppressWarnings("unchecked") + public EditAnimationDialog(Skin skin, SpriteActor p, AnimationDesc e) { + super(skin); + + setInfo(INFO); + + source = InputPanelFactory.createInputPanel(skin, "Source", + "Select the source where the sprite or animation is defined", new String[0], true); + atlas = InputPanelFactory.createInputPanel(skin, "Atlas", "Select the atlas for the selected Spine skeleton", + getAtlases(), true); + localizable = InputPanelFactory.createInputPanel(skin, "Localizable", + "True if the image is customizable per language.", Param.Type.BOOLEAN, true, "false"); + id = InputPanelFactory.createInputPanel(skin, "ID", "Select the id of the animation", new String[0], true); + repeat = InputPanelFactory.createInputPanel(skin, "Animation type", "Select the type of the animation", + Param.Type.OPTION, true, Tween.Type.NO_REPEAT.toString(), Tween.Type.class.getEnumConstants()); + + speed = InputPanelFactory.createInputPanel(skin, "Speed", "Select the speed of the animation in secods", + Param.Type.FLOAT, true, "1.0"); + count = InputPanelFactory.createInputPanel(skin, "Count", "Select the repeat times. -1 for infinity", + Param.Type.INTEGER, true, "-1"); + in = InputPanelFactory.createInputPanel(skin, "In Dist", + "Select the distance in pixels to add to the actor position when the sprite is displayed", + Param.Type.VECTOR2, false); + out = InputPanelFactory.createInputPanel(skin, "Out Dist", + "Select the distance in pixels to add to the actor position when the sprite is changed", + Param.Type.VECTOR2, false); + sound = InputPanelFactory.createInputPanel(skin, "Sound", + "Select the sound ID that will be played when showing", Param.Type.SOUND, false); + preload = InputPanelFactory.createInputPanel(skin, "Preload", "Preload the animation when the scene is loaded", + Param.Type.BOOLEAN, true, "true"); + dispose = InputPanelFactory.createInputPanel(skin, "Dispose When Played", "Dispose de animation after playing", + Param.Type.BOOLEAN, true, "false"); + + ((SelectBox) repeat.getField()).addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + showHideFieldsDelayCountFields(); + } + }); + + ((FilteredSelectBox) source.getField()).addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + EditorLogger.debug("EditAnimationDialog.setSource():" + source.getText()); + + setSource(); + fillAnimations(); + } + }); + + ((FilteredSelectBox) id.getField()).addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + setAnimation(); + } + }); + + ((FilteredSelectBox) atlas.getField()).addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + setSource(); + fillAnimations(); + } + }); + + ((TextField) speed.getField()).addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + setAnimation(); + } + }); + + setInfoWidget(spriteWidget); + + init(p, e, new InputPanel[]{source, localizable, atlas, id, repeat, speed, count, in, out, sound, preload, + dispose}); + + addSources(); + + // call modelToInputs again to set the correct source + if (e != null) + modelToInputs(); + + setVisible(count, false); + setVisible(atlas, false); + setVisible(localizable, false); + + ActorRenderer renderer = parent.getRenderer(); + if (renderer instanceof ImageRenderer) { + setVisible(localizable, true); + setVisible(speed, false); + setVisible(repeat, false); + setVisible(id, false); + } + + if (e != null) { + source.setText(e.source); + } else { + // If the actor has some animation, set the same source. + HashMap animations = ((AnimationRenderer) p.getRenderer()).getAnimations(); + if (animations.size() > 0) { + source.setText(animations.values().iterator().next().source); + } else { + // set the background source it atlas type + if (p.getRenderer() instanceof AtlasRenderer && p.getScene().getBackgroundAtlas() != null) + source.setText(p.getScene().getBackgroundAtlas()); + } + } + + if (source.getText() != null && !source.getText().isEmpty()) { + setSource(); + + fillAnimations(); + + if (e != null) { + id.setText(e.id); + } + } + } + + private void showHideFieldsDelayCountFields() { + String type = repeat.getText(); + + if (type.equals(Tween.Type.REPEAT.toString()) || type.equals(Tween.Type.YOYO.toString())) { + setVisible(count, true); + } else { + setVisible(count, false); + } + } + + private void setSource() { + AnimationDesc anim = null; + + ActorRenderer renderer = parent.getRenderer(); + String sourceStr = source.getText(); + + if (renderer instanceof SpineRenderer) { + anim = new SpineAnimationDesc(); + + if (spineAtlasExists(sourceStr)) { + ((SpineAnimationDesc) anim).atlas = null; + setVisible(atlas, false); + } else { + if (!atlas.isVisible()) { + setVisible(atlas, true); + } + + ((SpineAnimationDesc) anim).atlas = atlas.getText(); + } + + } else if (renderer instanceof AtlasRenderer) { + anim = new AtlasAnimationDesc(); + } else { + anim = new AnimationDesc(); + } + + anim.source = sourceStr; + anim.count = Tween.INFINITY; + anim.preload = true; + anim.disposeWhenPlayed = false; + + if (renderer instanceof SpineRenderer) { + spriteWidget.setSource(Project.SPINE_RENDERER_STRING, anim); + } else if (renderer instanceof AtlasRenderer) { + spriteWidget.setSource(Project.ATLAS_RENDERER_STRING, anim); + } else if (renderer instanceof ImageRenderer) { + spriteWidget.setSource(Project.IMAGE_RENDERER_STRING, anim); + } + } + + public boolean spineAtlasExists(String source) { + return EngineAssetManager.getInstance() + .assetExists(Ctx.project.getAssetPath() + Project.ATLASES_PATH + "/" + source + ".atlas"); + } + + private void setAnimation() { + String ids = id.getText(); + String type = repeat.getText(); + String speedStr = speed.getText(); + + @SuppressWarnings("unchecked") + FilteredSelectBox cb = (FilteredSelectBox) id.getField(); + + if (e != null || cb.getSelectedIndex() != 0) + spriteWidget.setAnimation(ids, speedStr, Tween.Type.valueOf(type)); + } + + private void fillAnimations() { + @SuppressWarnings("unchecked") + FilteredSelectBox cb = (FilteredSelectBox) id.getField(); + cb.clearItems(); + + // When creating, give option to add all elements + if (e == null) + cb.getItems().add(""); + + String[] ids = spriteWidget.getAnimations(); + for (String s : ids) + cb.getItems().add(s); + + cb.getList().setItems(cb.getItems()); + if (cb.getItems().size > 0) + cb.setSelectedIndex(0); + + cb.invalidateHierarchy(); + + setAnimation(); + } + + String ext; + + private void addSources() { + @SuppressWarnings("unchecked") + FilteredSelectBox cb = (FilteredSelectBox) source.getField(); + String[] src = getSources(); + cb.getItems().clear(); + + for (String s : src) + cb.getItems().add(s); + + cb.getList().setItems(cb.getItems()); + if (cb.getItems().size > 0) + cb.setSelectedIndex(0); + cb.invalidateHierarchy(); + } + + private String[] getSources() { + String path = null; + ActorRenderer renderer = parent.getRenderer(); + + if (renderer instanceof AtlasRenderer) { + path = Ctx.project.getAssetPath() + Project.ATLASES_PATH + "/" + Ctx.project.getResDir(); + ext = EngineAssetManager.ATLAS_EXT; + } else if (renderer instanceof SpineRenderer) { + path = Ctx.project.getAssetPath() + Project.SPINE_PATH; + ext = EngineAssetManager.SPINE_EXT; + } else if (renderer instanceof ImageRenderer) { + path = Ctx.project.getAssetPath() + Project.IMAGE_PATH + "/" + Ctx.project.getResDir(); + ext = ""; + } + + File f = new File(path); + + String[] sources = f.list(new FilenameFilter() { + + @Override + public boolean accept(File arg0, String arg1) { + return arg1.endsWith(ext); + } + }); + + if (sources != null) { + Arrays.sort(sources); + + for (int i = 0; i < sources.length; i++) + sources[i] = sources[i].substring(0, sources[i].length() - ext.length()); + } else { + sources = new String[0]; + } + + return sources; + } + + private String[] getAtlases() { + String path = Ctx.project.getAssetPath() + Project.ATLASES_PATH + "/" + Ctx.project.getResDir(); + + File f = new File(path); + + String[] atlases = f.list(new FilenameFilter() { + + @Override + public boolean accept(File arg0, String arg1) { + return arg1.endsWith(EngineAssetManager.ATLAS_EXT); + } + }); + + if (atlases != null) { + Arrays.sort(atlases); + + for (int i = 0; i < atlases.length; i++) + atlases[i] = atlases[i].substring(0, atlases[i].length() - EngineAssetManager.ATLAS_EXT.length()); + } else { + atlases = new String[0]; + } + + return atlases; + } + + /** + * Override to append all animations if selected. + */ + @Override + protected void ok() { + @SuppressWarnings("unchecked") + FilteredSelectBox cb = (FilteredSelectBox) id.getField(); + + if (e == null && cb.getSelectedIndex() == 0) { + AnimationRenderer renderer = (AnimationRenderer) parent.getRenderer(); + + for (int i = 1; i < cb.getItems().size; i++) { + cb.setSelectedIndex(i); + + if (renderer.getAnimations().get(id.getText()) != null) + continue; + + inputsToModel(true); + // doc.setId(e, cb.getItems().get(i)); + + if (listener != null) + listener.changed(new ChangeEvent(), this); + } + + } else { + super.ok(); + } + } + + @Override + protected void inputsToModel(boolean create) { + + String sourceStr = source.getText(); + AnimationRenderer renderer = (AnimationRenderer) parent.getRenderer(); + + if (create) { + + if (renderer instanceof SpineRenderer) { + e = new SpineAnimationDesc(); + } else if (renderer instanceof AtlasRenderer) { + e = new AtlasAnimationDesc(); + } else { + e = new AnimationDesc(); + } + } else { + HashMap animations = renderer.getAnimations(); + animations.remove(e.id); + + if (e.id.equals(renderer.getInitAnimation())) + renderer.setInitAnimation(null); + } + + if (renderer instanceof SpineRenderer) { + if (spineAtlasExists(sourceStr)) { + ((SpineAnimationDesc) e).atlas = null; + setVisible(atlas, false); + } else { + if (!atlas.isVisible()) { + setVisible(atlas, true); + } + + ((SpineAnimationDesc) e).atlas = atlas.getText(); + } + } + + e.id = id.getText(); + e.sound = sound.getText(); + e.source = sourceStr; + e.count = Integer.parseInt(count.getText()); + e.preload = Boolean.parseBoolean(preload.getText()); + e.disposeWhenPlayed = Boolean.parseBoolean(dispose.getText()); + e.animationType = Type.valueOf(repeat.getText()); + e.inD = Param.parseVector2(in.getText()); + e.outD = Param.parseVector2(out.getText()); + e.duration = Float.parseFloat(speed.getText()); + + ((AnimationRenderer) parent.getRenderer()).addAnimation(e); + + if (renderer instanceof ImageRenderer && Boolean.parseBoolean(localizable.getText()) && e.source != null + && e.source.length() > 0) { + e.source = I18N.PREFIX + e.source; + } + + if (renderer.getInitAnimation() == null) + renderer.setInitAnimation(e.id); + + // TODO UNDO OP + // UndoOp undoOp = new UndoAddElement(doc, e); + // Ctx.project.getUndoStack().add(undoOp); + + Ctx.project.setModified(); + } + + @Override + protected void modelToInputs() { + source.setText(e.source); + + if (atlas.isVisible() && e instanceof SpineAnimationDesc) + atlas.setText(((SpineAnimationDesc) e).atlas); + + id.setText(e.id); + repeat.setText(e.animationType.toString()); + speed.setText(Float.toString(e.duration)); + count.setText(Integer.toString(e.count)); + in.setText(Param.toStringParam(e.inD)); + out.setText(Param.toStringParam(e.outD)); + sound.setText(e.sound); + preload.setText(Boolean.toString(e.preload)); + dispose.setText(Boolean.toString(e.disposeWhenPlayed)); + + showHideFieldsDelayCountFields(); + + ActorRenderer renderer = parent.getRenderer(); + if (renderer instanceof ImageRenderer && e.source != null && e.source.length() > 1 + && e.source.charAt(0) == I18N.PREFIX) { + localizable.setText("true"); + source.setText(e.source.substring(1)); + } + } + + @Override + protected boolean validateFields() { + AnimationRenderer renderer = (AnimationRenderer) parent.getRenderer(); + HashMap animations = renderer.getAnimations(); + + if ((e == null && animations.get(id.getText()) != null) + || (e != null && animations.get(id.getText()) != null && !e.id.equals(id.getText()))) { + id.setError(true); + return false; + } + + return super.validateFields(); + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditChapterDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditChapterDialog.java similarity index 74% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditChapterDialog.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditChapterDialog.java index 209d7c488..a82f90fbe 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditChapterDialog.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditChapterDialog.java @@ -15,7 +15,6 @@ ******************************************************************************/ package com.bladecoder.engineeditor.ui; -import java.io.FileNotFoundException; import java.io.IOException; import java.text.MessageFormat; @@ -28,13 +27,16 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.ChangeEvent; import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.WorldDocument; -import com.bladecoder.engineeditor.ui.components.EditDialog; -import com.bladecoder.engineeditor.ui.components.InputPanel; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.model.Chapter; +import com.bladecoder.engineeditor.ui.panels.EditDialog; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; public class EditChapterDialog extends EditDialog { - private WorldDocument doc; + private Chapter doc; private InputPanel inputId; private String previousId = null; @@ -42,12 +44,12 @@ public class EditChapterDialog extends EditDialog { private ChangeListener listener; - public EditChapterDialog(Skin skin, WorldDocument doc, String chapter) { + public EditChapterDialog(Skin skin, Chapter doc, String chapter) { super("", skin); this.doc = doc; - inputId = new InputPanel(skin, "Chapter ID", "The id of the chapter", + inputId = InputPanelFactory.createInputPanel(skin, "Chapter ID", "The id of the chapter", true); setInfo("An adventure game is composed of chapters. Chapters contains scenes."); @@ -68,15 +70,15 @@ public EditChapterDialog(Skin skin, WorldDocument doc, String chapter) { private void create() { - try { - newId = ((WorldDocument) doc).createChapter(inputId.getText()).getRootAttr("id"); - } catch (FileNotFoundException | TransformerException - | ParserConfigurationException e) { + try { + newId = doc.createChapter(inputId.getText()); + } catch (TransformerException + | ParserConfigurationException | IOException e) { String msg = "Something went wrong while creating the chapter.\n\n" + e.getClass().getSimpleName() + " - " + e.getMessage(); - Ctx.msg.show(getStage(), msg, 2); + Message.showMsg(getStage(), msg, 2); - e.printStackTrace(); + EditorLogger.printStackTrace(e); } } @@ -86,19 +88,19 @@ private void renameChapter() { try { // save selected chapter if renamed chapter is the selected chapter - if(previousId.equals(Ctx.project.getSelectedChapter())) { - Ctx.project.getSelectedChapter().save(); + if(previousId.equals(Ctx.project.getChapter().getId())) { + Ctx.project.getChapter().save(); } - ((WorldDocument) doc).renameChapter(previousId, newId); + doc.renameChapter(previousId, newId); // Reload chapter if renamed chapter is the selected chapter - if(previousId.equals(Ctx.project.getSelectedChapter())) { + if(previousId.equals(Ctx.project.getChapter().getId())) { Ctx.project.loadChapter(newId); } // sets the init chapter - if(previousId.equals(Ctx.project.getWorld().getInitChapter())) { + if(previousId.equals(doc.getInitChapter())) { Ctx.project.getWorld().setInitChapter(newId); } @@ -109,9 +111,9 @@ private void renameChapter() { + e1.getClass().getSimpleName() + " - " + e1.getMessage(); - Ctx.msg.show(getStage(), msg, 3); + Message.showMsg(getStage(), msg, 3); - e1.printStackTrace(); + EditorLogger.printStackTrace(e1); } } } diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditDialogDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditDialogDialog.java new file mode 100644 index 000000000..704baf970 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditDialogDialog.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.bladecoder.engine.model.CharacterActor; +import com.bladecoder.engine.model.Dialog; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.ElementUtils; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; + +public class EditDialogDialog extends EditModelDialog { + public static final String INFO = "[RED]DEPRECATED:[]\nActors can have several dialogs defined. Dialogs have a list of options to choose. This is the legacy option to create simple dialogs, for more complex dialogs use the *Ink* language."; + + private InputPanel id; + + public EditDialogDialog(Skin skin, CharacterActor parent, Dialog e) { + super(skin); + + id = InputPanelFactory.createInputPanel(skin, "Dialog ID", "Select the dialog id to create.", true); + + setInfo(INFO); + + init(parent, e, new InputPanel[] { id }); + } + + @Override + protected void inputsToModel(boolean create) { + + if (create) { + e = new Dialog(); + } else { + parent.getDialogs().remove(e.getId()); + } + + if (parent.getDialogs() != null) + e.setId(ElementUtils.getCheckedId(id.getText(), parent.getDialogs().keySet().toArray(new String[0]))); + else + e.setId(id.getText()); + + parent.addDialog(e); + + // TODO UNDO OP +// UndoOp undoOp = new UndoAddElement(doc, e); +// Ctx.project.getUndoStack().add(undoOp); + + Ctx.project.setModified(); + } + + @Override + protected void modelToInputs() { + id.setText(e.getId()); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditInkDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditInkDialog.java new file mode 100644 index 000000000..ec4057d8c --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditInkDialog.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.Arrays; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.bladecoder.engine.assets.EngineAssetManager; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.EditDialog; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; + +public class EditInkDialog extends EditDialog { + + private InputPanel inkStory; + + public EditInkDialog(Skin skin) { + super("", skin); + + inkStory = InputPanelFactory.createInputPanel(skin, "Ink Story", "Ink story file for this chapter", + getInkFiles(), false); + + setTitle("SET INK STORY FILE"); + setInfo("Each chapter have its own ink story file.\n\nStories are compiled Ink files with the '.ink.json' extension in the 'assets/model' folder."); + + addInputPanel(inkStory); + + inkStory.setText(Ctx.project.getWorld().getInkManager().getStoryName()); + } + + @Override + protected boolean validateFields() { + return inkStory.validateField(); + } + + @Override + protected void ok() { + Ctx.project.getWorld().getInkManager().setStoryName(inkStory.getText()); + Ctx.project.setModified(); + } + + private String[] getInkFiles() { + String path = Ctx.project.getAssetPath() + Project.MODEL_PATH; + + File f = new File(path); + + String inkFiles[] = f.list(new FilenameFilter() { + + @Override + public boolean accept(File arg0, String arg1) { + if (arg1.endsWith(EngineAssetManager.INK_EXT)) + return true; + + return false; + } + }); + + if (inkFiles == null) + inkFiles = new String[0]; + + for (int i = 0; i < inkFiles.length; i++) + inkFiles[i] = inkFiles[i].substring(0, inkFiles[i].length() - EngineAssetManager.INK_EXT.length()); + + Arrays.sort(inkFiles); + + return inkFiles; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditLayerDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditLayerDialog.java new file mode 100644 index 000000000..39dd62ab0 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditLayerDialog.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.SceneLayer; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; + +public class EditLayerDialog extends EditModelDialog { + + private InputPanel name; + private InputPanel visible; + private InputPanel dynamic; + private InputPanel parallax; + + public EditLayerDialog(Skin skin, Scene parent, SceneLayer e) { + super(skin); + + name = InputPanelFactory.createInputPanel(skin, "Layer Name", "The name of the layer", true); + visible = InputPanelFactory.createInputPanel(skin, "Visible", "Layer Visibility", Param.Type.BOOLEAN, true, "true"); + dynamic = InputPanelFactory.createInputPanel(skin, "Dynamic", "True for actor reordering based in y position", Param.Type.BOOLEAN, true, "false"); + parallax = InputPanelFactory.createInputPanel(skin, "Parallax Factor", "The multiplier factor for parallax effect", Param.Type.FLOAT, true, "1.0"); + + setInfo("Scenes can have a list of layers. Actors are added to a specific layer to control the draw order"); + + init(parent, e, new InputPanel[]{name, visible, dynamic, parallax}); + } + + @Override + protected void inputsToModel(boolean create) { + + if (create) { + e = new SceneLayer(); + } + + // if the name is changed. Change all actor layer name. + if (!create && !e.getName().equals(name.getText())) { + for (SceneLayer l : parent.getLayers()) { + for (int i = 0; i < l.getActors().size(); i++) { + if (l.getActors().get(i).getLayer().equals(e.getName())) { + l.getActors().get(i).setLayer(name.getText()); + } + } + } + } + + e.setName(name.getText()); + e.setVisible(Boolean.parseBoolean(visible.getText())); + e.setDynamic(Boolean.parseBoolean(dynamic.getText())); + e.setParallaxMultiplier(Float.parseFloat(parallax.getText())); + + if (create) { + parent.getLayers().add(e); + } + + // TODO UNDO OP +// UndoOp undoOp = new UndoAddElement(doc, e); +// Ctx.project.getUndoStack().add(undoOp); + + Ctx.project.setModified(); + } + + @Override + protected void modelToInputs() { + name.setText(e.getName()); + visible.setText(Boolean.toString(e.isVisible())); + dynamic.setText(Boolean.toString(e.isDynamic())); + parallax.setText(Float.toString(e.getParallaxMultiplier())); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditOptionDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditOptionDialog.java new file mode 100644 index 000000000..03922020a --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditOptionDialog.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engine.actions.Param.Type; +import com.bladecoder.engine.i18n.I18N; +import com.bladecoder.engine.model.CharacterActor; +import com.bladecoder.engine.model.Dialog; +import com.bladecoder.engine.model.DialogOption; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; + +public class EditOptionDialog extends EditModelDialog { + + private InputPanel text; + private InputPanel voice; + private InputPanel responseText; + private InputPanel responseVoice; + private InputPanel verb; + private InputPanel next; + private InputPanel visible; + private InputPanel once; + private int pos; + + + public EditOptionDialog(Skin skin, Dialog parent, DialogOption e, int pos) { + super(skin); + + this.pos = e == null ? pos + 1 : pos; + + text = InputPanelFactory.createInputPanel(skin, "Text", "The sentence of the dialog to say by the player", + Type.SMALL_TEXT, true); + voice = InputPanelFactory.createInputPanel(skin, "Voice", "The voice filename for the player lines", + Type.VOICE, false); + responseText = InputPanelFactory.createInputPanel(skin, "Response Text", "The response said by the character", + Type.TEXT, false); + responseVoice = InputPanelFactory.createInputPanel(skin, "Response Voice", "The voice filename for the response lines", + Type.VOICE, false); + verb = InputPanelFactory.createInputPanel(skin, "Verb", "The verb to execute when choosing this option"); + next = InputPanelFactory.createInputPanel(skin, "Next Dialog", + "The next dialog to show when this option is selected", + getActorDialogs((CharacterActor) Ctx.project.getSelectedActor()), false); + visible = InputPanelFactory.createInputPanel(skin, "Visible", "The visibility", Param.Type.BOOLEAN, true, "true"); + once = InputPanelFactory.createInputPanel(skin, "Once", "When true, the option is hidden after selection", + Param.Type.BOOLEAN, false); + + setInfo("A dialog is composed of an option tree. Each option is a dialog sentence that the user can choose to say"); + + text.getCell(text.getField()).fillX(); + responseText.getCell(responseText.getField()).fillX(); + + init(parent, e, new InputPanel[] { text, responseText, voice, responseVoice, verb, next, visible, once }); + } + + @Override + protected void inputsToModel(boolean create) { + + if (create) { + e = new DialogOption(); +// parent.addOption(e); + + parent.getOptions().add(pos, e); + } + + String key = e.getText(); + + if (key == null || key.isEmpty() || key.charAt(0) != I18N.PREFIX) + key = Ctx.project.getI18N().genKey(Ctx.project.getSelectedScene().getId(), Ctx.project.getSelectedActor().getId(), parent.getId(), pos, "text"); + + Ctx.project.getI18N().setTranslation(key, text.getText()); + + if (text.getText() != null && !text.getText().isEmpty()) + e.setText(key); + else + e.setText(null); + + String responseKey = e.getResponseText(); + + if (responseKey == null || responseKey.isEmpty() || responseKey.charAt(0) != I18N.PREFIX) + responseKey = Ctx.project.getI18N().genKey(Ctx.project.getSelectedScene().getId(), Ctx.project.getSelectedActor().getId(), parent.getId(), pos, "responseText"); + + Ctx.project.getI18N().setTranslation(responseKey, responseText.getText()); + + if (responseText.getText() != null && !responseText.getText().isEmpty()) + e.setResponseText(responseKey); + else + e.setResponseText(null); + + e.setVerbId(verb.getText()); + e.setNext(next.getText()); + e.setVisible(Boolean.parseBoolean(visible.getText())); + e.setOnce(Boolean.parseBoolean(once.getText())); + e.setVoiceId(voice.getText()); + e.setResponseVoiceId(responseVoice.getText()); + + + // TODO UNDO OP + // UndoOp undoOp = new UndoAddElement(doc, e); + // Ctx.project.getUndoStack().add(undoOp); + + Ctx.project.setModified(); + } + + @Override + protected void modelToInputs() { + text.setText(Ctx.project.translate(e.getText())); + + + responseText.setText(Ctx.project.translate(e.getResponseText())); + + verb.setText(e.getVerbId()); + next.setText(e.getNext()); + + visible.setText(Boolean.toString(e.isVisible())); + once.setText(Boolean.toString(e.isOnce())); + voice.setText(e.getVoiceId()); + responseVoice.setText(e.getResponseVoiceId()); + } + + private String[] getActorDialogs(CharacterActor actor) { + Dialog[] array = actor.getDialogs().values().toArray(new Dialog[0]); + + String[] result = new String[array.length + 1]; + result[0] = "this"; + + for (int i = 0; i < array.length; i++) { + result[i + 1] = array[i].getId(); + } + + return result; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditSceneDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditSceneDialog.java new file mode 100644 index 000000000..79ebdd201 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditSceneDialog.java @@ -0,0 +1,308 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Container; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.Scaling; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engine.actions.Param.Type; +import com.bladecoder.engine.model.MusicDesc; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.SceneLayer; +import com.bladecoder.engine.model.World; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.ElementUtils; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.FilteredSelectBox; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; +import com.bladecoder.engineeditor.undo.UndoCreateScene; +import com.bladecoder.engineeditor.undo.UndoEditScene; + +public class EditSceneDialog extends EditModelDialog { + + public static final String INFO = "An adventure is composed of many scenes (rooms/screens).\n" + + "Inside a scene, there are actors and a 'player'.\nThe player/user can interact with actors throught 'verbs'."; + + private Image bgImage; + private Container infoContainer; + private TextureAtlas atlas; + + private InputPanel id; + private InputPanel backgroundAtlas; + private InputPanel backgroundRegion; + private InputPanel depthVector; + private InputPanel state; + private InputPanel music; + private InputPanel loopMusic; + private InputPanel volumeMusic; + private InputPanel initialMusicDelay; + private InputPanel repeatMusicDelay; + private InputPanel stopWhenLeaving; + private InputPanel sceneSize; + private InputPanel walkzone; + + @SuppressWarnings("unchecked") + public EditSceneDialog(Skin skin, World parent, Scene e) { + + super(skin); + + id = InputPanelFactory.createInputPanel(skin, "Scene ID", "The ID is mandatory for scenes.", true); + backgroundAtlas = InputPanelFactory.createInputPanel(skin, "Background Atlas", + "The atlas where the background for the scene is located", Type.ATLAS_ASSET, false); + backgroundRegion = InputPanelFactory.createInputPanel(skin, "Background Region Id", + "The region id for the background.", new String[0], false); +// depthVector = InputPanelFactory.createInputPanel(skin, "Depth Vector", +// "X: the actor 'y' position for a 0.0 scale, Y: the actor 'y' position for a 1.0 scale.", +// Param.Type.VECTOR2, false); + + depthVector = InputPanelFactory.createInputPanel(skin, "Fake depth", + "Change actor scale based in the 'y' axis position.", Param.Type.BOOLEAN, true, "false"); + + state = InputPanelFactory.createInputPanel(skin, "State", "The initial state for the scene.", false); + music = InputPanelFactory.createInputPanel(skin, "Music Filename", "The music for the scene", Type.MUSIC_ASSET, + false); + loopMusic = InputPanelFactory.createInputPanel(skin, "Loop Music", "If the music is playing in looping", + Param.Type.BOOLEAN, true, "true"); + volumeMusic = InputPanelFactory.createInputPanel(skin, "Music Volume", + "The volume of the music. Value is between 0 and 1.", Param.Type.FLOAT, true, "1"); + initialMusicDelay = InputPanelFactory.createInputPanel(skin, "Initial music delay", + "The time to wait before playing", Param.Type.FLOAT, true, "0"); + repeatMusicDelay = InputPanelFactory.createInputPanel(skin, "Repeat music delay", + "The time to wait before repetitions", Param.Type.FLOAT, true, "-1"); + stopWhenLeaving = InputPanelFactory.createInputPanel(skin, "Stop music when leaving", + "Stops the music when leaving the current scene.", Param.Type.BOOLEAN, true, "true"); + + sceneSize = InputPanelFactory.createInputPanel(skin, "Scene Dimension", + "Sets the size of the scene. If empty, the background image size is used as the scene dimension.", + Param.Type.DIMENSION, false); + + walkzone = InputPanelFactory.createInputPanel(skin, "Walkzone", "The initial walkzone.", Type.WALKZONE_ACTOR, + false); + + bgImage = new Image(); + bgImage.setScaling(Scaling.fit); + infoContainer = new Container(bgImage); + setInfo(INFO); + + ((FilteredSelectBox) backgroundAtlas.getField()).addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + try { + fillBGRegions(backgroundAtlas, backgroundRegion); + } catch (Exception e) { + EditorLogger.error("Error loading regions from selected atlas: " + backgroundAtlas.getText() + "." + + backgroundRegion.getText()); + } + } + }); + + ((FilteredSelectBox) backgroundRegion.getField()).addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + showBgImage(backgroundRegion.getText()); + } + }); + + try { + fillBGRegions(backgroundAtlas, backgroundRegion); + } catch (Exception e2) { + EditorLogger.error("Error loading regions from selected atlas: " + backgroundAtlas.getText() + "." + + backgroundRegion.getText()); + } + + init(parent, e, new InputPanel[] { id, backgroundAtlas, backgroundRegion, depthVector, state, sceneSize, music, + loopMusic, volumeMusic, initialMusicDelay, repeatMusicDelay, stopWhenLeaving, walkzone }); + } + + private void showBgImage(String r) { + if (atlas == null || r == null) + return; + + bgImage.setDrawable(new TextureRegionDrawable(atlas.findRegion(r))); + + infoContainer.prefWidth(250); + infoContainer.prefHeight(250); + setInfoWidget(infoContainer); + } + + private void fillBGRegions(InputPanel atlasInput, InputPanel regionInput) { + @SuppressWarnings("unchecked") + FilteredSelectBox cb = (FilteredSelectBox) regionInput.getField(); + + // cb.clearItems(); + cb.getItems().clear(); + + if (atlas != null) { + atlas.dispose(); + atlas = null; + } + + if (backgroundAtlas.getText().isEmpty()) { + setInfoWidget(new Label(INFO, getSkin())); + return; + } + + atlas = new TextureAtlas(Gdx.files.absolute(Ctx.project.getAssetPath() + Project.ATLASES_PATH + "/" + + Ctx.project.getResDir() + "/" + atlasInput.getText() + ".atlas")); + + Array regions = atlas.getRegions(); + + for (AtlasRegion r : regions) + if (cb.getItems().indexOf(r.name, false) == -1) + cb.getItems().add(r.name); + + cb.getList().setItems(cb.getItems()); + if (cb.getItems().size > 0) + cb.setSelectedIndex(0); + + cb.invalidateHierarchy(); + + showBgImage(regionInput.getText()); + } + + @Override + protected void inputsToModel(boolean create) { + + if (create) { + e = new Scene(Ctx.project.getWorld()); + + // CREATE DEFAULT LAYERS: BG, DYNAMIC, FG + SceneLayer l = new SceneLayer(); + l.setName("foreground"); + l.setVisible(true); + l.setDynamic(false); + e.addLayer(l); + + l = new SceneLayer(); + l.setName("dynamic"); + l.setVisible(true); + l.setDynamic(true); + e.addLayer(l); + + l = new SceneLayer(); + l.setName("background"); + l.setVisible(true); + l.setDynamic(false); + e.addLayer(l); + } else { + parent.getScenes().remove(e.getId()); + } + + e.setId(ElementUtils.getCheckedId(id.getText(), + Ctx.project.getWorld().getScenes().keySet().toArray(new String[0]))); + + e.setBackgroundAtlas(backgroundAtlas.getText()); + e.setBackgroundRegionId(backgroundRegion.getText()); + + boolean dv = Boolean.parseBoolean(depthVector.getText()); + + if (dv == true && e.getDepthVector() == null) { // create depth vector + e.setDepthVector(new Vector2(Ctx.project.getWorld().getHeight(), 0)); + } else if (dv == false && e.getDepthVector() != null) { // Remove depth vector + e.setDepthVector(null); + } + + e.setState(state.getText()); + + MusicDesc md = null; + + if (music.getText() != null) { + md = new MusicDesc(); + + md.setFilename(music.getText()); + md.setLoop(Boolean.parseBoolean(loopMusic.getText())); + md.setVolume(Float.parseFloat(volumeMusic.getText())); + md.setInitialDelay(Float.parseFloat(initialMusicDelay.getText())); + md.setRepeatDelay(Float.parseFloat(repeatMusicDelay.getText())); + md.setStopWhenLeaving(Boolean.parseBoolean(stopWhenLeaving.getText())); + } + + e.setMusicDesc(md); + + e.setSceneSize(Param.parseVector2(sceneSize.getText())); + + e.setWalkZone(walkzone.getText()); + + parent.addScene(e); + + if (parent.getScenes().size() == 1) + parent.setInitScene(e.getId()); + + // UNDO OP + if (create) { + Ctx.project.getUndoStack().add(new UndoCreateScene(e)); + } else { + Ctx.project.getUndoStack().add(new UndoEditScene(e)); + } + + Ctx.project.setModified(this, Project.NOTIFY_ELEMENT_CREATED, null, e); + } + + @Override + protected void modelToInputs() { + + id.setText(e.getId()); + backgroundAtlas.setText(e.getBackgroundAtlas()); + backgroundRegion.setText(e.getBackgroundRegionId()); + + if (e.getDepthVector() != null) + depthVector.setText("true"); + else + depthVector.setText("false"); + + state.setText(e.getState()); + + MusicDesc md = e.getMusicDesc(); + + if (md != null) { + music.setText(md.getFilename()); + loopMusic.setText(Boolean.toString(md.isLoop())); + volumeMusic.setText(Float.toString(md.getVolume())); + initialMusicDelay.setText(Float.toString(md.getInitialDelay())); + repeatMusicDelay.setText(Float.toString(md.getRepeatDelay())); + stopWhenLeaving.setText(Boolean.toString(md.isStopWhenLeaving())); + } + + if (e.getSceneSize() != null) + sceneSize.setText(Param.toStringParam(e.getSceneSize())); + + walkzone.setText(e.getWalkZone()); + } + + @Override + protected void result(Object object) { + if (atlas != null) { + atlas.dispose(); + } + + super.result(object); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditSoundDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditSoundDialog.java new file mode 100644 index 000000000..67b7703e6 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditSoundDialog.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.util.HashMap; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.audio.Sound; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engine.model.SoundDesc; +import com.bladecoder.engine.model.World; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.ElementUtils; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.common.ModelTools; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; +import com.bladecoder.engineeditor.undo.UndoCreateSound; + +public class EditSoundDialog extends EditModelDialog { + + private InputPanel id; + private InputPanel filename; + private InputPanel loop; + private InputPanel volume; + private InputPanel pan; + private InputPanel pitch; + private InputPanel preload; + + private Sound s = null; + + public EditSoundDialog(Skin skin, World parent, SoundDesc e) { + super(skin); + + id = InputPanelFactory.createInputPanel(skin, "Sound ID", "The id of the sound", true); + filename = InputPanelFactory.createInputPanel(skin, "Filename", "Filename of the sound", + ModelTools.getSoundList(), true); + loop = InputPanelFactory.createInputPanel(skin, "Loop", "True if the sound is looping", Param.Type.BOOLEAN, + true, "false"); + volume = InputPanelFactory.createInputPanel(skin, "Volume", "Select the volume between 0 and 1", + Param.Type.FLOAT, true, "1.0"); + pan = InputPanelFactory.createInputPanel(skin, "Pan", + "Panning in the range -1 (full left) to 1 (full right). 0 is center position", Param.Type.FLOAT, true, + "0.0"); + pitch = InputPanelFactory.createInputPanel(skin, "Pitch", + "The pitch multiplier, 1 == default, >1 == faster, <1 == slower, the value has to be between 0.5 and 2.0", + Param.Type.FLOAT, true, "1.0"); + preload = InputPanelFactory.createInputPanel(skin, "Preload", + "True if the sound has to be loaded when the scene is loaded.", Param.Type.BOOLEAN, true, "true"); + + setInfo("Actors can have a list of sounds that can be associated to Sprites or played with the 'sound' action"); + + init(parent, e, new InputPanel[] { id, filename, loop, volume, pan, pitch, preload }); + + TextButton playButton = new TextButton("Play", skin, "no-toggled"); + + playButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + if (s != null) { + s.dispose(); + s = null; + } + + if (filename.getText() != null && !filename.getText().isEmpty()) { + try { + s = Gdx.audio.newSound( + new FileHandle( + Ctx.project.getAssetPath() + Project.SOUND_PATH + "/" + filename.getText())); + + s.play(Float.parseFloat(volume.getText()), Float.parseFloat(pitch.getText()), + Float.parseFloat(pan.getText())); + } catch (Exception e) { + Message.showMsg(getStage(), "Could not play sound: " + e.getMessage(), 4); + } + } + + } + }); + + Table bt = getButtonTable(); + bt.add(playButton); + } + + @Override + protected void inputsToModel(boolean create) { + + if (create) { + e = new SoundDesc(); + + // UNDO OP + Ctx.project.getUndoStack().add(new UndoCreateSound(e)); + } else { + HashMap sounds = parent.getSounds(); + sounds.remove(e.getId()); + } + + String checkedId = parent.getSounds() == null ? id.getText() + : ElementUtils.getCheckedId(id.getText(), + parent.getSounds().keySet().toArray(new String[parent.getSounds().size()])); + + e.setId(checkedId); + e.setFilename(filename.getText()); + e.setLoop(Boolean.parseBoolean(loop.getText())); + e.setVolume(Float.parseFloat(volume.getText())); + e.setPan(Float.parseFloat(pan.getText())); + e.setPitch(Float.parseFloat(pitch.getText())); + e.setPreload(Boolean.parseBoolean(preload.getText())); + + parent.getSounds().put(e.getId(), e); + + Ctx.project.setModified(); + } + + @Override + protected void modelToInputs() { + id.setText(e.getId()); + filename.setText(e.getFilename()); + loop.setText(Boolean.toString(e.getLoop())); + volume.setText(Float.toString(e.getVolume())); + pan.setText(Float.toString(e.getPan())); + pitch.setText(Float.toString(e.getPitch())); + preload.setText(Boolean.toString(e.isPreload())); + } + + @Override + protected void result(Object object) { + if (s != null) { + s.dispose(); + s = null; + } + + super.result(object); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditVerbDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditVerbDialog.java new file mode 100644 index 000000000..bdc6e6653 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/EditVerbDialog.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.util.HashMap; + +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextField; +import com.badlogic.gdx.scenes.scene2d.ui.TextField.TextFieldListener; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.bladecoder.engine.actions.Param.Type; +import com.bladecoder.engine.model.Verb; +import com.bladecoder.engine.model.VerbManager; +import com.bladecoder.engine.util.ActionUtils; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.EditableSelectBox; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; +import com.bladecoder.engineeditor.ui.panels.OptionsInputPanel; +import com.bladecoder.engineeditor.ui.panels.ScopePanel; + +public class EditVerbDialog extends EditModelDialog { + private static final String VERBS[] = { "lookat", "pickup", "talkto", "use", "leave", "action", "enter", "exit" }; + + private static final String SCENE_VERBS[] = { "init", "test" }; + + private static final String DEFAULT_DESC = "Verbs are used to create the game interaction. Select or write the verb to create"; + private static final String CUSTOM_VERB_DESC = "User defined verbs can be called\n from dialogs or inside other verbs using \nthe 'run_verb' action"; + + private static final String VERBS_INFO[] = { + "Called when the user clicks\n in the 'lookat' icon\n over a object in scene", + "Called when the user clicks\n in the 'pickup' icon\n over a object in scene", + "Called when the user clicks\n in the 'talkto' icon\n over a character in scene", + "Called when the user drags and drops\n an inventory object over\n an object in scene or in inventory", + "Called when the user clicks\n in an exit zone in scene", + "Called when the user clicks in the actor. Useful for one click actions. Doesn't show the verb menu.", + "Called when the player enters\n in the object bounding box", + "Called when the player exits\n the object bounding box" }; + + private static final String SCENE_VERBS_INFO[] = { "Called every time\n that the scene is loaded", + "Called every time\n that the scene is loaded in test mode.\n'test' verb is called before the 'init' verb" }; + + private InputPanel id; + private InputPanel state; + private InputPanel target; + private InputPanel icon; + + private String scope; + + public EditVerbDialog(Skin skin, String scope, VerbManager parentElement, Verb e) { + super(skin); + + this.scope = scope; + + id = InputPanelFactory.createInputPanel(skin, "Verb ID", "Select the verb to create.", Type.EDITABLE_OPTION, + true, "", ScopePanel.SCENE_SCOPE.equals(scope) ? SCENE_VERBS : VERBS); + state = InputPanelFactory.createInputPanel(skin, "State", "Select the state."); + target = InputPanelFactory.createInputPanel(skin, "Target BaseActor", + "Select the target actor id for the 'use' verb."); + + icon = InputPanelFactory.createInputPanel(skin, "UI Icon", + "The icon that will be showed in the ui for selecting the verb."); + + if (ScopePanel.SCENE_SCOPE.equals(scope)) + setInfo(SCENE_VERBS_INFO[0]); + else + setInfo(VERBS_INFO[0]); + + id.getField().addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + updateDesc(); + } + + }); + + ((EditableSelectBox) id.getField()).getInput().setTextFieldListener(new TextFieldListener() { + @Override + public void keyTyped(TextField actor, char c) { + updateDesc(); + } + }); + + init(parentElement, e, new InputPanel[] { id, state, target, icon }); + + setVisible(target, false); + + if (e != null) { + String id = e.getId(); + + if (id.equals("use")) + setVisible(target, true); + } + + updateDesc(); + } + + private void updateDesc() { + String idStr = id.getText(); + int i = ((OptionsInputPanel) id).getSelectedIndex(); + + if (i == -1) { + if (idStr != null && idStr.isEmpty()) + setInfo(DEFAULT_DESC); + else + setInfo(CUSTOM_VERB_DESC); + } else { + if (ScopePanel.SCENE_SCOPE.equals(scope)) { + setInfo(SCENE_VERBS_INFO[i]); + } else { + setInfo(VERBS_INFO[i]); + } + } + + if (idStr != null && idStr.equals("use")) + setVisible(target, true); + else + setVisible(target, false); + + pack(); + } + + @Override + protected void inputsToModel(boolean create) { + + if (create) { + e = new Verb(); + } else { + HashMap verbs = parent.getVerbs(); + verbs.remove(e.getHashKey()); + } + + e.setId(id.getText()); + e.setState(state.getText()); + e.setTarget(target.getText()); + e.setIcon(icon.getText()); + + parent.addVerb(e); + + // TODO UNDO OP +// UndoOp undoOp = new UndoAddElement(doc, e); +// Ctx.project.getUndoStack().add(undoOp); + + Ctx.project.setModified(); + } + + @Override + protected void modelToInputs() { + id.setText(e.getId()); + state.setText(e.getState()); + target.setText(e.getTarget()); + icon.setText(e.getIcon()); + } + + @Override + protected boolean validateFields() { + + if (!super.validateFields()) + return false; + + Verb verb = parent.getVerb(id.getText(), state.getText(), target.getText()); + + if (verb == null) + return true; + + boolean sameParams = verb.getId().equals(id.getText()) + && ActionUtils.compareNullStr(verb.getState(), state.getText()) + && ActionUtils.compareNullStr(verb.getTarget(), target.getText()); + + if (sameParams && (e == null || verb != e)) { + id.setError(true); + return false; + } + + return true; + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ActionList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/LayerList.java similarity index 50% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ActionList.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/LayerList.java index 4fe4d830a..78c15e07c 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ActionList.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/LayerList.java @@ -15,32 +15,42 @@ ******************************************************************************/ package com.bladecoder.engineeditor.ui; -import java.text.MessageFormat; - -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; - +import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.utils.Array; -import com.bladecoder.engineeditor.ui.components.CellRenderer; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.ElementList; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.SceneLayer; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.ui.panels.CellRenderer; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.ModelList; + +public class LayerList extends ModelList { -public class ActionList extends ElementList { - Skin skin; - private ImageButton upBtn; private ImageButton downBtn; + private ImageButton visibilityBtn; + + public LayerList(Skin skin) { + super(skin, false); - public ActionList(Skin skin) { - super(skin, true); - this.skin = skin; - - setCellRenderer(listCellRenderer); + list.setCellRenderer(listCellRenderer); + + visibilityBtn = new ImageButton(skin); + toolbar.addToolBarButton(visibilityBtn, "ic_eye", "Toggle Visibility", "Toggle Visibility"); + + visibilityBtn.setDisabled(false); + + visibilityBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + toggleVisibility(); + } + }); upBtn = new ImageButton(skin); downBtn = new ImageButton(skin); @@ -62,14 +72,13 @@ public void changed(ChangeEvent event, Actor actor) { }); upBtn.addListener(new ChangeListener() { - + @Override public void changed(ChangeEvent event, Actor actor) { up(); } }); - - + downBtn.addListener(new ChangeListener() { @Override public void changed(ChangeEvent event, Actor actor) { @@ -78,37 +87,16 @@ public void changed(ChangeEvent event, Actor actor) { }); } - @Override - protected EditElementDialog getEditElementDialogInstance(Element e) { - return new EditActionDialog(skin, doc, parent, e); - } - - @Override - protected void create() { - EditElementDialog dialog = getEditElementDialogInstance(null); - dialog.show(getStage()); - dialog.setListener(new ChangeListener() { - @Override - public void changed(ChangeEvent event, Actor actor) { - int pos = list.getSelectedIndex() + 1; - - Element e2 = null; - - if(pos!=0 && pos < list.getItems().size) - e2 = list.getItems().get(pos); - - Element e = ((EditElementDialog)actor).getElement(); - list.getItems().insert(pos, e); - - Node parent = e.getParentNode(); - parent.removeChild(e); - parent.insertBefore(e, e2); - - list.setSelectedIndex(pos); - - list.invalidateHierarchy(); - } - }); + private void toggleVisibility() { + + SceneLayer e = list.getSelected(); + + if (e == null) + return; + + e.setVisible(!e.isVisible()); + + Ctx.project.setModified(); } private void up() { @@ -117,89 +105,130 @@ private void up() { if (pos == -1 || pos == 0) return; - Array items = list.getItems(); - Element e = items.get(pos); - Element e2 = items.get(pos - 1); + Array items = list.getItems(); + SceneLayer e = items.get(pos); + SceneLayer e2 = items.get(pos - 1); - Node parent = e.getParentNode(); - parent.removeChild(e); - parent.insertBefore(e, e2); + parent.getLayers().set(pos, e2); + parent.getLayers().set(pos - 1, e); items.removeIndex(pos); - items.insert( pos - 1, e); + items.insert(pos - 1, e); list.setSelectedIndex(pos - 1); upBtn.setDisabled(list.getSelectedIndex() == 0); downBtn.setDisabled(list.getSelectedIndex() == list.getItems().size - 1); - doc.setModified(e); + Ctx.project.setModified(); } private void down() { int pos = list.getSelectedIndex(); - Array items = list.getItems(); + Array items = list.getItems(); if (pos == -1 || pos == items.size - 1) return; - Element e = items.get(pos); - Element e2 = pos + 2 < items.size ? items.get(pos + 2) : null; + SceneLayer e = items.get(pos); + SceneLayer e2 = pos + 1 < items.size ? items.get(pos + 1) : null; - Node parent = e.getParentNode(); - parent.removeChild(e); - parent.insertBefore(e, e2); + parent.getLayers().set(pos, e2); + parent.getLayers().set(pos + 1, e); - items.removeIndex(pos); items.insert(pos + 1, e); list.setSelectedIndex(pos + 1); upBtn.setDisabled(list.getSelectedIndex() == 0); downBtn.setDisabled(list.getSelectedIndex() == list.getItems().size - 1); - doc.setModified(e); + Ctx.project.setModified(); + } + + @Override + protected EditModelDialog getEditElementDialogInstance(SceneLayer l) { + return new EditLayerDialog(skin, parent, l); + } + + @Override + protected void delete() { + + int pos = list.getSelectedIndex(); + + if (pos == -1) + return; + + if (list.getItems().size < 2) { + String msg = "The layer will not be deleted, at least one layer must exist"; + Message.showMsg(getStage(), msg, 3); + + return; + } + + SceneLayer e = list.getSelected(); + + if (e.getActors().isEmpty()) { + SceneLayer l = removeSelected(); + parent.getLayers().remove(l); + Ctx.project.setModified(); + } else { + String msg = "The layer is not empty."; + Message.showMsg(getStage(), msg, 3); + } + + } + + @Override + protected void copy() { + // TODO + } + + @Override + protected void paste() { + // TODO } // ------------------------------------------------------------------------- // ListCellRenderer // ------------------------------------------------------------------------- - private final CellRenderer listCellRenderer = new CellRenderer() { + private static final CellRenderer listCellRenderer = new CellRenderer() { @Override - protected String getCellTitle(Element e) { - String id = e.getAttribute("class").isEmpty()?e.getAttribute("action_name"): e.getAttribute("class"); - - String actor = e.getAttribute("actor"); - - if (!actor.isEmpty()) - id = MessageFormat.format("{1}.{0}", id, actor); - - return id; + protected String getCellTitle(SceneLayer l) { + return l.getName(); } @Override - protected String getCellSubTitle(Element e) { - StringBuilder sb = new StringBuilder(); + protected String getCellSubTitle(SceneLayer l) { - NamedNodeMap attr = e.getAttributes(); + StringBuilder sb = new StringBuilder(); - for (int i = 0; i < attr.getLength(); i++) { - Node n = attr.item(i); - String name = n.getNodeName(); + sb.append("dynamic: ").append(l.isDynamic()); + sb.append(" visible: ").append(l.isVisible()); + sb.append(" parallax: ").append(l.getParallaxMultiplier()); - if (name.equals("actor") || name.equals("class") || name.equals("action_name")) - continue; + return sb.toString(); + } - String v = n.getNodeValue(); + @Override + public TextureRegion getCellImage(SceneLayer l) { + String u = null; - sb.append(name).append(": ").append(doc.getTranslation(v)).append(' '); + if (l.isVisible()) { + u = "eye"; + } else { + u = "eye_disabled"; } - - return sb.toString(); + + return Ctx.assetManager.getIcon(u); } - + @Override protected boolean hasSubtitle() { return true; } - }; + @Override + protected boolean hasImage() { + return true; + } + }; } diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/OptionList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/OptionList.java new file mode 100644 index 000000000..e0634a060 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/OptionList.java @@ -0,0 +1,256 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.utils.Array; +import com.bladecoder.engine.model.Dialog; +import com.bladecoder.engine.model.DialogOption; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.ElementUtils; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.CellRenderer; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.ModelList; +import com.bladecoder.engineeditor.undo.UndoDeleteOption; + +public class OptionList extends ModelList { + Skin skin; + + private ImageButton upBtn; + private ImageButton downBtn; + + public OptionList(Skin skin) { + super(skin, false); + this.skin = skin; + + setCellRenderer(listCellRenderer); + + upBtn = new ImageButton(skin); + downBtn = new ImageButton(skin); + + toolbar.addToolBarButton(upBtn, "ic_up", "Move up", "Move up"); + toolbar.addToolBarButton(downBtn, "ic_down", "Move down", "Move down"); + toolbar.pack(); + + list.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + int pos = list.getSelectedIndex(); + + toolbar.disableEdit(pos == -1); + upBtn.setDisabled(pos == -1 || pos == 0); + downBtn.setDisabled(pos == -1 || pos == list.getItems().size - 1); + } + }); + + upBtn.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + up(); + } + }); + + downBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + down(); + } + }); + + Ctx.project.addPropertyChangeListener(Project.NOTIFY_ELEMENT_CREATED, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getNewValue() instanceof DialogOption && !(evt.getSource() instanceof EditOptionDialog)) { + addElements(parent, parent.getOptions()); + } + } + }); + } + + @Override + protected EditModelDialog getEditElementDialogInstance(DialogOption e) { + return new EditOptionDialog(skin, parent, e, list.getSelectedIndex()); + } + + @Override + protected void create() { + EditOptionDialog dialog = (EditOptionDialog) getEditElementDialogInstance(null); + dialog.show(getStage()); + dialog.setListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + int pos = list.getSelectedIndex() + 1; + + DialogOption e = ((EditOptionDialog) actor).getElement(); + list.getItems().insert(pos, e); + list.setSelectedIndex(pos); + list.invalidateHierarchy(); + } + }); + } + + private void up() { + int pos = list.getSelectedIndex(); + + if (pos == -1 || pos == 0) + return; + + Array items = list.getItems(); + DialogOption e = items.get(pos); + DialogOption e2 = items.get(pos - 1); + + items.set(pos - 1, e); + items.set(pos, e2); + + parent.getOptions().set(pos - 1, e); + parent.getOptions().set(pos, e2); + + list.setSelectedIndex(pos - 1); + upBtn.setDisabled(list.getSelectedIndex() == 0); + downBtn.setDisabled(list.getSelectedIndex() == list.getItems().size - 1); + + Ctx.project.setModified(); + } + + private void down() { + int pos = list.getSelectedIndex(); + Array items = list.getItems(); + + if (pos == -1 || pos == items.size - 1) + return; + + DialogOption e = items.get(pos); + DialogOption e2 = items.get(pos + 1); + + parent.getOptions().set(pos + 1, e); + parent.getOptions().set(pos, e2); + + items.set(pos + 1, e); + items.set(pos, e2); + list.setSelectedIndex(pos + 1); + upBtn.setDisabled(list.getSelectedIndex() == 0); + downBtn.setDisabled(list.getSelectedIndex() == list.getItems().size - 1); + + Ctx.project.setModified(); + } + + @Override + protected void delete() { + + DialogOption option = removeSelected(); + + int idx = parent.getOptions().indexOf(option); + + parent.getOptions().remove(option); + + // TRANSLATIONS + Ctx.project.getI18N().putTranslationsInElement(option); + + // UNDO + Ctx.project.getUndoStack().add(new UndoDeleteOption(parent, option, idx)); + + Ctx.project.setModified(); + } + + @Override + protected void copy() { + DialogOption e = list.getSelected(); + + if (e == null) + return; + + clipboard = (DialogOption) ElementUtils.cloneElement(e); + toolbar.disablePaste(false); + + // TRANSLATIONS + Ctx.project.getI18N().putTranslationsInElement(clipboard); + } + + @Override + protected void paste() { + DialogOption newElement = (DialogOption) ElementUtils.cloneElement(clipboard); + + int pos = list.getSelectedIndex() + 1; + + list.getItems().insert(pos, newElement); + + parent.addOption(newElement); + + Ctx.project.getI18N().extractStrings(Ctx.project.getSelectedScene().getId(), + Ctx.project.getSelectedActor().getId(), parent.getId(), pos, newElement); + + list.setSelectedIndex(pos); + list.invalidateHierarchy(); + + Ctx.project.setModified(); + } + + // ------------------------------------------------------------------------- + // ListCellRenderer + // ------------------------------------------------------------------------- + private final CellRenderer listCellRenderer = new CellRenderer() { + + @Override + protected String getCellTitle(DialogOption e) { + String text = e.getText(); + + int i = parent.getOptions().indexOf(e); + + String str = i + ". " + Ctx.project.translate(text); + + if(e.isOnce()) + str = "[[ONCE]" + str; + + if(!e.isVisible()) + str = "[GRAY]" + str + "[]"; + + return str; + } + + @Override + protected String getCellSubTitle(DialogOption e) { + + StringBuilder sb = new StringBuilder(); + String response = e.getResponseText(); + + if (response != null && !response.isEmpty()) + sb.append("R: ").append(Ctx.project.translate(response).replace("\n", "|")).append(' '); + + if (e.getVerbId() != null) + sb.append(" verb: ").append(e.getVerbId()); + + if (e.getNext() != null) + sb.append(" next: ").append(e.getNext()); + + return sb.toString(); + } + + @Override + protected boolean hasSubtitle() { + return true; + } + }; + +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/PackageDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/PackageDialog.java new file mode 100644 index 000000000..08fd73fda --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/PackageDialog.java @@ -0,0 +1,854 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Cell; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.ui.TextField; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.Array; +import com.badlogicgames.packr.Packr; +import com.badlogicgames.packr.PackrConfig; +import com.badlogicgames.packr.PackrConfig.Platform; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engine.actions.Param.Type; +import com.bladecoder.engine.util.Config; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.HttpUtils; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.common.OrderedProperties; +import com.bladecoder.engineeditor.common.RunProccess; +import com.bladecoder.engineeditor.ui.panels.EditDialog; +import com.bladecoder.engineeditor.ui.panels.FileInputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanel; +import com.bladecoder.engineeditor.ui.panels.InputPanelFactory; +import com.kotcrab.vis.ui.widget.file.FileChooser; +import com.kotcrab.vis.ui.widget.file.FileChooserListener; +import com.kotcrab.vis.ui.widget.file.FileTypeFilter; +import org.apache.commons.compress.archivers.ArchiveException; +import org.apache.commons.compress.compressors.CompressorException; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FilenameFilter; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Properties; + +public class PackageDialog extends EditDialog { + private static final String ARCH_PROP = "package.arch"; + private static final String DIR_PROP = "package.dir"; + + private static final String DESKTOP_LAUNCHER = "DesktopLauncher.java"; + + private static final String INFO = "Package the Game for distribution"; + private static final String[] ARCHS = {"desktop", "android", "ios"}; + private static final String[] DESKTOP_TYPES = {"Bundle JRE", "Runnable jar"}; + private static final String[] ANDROID_TYPES = {".apk", ".aab"}; + private static final String[] OSS = {"windows64", "linux64", "macOS-x86"}; + + private final InputPanel arch; + private final InputPanel dir; + + private final InputPanel desktopType; + private final InputPanel androidType; + + private final InputPanel os; + private final FileInputPanel linux64JRE; + private final FileInputPanel winJRE64; + private final FileInputPanel osxJRE; + private final InputPanel version; + private final InputPanel icon; + private final InputPanel versionCode; + private final InputPanel androidSDK; + private final InputPanel expansionFile; + private final InputPanel androidKeyStore; + private final InputPanel androidKeyAlias; + private final InputPanel androidKeyStorePassword; + private final InputPanel androidKeyAliasPassword; + + private final InputPanel iosSignIdentity; + private final InputPanel iosProvisioningProfile; + + private final InputPanel customBuildParameters; + + private final InputPanel[] options; + + public PackageDialog(final Skin skin) { + super("PACKAGE GAME", skin); + + arch = InputPanelFactory.createInputPanel(skin, "Architecture", "Select the target Architecture for the game", + ARCHS, true); + dir = new FileInputPanel(skin, "Output Directory", "Select the output directory to put the package", + FileInputPanel.DialogType.DIRECTORY); + desktopType = InputPanelFactory.createInputPanel(skin, "Type", "Select the package type", DESKTOP_TYPES, true); + androidType = InputPanelFactory.createInputPanel(skin, "Type", "Select the package type", ANDROID_TYPES, true); + os = InputPanelFactory.createInputPanel(skin, "OS", "Select the OS of the package", OSS, true); + + FileTypeFilter typeFilter = new FileTypeFilter(true); + typeFilter.addRule("Compressed files", "zip", "tar.gz"); + + linux64JRE = new FileInputPanel(skin, "JRE lin64", + "Select the 64 bits Linux JRE Location to bundle. Must be a .zip or a .tar.gz file", + FileInputPanel.DialogType.OPEN_FILE); + linux64JRE.setFileTypeFilter(typeFilter); + + winJRE64 = new FileInputPanel(skin, "JRE win64", + "Select the Windows 64 bits JRE Location to bundle. Must be a .zip or a .tar.gz file", + FileInputPanel.DialogType.OPEN_FILE); + winJRE64.setFileTypeFilter(typeFilter); + + osxJRE = new FileInputPanel(skin, "JRE mac-x86", + "Select the MacOS-x86 JRE Location to bundle. Must be a .zip or a .tar.gz file", + FileInputPanel.DialogType.OPEN_FILE); + osxJRE.setFileTypeFilter(typeFilter); + + version = InputPanelFactory.createInputPanel(skin, "Version", "Select the package version", true); + icon = new FileInputPanel(skin, "MacOS Icon", "The icon (.icns) for the Mac package. It is not mandatory.", + FileInputPanel.DialogType.OPEN_FILE, false); + versionCode = InputPanelFactory.createInputPanel(skin, "Version Code", "An integer that identify the version.", + Type.INTEGER, true); + androidSDK = new FileInputPanel(skin, "SDK", + "Select the Android SDK Location. If empty, the ANDROID_HOME variable will be used.", + FileInputPanel.DialogType.DIRECTORY, false); + expansionFile = InputPanelFactory.createInputPanel(skin, "Expansion File", + "If your assets exceeds 100mb, you have to create an expansion file to upload the game to the Play " + + "Store.", + Param.Type.BOOLEAN, true, "false"); + androidKeyStore = new FileInputPanel(skin, "KeyStore", "Select the Key Store Location", + FileInputPanel.DialogType.OPEN_FILE); + androidKeyAlias = InputPanelFactory.createInputPanel(skin, "KeyAlias", "Select the Key Alias", true); + + androidKeyStorePassword = InputPanelFactory.createInputPanel(skin, "KeyStorePasswd", "Key Store Password", + true); + androidKeyAliasPassword = InputPanelFactory.createInputPanel(skin, "KeyAliasPasswd", "Key Alias Password", + true); + + iosSignIdentity = InputPanelFactory.createInputPanel(skin, "Sign Identity", + "Empty for auto select.\nThis field matches against the start of the certificate name. Alternatively " + + "you can use a certificate fingerprint.\nIf the value is enclosed in / a regexp search will " + + "be" + + " done against the certificate name instead.\nRun the command 'security find-identity -v -p " + + "codesigning' or use theKeyChain Access OS X app to view your installed certificates.", + false); + + iosProvisioningProfile = InputPanelFactory.createInputPanel(skin, "Provisioning Profile", + "Empty for auto select.", false); + + customBuildParameters = InputPanelFactory.createInputPanel(skin, "Custom build parameters", + "You can add extra build parameters for customized build scripts.", false); + + options = new InputPanel[]{androidType, desktopType, os, linux64JRE, winJRE64, osxJRE, version, icon, + versionCode, androidSDK, expansionFile, androidKeyStore, androidKeyAlias, iosSignIdentity, + iosProvisioningProfile, customBuildParameters}; + + addInputPanel(arch); + addInputPanel(dir); + + for (InputPanel i : options) { + addInputPanel(i); + } + + addInputPanel(androidKeyStorePassword); + addInputPanel(androidKeyAliasPassword); + + ((TextField) androidKeyStorePassword.getField()).setPasswordMode(true); + ((TextField) androidKeyStorePassword.getField()).setPasswordCharacter('*'); + ((TextField) androidKeyAliasPassword.getField()).setPasswordMode(true); + ((TextField) androidKeyAliasPassword.getField()).setPasswordCharacter('*'); + + dir.setMandatory(true); + + arch.setText(Ctx.project.getEditorConfig().getProperty(ARCH_PROP, ARCHS[0])); + dir.setText(Ctx.project.getEditorConfig().getProperty(DIR_PROP, "")); + + for (InputPanel i : options) { + String prop = Ctx.project.getEditorConfig().getProperty("package." + i.getTitle()); + + if (prop != null && !prop.isEmpty()) + i.setText(prop); + } + + version.setText(getCurrentVersion()); + + // TODO Set version code based in version + // androidVersionCode.setText(genVersionCode(version.getText())); + + setInfo(INFO); + + arch.getField().addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + archChanged(); + } + }); + + desktopType.getField().addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + desktopTypeChanged(); + } + }); + + os.getField().addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + osChanged(); + } + }); + + androidType.getField().addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + androidTypeChanged(); + } + }); + + // Add the 'create' button to the keystore. + TextButton createButton = new TextButton("Create", skin, "no-toggled"); + + createButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + final CreateAndroidKeystoreDialog c = new CreateAndroidKeystoreDialog(skin); + c.show(getStage()); + + c.setListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + androidKeyStore.setText(c.getKeyStorePath()); + androidKeyAlias.setText(c.getKeyAlias()); + androidKeyStorePassword.setText(c.getKeyStorePassword()); + androidKeyAliasPassword.setText(c.getKeyAliasPassword()); + + } + }); + + } + }); + + Table t = new Table(); + Actor a = androidKeyStore.getField(); + Cell c = androidKeyStore.getCell(a); + t.add(a); + t.add(createButton); + c.setActor(t); + + // Add the 'download' button to the OS combo. + TextButton downloadButton = new TextButton("Download JRE", skin, "no-toggled"); + + downloadButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + + if ("windows64".equals(os.getText())) { + downloadJDK( + "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.7%2B7/OpenJDK17U-jdk_x64_windows_hotspot_17.0.7_7.zip", + "jdk17_windows64.tar.gz"); + } else if ("linux64".equals(os.getText())) { + downloadJDK("https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.7%2B7/OpenJDK17U-jdk_x64_linux_hotspot_17.0.7_7.tar.gz", + "jdk17_linux64.tar.gz"); + } else if ("macOS-x86".equals(os.getText())) { + downloadJDK("https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.7%2B7/OpenJDK17U-jdk_x64_mac_hotspot_17.0.7_7.tar.gz", + "jdk17_macos64_x86.tar.gz"); + } + } + }); + + Table t2 = new Table(); + Actor a2 = os.getField(); + Cell c2 = os.getCell(a2); + t2.add(a2); + t2.add(downloadButton); + c2.setActor(t2); + + archChanged(); + } + + private void downloadJDK(String url, String fileName) { + FileChooser fileChooser = new FileChooser(FileChooser.Mode.OPEN); + fileChooser.setSize(Gdx.graphics.getWidth() * 0.7f, Gdx.graphics.getHeight() * 0.7f); + fileChooser.setViewMode(FileChooser.ViewMode.LIST); + + fileChooser.setSelectionMode(FileChooser.SelectionMode.DIRECTORIES); + getStage().addActor(fileChooser); + + fileChooser.setListener(new FileChooserListener() { + + @Override + public void selected(Array files) { + try { + File outputFile = new File(files.get(0).file(), fileName); + HttpUtils.downloadAsync(new URL(url), new FileOutputStream(outputFile), new HttpUtils.Callback() { + @Override + public void updated(int length, int totalLength) { + final int progress = ((int) (((double) length / (double) totalLength) * 100)); + Message.showMsg(getStage(), "Downloading JDK... " + progress + "%", true); + } + + @Override + public void completed() { + Gdx.app.postRunnable(new Runnable() { + @Override + public void run() { + Message.hideMsg(); + + if ("windows64".equals(os.getText())) { + winJRE64.setText(outputFile.getAbsolutePath()); + } else if ("linux64".equals(os.getText())) { + linux64JRE.setText(outputFile.getAbsolutePath()); + } else if ("macOS-x86".equals(os.getText())) { + osxJRE.setText(outputFile.getAbsolutePath()); + } + } + }); + } + + @Override + public void canceled() { + Message.showMsgDialog(getStage(), "Error", "Download cancelled."); + } + + @Override + public void error(IOException ex) { + Message.showMsgDialog(getStage(), "Error", "Download error: " + ex.getMessage()); + } + }); + } catch (FileNotFoundException | MalformedURLException e) { + Message.showMsgDialog(getStage(), "Error", "Download error: " + e.getMessage()); + } + } + + @Override + public void canceled() { + + } + }); + } + + @Override + protected void ok() { + + final Stage stg = getStage(); + + Message.showMsg(stg, "Generating package...", true); + + new Thread() { + + @Override + public void run() { + + String msg; + + if (Ctx.project.getSelectedScene() == null) { + msg = "There are no scenes in this chapter."; + Message.showMsg(stg, msg, 3); + return; + } + + Ctx.project.getProjectConfig().removeProperty(Config.CHAPTER_PROP); + Ctx.project.getProjectConfig().removeProperty(Config.TEST_SCENE_PROP); + setCurrentVersion(version.getText()); + + try { + Ctx.project.saveProject(); + } catch (Exception ex) { + msg = "Something went wrong while saving the project.\n\n" + ex.getClass().getSimpleName() + " - " + + ex.getMessage(); + + Message.showMsgDialog(stg, "Error", msg); + return; + } + + try { + msg = packageAdv(); + } catch (Exception e) { + msg = "Error Generating package\n\n" + e.getMessage(); + e.printStackTrace(); + } + + Ctx.project.getEditorConfig().setProperty(ARCH_PROP, arch.getText()); + Ctx.project.getEditorConfig().setProperty(DIR_PROP, dir.getText()); + + for (InputPanel i : options) { + if (i.getText() != null) + Ctx.project.getEditorConfig().setProperty("package." + i.getTitle(), i.getText()); + } + + // hide message + Message.hideMsg(); + + final String m = msg; + Message.showMsgDialog(stg, "Result", m); + } + }.start(); + + } + + private String packageAdv() throws IOException, CompressorException, ArchiveException { + String msg = "Package generated SUCCESSFULLY"; + + String projectName = getAppName(); + if (projectName == null) + Ctx.project.getProjectDir().getName(); + + String versionParam = "-Pversion=" + version.getText() + " "; + Ctx.project.getProjectConfig().setProperty(Config.VERSION_PROP, version.getText()); + + String customBuildParams = customBuildParameters.getText() == null ? "" : customBuildParameters.getText() + " "; + + if (arch.getText().equals("desktop")) { + String error = createDesktop(projectName, versionParam, customBuildParams); + return error == null ? msg : error; + } + + if (arch.getText().equals("android")) { + String error = createAndroid(projectName, versionParam, customBuildParams); + return error == null ? msg : error; + } + + if (arch.getText().equals("ios")) { + String error = createIOS(projectName, customBuildParams); + return error == null ? msg : error; + } + + return msg; + } + + private String createIOS(String projectName, String customBuildParams) throws IOException { + if (!System.getProperty("os.name").toLowerCase().contains("mac")) { + return "You need a MacOSX computer with XCode installed to generate the IOS package."; + } + + // UPDATE 'robovm.properties' + Properties p = new Properties(); + p.load(new FileReader(Ctx.project.getProjectDir().getAbsolutePath() + "/ios/robovm.properties")); + p.setProperty("app.version", version.getText()); + p.setProperty("app.build", versionCode.getText()); + p.setProperty("app.name", Ctx.project.getTitle()); + p.store(new FileOutputStream(new File(Ctx.project.getProjectDir().getAbsolutePath(), "/ios/robovm.properties")), + null); + + List params = new ArrayList<>(); + + if (iosSignIdentity.getText() != null) + params.add("-Probovm.iosSignIdentity=" + iosSignIdentity.getText()); + + if (iosProvisioningProfile.getText() != null) + params.add("-Probovm.iosProvisioningProfile=" + iosProvisioningProfile.getText()); + + if (customBuildParameters.getText() != null) + params.add(customBuildParams); + + // Add clean target in IOS because the app. is not signing well if not cleaning. + params.add("ios:clean"); + + params.add("ios:createIPA"); + + if (RunProccess.runGradle(Ctx.project.getProjectDir(), params)) { + + String apk = Ctx.project.getProjectDir().getAbsolutePath() + "/ios/build/robovm/IOSLauncher.ipa"; + + File f = new File(apk); + FileUtils.copyFile(f, new File(dir.getText(), projectName + "-" + version.getText() + ".ipa")); + } else { + return "Error Generating package"; + } + + return null; + } + + private String createAndroid(String projectName, String versionParam, String customBuildParams) + throws IOException { + String params = versionParam + customBuildParams + "-PversionCode=" + versionCode.getText() + " " + + "-Pkeystore=\"" + androidKeyStore.getText() + "\" " + "-PstorePassword=" + + androidKeyStorePassword.getText() + " " + "-Palias=" + androidKeyAlias.getText() + " " + + "-PkeyPassword=" + androidKeyAliasPassword.getText() + " "; + + // UPDATE 'local.properties' with the android SDK location. + if (androidSDK.getText() != null && !androidSDK.getText().trim().isEmpty()) { + String sdk = androidSDK.getText(); + + Properties p = new Properties(); + p.setProperty("sdk.dir", sdk); + p.store(new FileOutputStream(new File(Ctx.project.getProjectDir().getAbsolutePath(), "local.properties")), + null); + } + + if (!new File(Ctx.project.getProjectDir().getAbsolutePath(), "local.properties").exists() + && System.getenv("ANDROID_HOME") == null) { + return "You have to specify the Android SDK path or set the ANDROID_HOME environtment variable."; + } + + boolean isAPK = androidType.getText().equals(ANDROID_TYPES[0]); + + String task = "android:assembleFullRelease"; + File pkgFile = new File(Ctx.project.getProjectDir().getAbsolutePath(), + "android/build/outputs/apk/full/release/android-full-release.apk"); + + File destPkgFile = new File(dir.getText(), projectName + "-" + version.getText() + ".apk"); + + boolean genExpansion = Boolean.parseBoolean(expansionFile.getText()); + + if (!isAPK) { // .aab + task = "android:bundleFullRelease"; + pkgFile = new File(Ctx.project.getProjectDir().getAbsolutePath(), + "android/build/outputs/bundle/fullRelease/android-full-release.aab"); + destPkgFile = new File(dir.getText(), projectName + "-" + version.getText() + ".aab"); + genExpansion = false; + } + + boolean newProjectStructure = new File(Ctx.project.getProjectDir().getAbsolutePath() + "/assets/").exists(); + + if (!newProjectStructure && genExpansion) + return "You need to update your project to the new layout to generate expansion files."; + + if (!newProjectStructure) { + task = "android:assembleRelease"; + pkgFile = new File(Ctx.project.getProjectDir().getAbsolutePath(), + "android/build/outputs/apk/android-release.apk"); + } + + if (genExpansion) { + task = "android:assembleExpansionRelease"; + pkgFile = new File(Ctx.project.getProjectDir().getAbsolutePath(), + "android/build/outputs/apk/expansion/release/android-expansion-release.apk"); + } + + if (!RunProccess.runGradle(Ctx.project.getProjectDir(), params + task)) { + return "Error Generating package"; + } + + FileUtils.copyFile(pkgFile, destPkgFile); + + if (genExpansion) { + File fExp = findObb(Ctx.project.getProjectDir().getAbsolutePath() + "/android/build/distributions/", + versionCode.getText()); + FileUtils.copyFile(fExp, new File(dir.getText(), fExp.getName())); + } + + return null; + } + + private String createDesktop(String projectName, String versionParam, String customBuildParams) + throws IOException, CompressorException, ArchiveException { + String jarDir = Ctx.project.getProjectDir().getAbsolutePath() + "/desktop/build/libs/"; + String jarName = "desktop-" + version.getText() + ".jar"; + + String error = genDesktopJar(projectName, versionParam, jarDir, jarName, customBuildParams); + + if (error != null) + return error; + + if (desktopType.getText().equals(DESKTOP_TYPES[0])) { // BUNDLE JRE + String launcher = getDesktopMainClass(); + + if (os.getText().equals("linux64")) { + packr(Platform.Linux64, linux64JRE.getText(), projectName, jarDir + jarName, launcher, dir.getText()); + } else if (os.getText().equals("windows64")) { + packr(Platform.Windows64, winJRE64.getText(), projectName, jarDir + jarName, launcher, dir.getText()); + } else if (os.getText().equals("macOS-x86")) { + packr(Platform.MacOS, osxJRE.getText(), projectName, jarDir + jarName, launcher, dir.getText()); + } + } + + return null; + } + + private void archChanged() { + for (InputPanel ip : options) { + setVisible(ip, false); + } + + setVisible(androidKeyStorePassword, false); + setVisible(androidKeyAliasPassword, false); + + setVisible(version, true); + + String a = arch.getText(); + if (a.equals("desktop")) { + setVisible(desktopType, true); + desktopTypeChanged(); + } else if (a.equals("android")) { + setVisible(androidType, true); + setVisible(versionCode, true); + setVisible(androidSDK, true); + setVisible(expansionFile, true); + setVisible(androidKeyStore, true); + setVisible(androidKeyAlias, true); + setVisible(androidKeyStorePassword, true); + setVisible(androidKeyAliasPassword, true); + } else if (a.equals("ios")) { + setVisible(versionCode, true); + setVisible(iosSignIdentity, true); + setVisible(iosProvisioningProfile, true); + } + + setVisible(customBuildParameters, true); + } + + private void desktopTypeChanged() { + if (desktopType.getText().equals(DESKTOP_TYPES[0])) { + setVisible(os, true); + } else { + setVisible(os, false); + setVisible(icon, false); + } + + osChanged(); + } + + private void androidTypeChanged() { + setVisible(expansionFile, androidType.getText().equals(ANDROID_TYPES[0])); + } + + private void osChanged() { + setVisible(icon, false); + + if (os.isVisible() && (os.getText().equals("windows64"))) { + setVisible(winJRE64, true); + } else { + setVisible(icon, false); + setVisible(winJRE64, false); + } + + setVisible(linux64JRE, os.isVisible() && (os.getText().equals("linux64"))); + + if (os.isVisible() && (os.getText().equals("macOS-x86"))) { + setVisible(osxJRE, true); + setVisible(icon, true); + } else { + setVisible(osxJRE, false); + } + } + + @Override + protected boolean validateFields() { + boolean ok = dir.validateField(); + + for (InputPanel i : options) { + if (i.isVisible() && !i.validateField()) + ok = false; + } + + if (androidKeyStorePassword.isVisible() && !androidKeyStorePassword.validateField()) + ok = false; + + if (androidKeyAliasPassword.isVisible() && !androidKeyAliasPassword.validateField()) + ok = false; + + if (linux64JRE.isVisible() + && (!new File(linux64JRE.getText()).exists() || (!linux64JRE.getText().toLowerCase() + .endsWith(".zip") && !linux64JRE.getText().toLowerCase().endsWith(".tar.gz")))) { + linux64JRE.setError(true); + ok = false; + } + + if (winJRE64.isVisible() + && (!new File(winJRE64.getText()).exists() || (!winJRE64.getText().toLowerCase() + .endsWith(".zip") && !winJRE64.getText().toLowerCase().endsWith(".tar.gz")))) { + winJRE64.setError(true); + ok = false; + } + + if (osxJRE.isVisible() + && (!new File(osxJRE.getText()).exists() || (!osxJRE.getText().toLowerCase() + .endsWith(".zip") && !osxJRE.getText().toLowerCase().endsWith(".tar.gz")))) { + osxJRE.setError(true); + ok = false; + } + + return ok; + } + + private String genDesktopJar(String projectName, String versionParam, String jarDir, String jarName, + String customBuildParams) throws IOException { + String msg = null; + + if (RunProccess.runGradle(Ctx.project.getProjectDir(), versionParam + customBuildParams + "desktop:dist")) { + File f = new File(jarDir + jarName); + FileUtils.copyFileToDirectory(f, new File(dir.getText())); + + new File(jarDir, jarName).setExecutable(true); + new File(dir.getText(), jarName).setExecutable(true); + } else { + msg = "Error Generating package"; + } + + return msg; + } + + private void packr(Platform platform, String jdk, String exe, String jar, String mainClass, String outDir) + throws IOException, CompressorException, ArchiveException { + String suffix = null; + + switch (platform) { + case Linux64: + suffix = "lin64"; + break; + case MacOS: + suffix = "mac.app"; + break; + case Windows64: + suffix = "win64"; + break; + + } + + PackrConfig config = new PackrConfig(); + config.platform = platform; + config.jdk = jdk; + config.jrePath = "jre"; + config.executable = exe; + config.classpath = Collections.singletonList(jar); + config.mainClass = mainClass.replace('/', '.'); + + if (platform.equals(Platform.MacOS)) { + config.vmArgs = Arrays.asList("-Xmx1G", "-Dsun.java2d.dpiaware=true", "-XstartOnFirstThread"); + } else { + config.vmArgs = Arrays.asList("-Xmx1G", "-Dsun.java2d.dpiaware=true"); + } + + config.minimizeJre = "hard"; + + config.outDir = new File(outDir + "/" + exe + "-" + suffix); + + new Packr().pack(config); + + // COPY MAC OS ICON + if (platform == Platform.MacOS && icon.getText() != null && icon.getText().endsWith(".icns")) { + FileUtils.copyFile(new File(icon.getText()), + new File(config.outDir.getAbsolutePath() + "/Contents/Resources/icons.icns")); + } + } + + /** + * @return The appName from the file gradle.properties from the game + */ + private String getAppName() { + + try { + OrderedProperties prop = Ctx.project.getGradleProperties(Ctx.project.getProjectDir()); + return prop.getProperty("appName"); + } catch (IOException e) { + Message.showMsg(getStage(), "Error reading file 'gradle.properties' from the game.", 3); + } + + return null; + } + + /** + * @return The version from the file gradle.properties from the game + */ + private String getCurrentVersion() { + + try { + OrderedProperties prop = Ctx.project.getGradleProperties(Ctx.project.getProjectDir()); + return prop.getProperty("version"); + } catch (IOException e) { + Message.showMsg(getStage(), "Error reading file 'gradle.properties' from the game.", 3); + } + + return null; + } + + /** + * Saves the selected version + */ + private void setCurrentVersion(String version) { + + try { + OrderedProperties prop = Ctx.project.getGradleProperties(Ctx.project.getProjectDir()); + prop.setProperty("version", version); + Ctx.project.saveGradleProperties(prop, Ctx.project.getProjectDir()); + } catch (IOException e) { + Message.showMsg(getStage(), "Error reading file 'gradle.properties' from the game.", 3); + } + } + + /** + * @return Search the desktop main class in the desktop folder + */ + private String getDesktopMainClass() { + + File result = search(new File(Ctx.project.getProjectDir().getAbsolutePath() + "/desktop")); + + String absolutePath = result.getAbsolutePath().replace('\\', '/'); + + int cutIdx = absolutePath.indexOf("src/main/java/"); + + if (cutIdx != -1) + cutIdx += 14; + else + cutIdx = absolutePath.indexOf("src/") + 4; + + return absolutePath.substring(cutIdx, absolutePath.length() - ".java".length()); + } + + private File search(File file) { + File result = null; + + // do you have permission to read this directory? + if (file.canRead()) { + for (File temp : file.listFiles()) { + if (temp.isDirectory()) { + result = search(temp); + + if (result != null) + return result; + } else { + if (temp.getName().equals(DESKTOP_LAUNCHER)) { + return temp; + } + } + } + + } + + return result; + } + + private File findObb(String baseDir, final String versionCode) { + File dir = new File(baseDir); + + File[] listFiles = dir.listFiles(new FilenameFilter() { + + @Override + public boolean accept(File arg0, String arg) { + return arg.startsWith("main." + versionCode + ".") && arg.endsWith(".obb"); + } + + }); + + return listFiles == null || listFiles.length == 0 ? null : listFiles[0]; + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ProjectPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ProjectPanel.java similarity index 63% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ProjectPanel.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ProjectPanel.java index 56fd95a47..40076b66d 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ProjectPanel.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ProjectPanel.java @@ -20,47 +20,42 @@ import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.ChapterDocument; import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.model.WorldDocument; -import com.bladecoder.engineeditor.ui.components.HeaderPanel; -import com.bladecoder.engineeditor.ui.components.TabPanel; +import com.bladecoder.engineeditor.ui.panels.HeaderPanel; +import com.bladecoder.engineeditor.ui.panels.TabPanel; -public class ProjectPanel extends HeaderPanel { +public class ProjectPanel extends HeaderPanel { private TabPanel tabPanel; private SceneList sceneList; - private VerbList verbList; private ChapterList chapterList; - - + private SoundList soundList; + public ProjectPanel(Skin skin) { - super(skin, "ADVENTURE"); - + super(skin, "ADVENTURE"); + tabPanel = new TabPanel(skin); sceneList = new SceneList(skin); - verbList = new VerbList(skin); chapterList = new ChapterList(skin); - + soundList = new SoundList(skin); + setContent(tabPanel); - + tabPanel.addTab("Scenes", sceneList); tabPanel.addTab("Chapters", chapterList); - tabPanel.addTab("Def. Verbs", verbList); - tabPanel.addTab("Properties", new WorldProps(skin)); - + tabPanel.addTab("Game Props", new WorldProps(skin)); + tabPanel.addTab("Sounds", soundList); + tabPanel.addTab("Assets", new AssetsList(skin)); + tabPanel.addTab("Resolutions", new ResolutionList(skin)); Ctx.project.addPropertyChangeListener(Project.NOTIFY_PROJECT_LOADED, new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent e) { - WorldDocument w = Ctx.project.getWorld(); - ChapterDocument selectedChapter = Ctx.project.getSelectedChapter(); - - sceneList.addElements(selectedChapter, selectedChapter.getElement(), "scene"); - verbList.addElements(w, w.getElement(), "verb"); - chapterList.addElements(w); - setTile("ADVENTURE - " + (Ctx.project.getTitle() != null? Ctx.project.getTitle():"")); + chapterList.addElements(); + setTile(Ctx.project.getTitle() != null + ? Ctx.project.getTitle() + " (" + Ctx.project.getWorld().getScenes().size() + " scenes)" + : "ADVENTURE GAME"); } - }); + }); } } diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ProjectToolbar.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ProjectToolbar.java new file mode 100644 index 000000000..a52c7e2de --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ProjectToolbar.java @@ -0,0 +1,369 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.awt.Desktop; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.IOException; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input.Keys; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Button.ButtonStyle; +import com.badlogic.gdx.scenes.scene2d.ui.Dialog; +import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; +import com.badlogic.gdx.scenes.scene2d.ui.ImageButton.ImageButtonStyle; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextTooltip; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.Array; +import com.bladecoder.engine.util.Config; +import com.bladecoder.engine.util.DPIUtils; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.EditorUtils; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.common.RunProccess; +import com.bladecoder.engineeditor.model.Project; +import com.kotcrab.vis.ui.widget.file.FileChooser; +import com.kotcrab.vis.ui.widget.file.FileChooser.Mode; +import com.kotcrab.vis.ui.widget.file.FileChooser.SelectionMode; +import com.kotcrab.vis.ui.widget.file.FileChooser.ViewMode; +import com.kotcrab.vis.ui.widget.file.FileChooserListener; + +public class ProjectToolbar extends Table { + private ImageButton newBtn; + private ImageButton loadBtn; + private ImageButton saveBtn; + private ImageButton packageBtn; + private ImageButton exitBtn; + private ImageButton playBtn; + private ImageButton assetsBtn; + private ImageButton atlasBtn; + + private Skin skin; + + private FileChooser fileChooser; + + public ProjectToolbar(Skin skin) { + super(skin); + this.skin = skin; + left(); + newBtn = new ImageButton(skin); + saveBtn = new ImageButton(skin); + loadBtn = new ImageButton(skin); + packageBtn = new ImageButton(skin); + exitBtn = new ImageButton(skin); + playBtn = new ImageButton(skin); + assetsBtn = new ImageButton(skin); + atlasBtn = new ImageButton(skin); + + fileChooser = new FileChooser(Mode.OPEN); + fileChooser.setSize(Gdx.graphics.getWidth() * 0.7f, Gdx.graphics.getHeight() * 0.7f); + fileChooser.setViewMode(ViewMode.LIST); + + addToolBarButton(skin, newBtn, "ic_new", "New", "Create a new project"); + addToolBarButton(skin, loadBtn, "ic_load", "Load", "Load an existing project"); + addToolBarButton(skin, saveBtn, "ic_save", "Save", "Save the current project"); + addToolBarButton(skin, exitBtn, "ic_quit", "Exit", "Save changes and exits"); + row(); + + addToolBarButton(skin, playBtn, "ic_play", "Play", "Play Adventure"); + addToolBarButton(skin, packageBtn, "ic_package", "Package", "Package the game for distribution"); + addToolBarButton(skin, assetsBtn, "ic_assets", "Assets", "Open assets folder"); + addToolBarButton(skin, atlasBtn, "ic_atlases", "Atlas", "Create Atlas"); + + newBtn.setDisabled(false); + loadBtn.setDisabled(false); + exitBtn.setDisabled(false); + + playBtn.setDisabled(true); + packageBtn.setDisabled(true); + atlasBtn.setDisabled(true); + assetsBtn.setDisabled(true); + + newBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + saveProjectAndExecute(new Runnable() { + + @Override + public void run() { + newProject(); + } + }); + } + }); + + loadBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + saveProjectAndExecute(new Runnable() { + @Override + public void run() { + loadProject(); + } + }); + } + }); + + exitBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + saveProjectAndExecute(new Runnable() { + @Override + public void run() { + exit(); + } + }); + } + }); + + saveBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + saveProject(); + } + }); + + playBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + play(); + } + }); + + packageBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + packageProject(); + } + }); + + assetsBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + openAssetFolder(); + } + }); + + atlasBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + createAtlas(); + } + }); + + Ctx.project.addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent e) { + saveBtn.setDisabled(!Ctx.project.isModified()); + } + }); + + Ctx.project.addPropertyChangeListener(Project.NOTIFY_PROJECT_LOADED, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent arg0) { + packageBtn.setDisabled(!Ctx.project.isLoaded()); + playBtn.setDisabled(!Ctx.project.isLoaded()); + assetsBtn.setDisabled(!Ctx.project.isLoaded()); + atlasBtn.setDisabled(!Ctx.project.isLoaded()); + } + }); + } + + private void addToolBarButton(Skin skin, ImageButton button, String icon, String text, String tooltip) { + ImageButtonStyle style = new ImageButtonStyle(skin.get(ButtonStyle.class)); + TextureRegion image = Ctx.assetManager.getIcon(icon); + style.imageUp = new TextureRegionDrawable(image); + + try { + TextureRegion imageDisabled = Ctx.assetManager.getIcon(icon + "_disabled"); + + if (imageDisabled != null) + style.imageDisabled = new TextureRegionDrawable(imageDisabled); + } catch (Exception e) { + + } + + button.setStyle(style); + // button.row(); + // button.add(new Label(text, skin)); + + add(button); + button.setDisabled(true); + TextTooltip t = new TextTooltip(tooltip, skin); + t.getContainer().pad(DPIUtils.getSpacing() / 2); + button.addListener(t); + } + + private void newProject() { + CreateProjectDialog dialog = new CreateProjectDialog(skin); + dialog.show(getStage()); + } + + @Override + public void act(float delta) { + super.act(delta); + } + + private void loadProject() { + fileChooser.setSelectionMode(SelectionMode.DIRECTORIES); + getStage().addActor(fileChooser); + + fileChooser.setListener(new FileChooserListener() { + + @Override + public void selected(Array files) { + + final File f = files.get(0).file(); + + try { + EditorUtils.checkVersionAndLoadProject(f, getStage(), skin); + } catch (Exception e) { + EditorLogger.error("Error loading last project.", e); + Ctx.project.closeProject(); + } + + } + + @Override + public void canceled() { + } + }); + } + + public void exit() { + Gdx.app.exit(); + } + + private void saveProject() { + File file = Ctx.project.getProjectDir(); + + if (file == null) { + String msg = "Please create a new project first."; + Message.showMsg(getStage(), msg, 3); + return; + } + + try { + Ctx.project.saveProject(); + } catch (Exception ex) { + String msg = "Something went wrong while saving the project.\n\n" + ex.getClass().getSimpleName() + " - " + + ex.getMessage(); + Message.showMsgDialog(getStage(), "Error saving project", msg); + } + } + + private void packageProject() { + saveProject(); + + new PackageDialog(skin).show(getStage()); + } + + private void play() { + saveProject(); + + new Thread(new Runnable() { + Stage stage = getStage(); + + @Override + public void run() { + + if (Ctx.project.getSelectedScene() == null) { + String msg = "There are no scenes in this chapter."; + Message.showMsg(getStage(), msg, 3); + return; + } + + Ctx.project.getProjectConfig().removeProperty(Config.CHAPTER_PROP); + Ctx.project.getProjectConfig().removeProperty(Config.TEST_SCENE_PROP); + + try { + Ctx.project.saveProject(); + } catch (Exception ex) { + String msg = "Something went wrong while saving the project.\n\n" + ex.getClass().getSimpleName() + + " - " + ex.getMessage(); + Message.showMsgDialog(getStage(), "Error", msg); + return; + } + + Message.showMsg(stage, "Running scene...", 3); + + try { + if (!RunProccess.runBladeEngine(Ctx.project.getProjectDir(), null, null, + Boolean.parseBoolean( + Ctx.project.getEditorConfig().getProperty("view.fullscreenPlay", "false")))) + Message.showMsg(getStage(), "There was a problem running the project", 3); + } catch (IOException e) { + Message.showMsgDialog(stage, "Error", "There was a problem running the project: " + e.getMessage()); + } + + } + }).start(); + + } + + private void openAssetFolder() { + if (Desktop.isDesktopSupported()) { + try { + Desktop.getDesktop().open(new File( + Ctx.project.getAssetPath(Ctx.project.getProjectDir().getAbsoluteFile().getAbsolutePath()))); + } catch (IOException e1) { + String msg = "Something went wrong while opening assets folder.\n\n" + e1.getClass().getSimpleName() + + " - " + e1.getMessage(); + Message.showMsgDialog(getStage(), "Error", msg); + } + } + } + + private void createAtlas() { + new CreateAtlasDialog(skin).show(getStage()); + } + + private void saveProjectAndExecute(final Runnable task) { + if (Ctx.project.isLoaded() && Ctx.project.isModified()) { + new Dialog("Save Project", skin) { + protected void result(Object object) { + if (((Boolean) object).booleanValue()) { + try { + Ctx.project.saveProject(); + } catch (IOException e1) { + String msg = "Something went wrong while saving the actor.\n\n" + + e1.getClass().getSimpleName() + " - " + e1.getMessage(); + Message.showMsgDialog(getStage(), "Error", msg); + + EditorLogger.printStackTrace(e1); + } + } + + task.run(); + } + }.text("Save current project changes?").button("Yes", true).button("No", false).key(Keys.ENTER, true) + .key(Keys.ESCAPE, false).show(getStage()); + } else { + task.run(); + } + } + +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ResolutionList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ResolutionList.java similarity index 80% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ResolutionList.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ResolutionList.java index f9f250fe7..330346edb 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ResolutionList.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ResolutionList.java @@ -25,10 +25,12 @@ import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.DesktopUtils; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.Message; import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.ui.components.CellRenderer; -import com.bladecoder.engineeditor.ui.components.EditList; -import com.bladecoder.engineeditor.utils.DesktopUtils; +import com.bladecoder.engineeditor.ui.panels.CellRenderer; +import com.bladecoder.engineeditor.ui.panels.EditList; public class ResolutionList extends EditList { @@ -52,14 +54,14 @@ public void changed(ChangeEvent event, Actor actor) { new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent arg0) { - toolbar.disableCreate(Ctx.project.getProjectDir() == null); + toolbar.disableCreate(!Ctx.project.isLoaded()); addResolutions(); } }); } private void addResolutions() { - if (Ctx.project.getProjectDir() != null) { + if (Ctx.project.isLoaded()) { list.getItems().clear(); @@ -79,7 +81,7 @@ private void addResolutions() { } } - toolbar.disableCreate(Ctx.project.getProjectDir() == null); + toolbar.disableCreate(!Ctx.project.isLoaded()); } @Override @@ -102,14 +104,18 @@ public void edit() { public void delete() { int index = list.getSelectedIndex(); String r = list.getItems().get(index); + + if(r.equals("1")) { + Message.showMsg(getStage(),"Initial resolution cannot be deleted", 3); + + return; + } - removeDir(Ctx.project.getProjectDir() + "/" + Project.BACKGROUNDS_PATH - + "/" + r); - removeDir(Ctx.project.getProjectDir() + "/" + Project.IMAGE_PATH + removeDir(Ctx.project.getAssetPath() + Project.IMAGE_PATH + "/" + r); - removeDir(Ctx.project.getProjectDir() + "/" + Project.UI_PATH + "/" + removeDir(Ctx.project.getAssetPath() + Project.UI_PATH + "/" + r); - removeDir(Ctx.project.getProjectDir() + "/" + Project.ATLASES_PATH + removeDir(Ctx.project.getAssetPath() + Project.ATLASES_PATH + "/" + r); addResolutions(); @@ -121,8 +127,8 @@ private void removeDir(String dir) { } catch (IOException e) { String msg = "Something went wrong while deleting the resolution.\n\n" + e.getClass().getSimpleName() + " - " + e.getMessage(); - Ctx.msg.show(getStage(),msg, 2); - e.printStackTrace(); + Message.showMsg(getStage(),msg, 2); + EditorLogger.printStackTrace(e); } } diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/SceneList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/SceneList.java new file mode 100644 index 000000000..824da5dfe --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/SceneList.java @@ -0,0 +1,540 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.GL30; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.graphics.glutils.FrameBuffer; +import com.badlogic.gdx.graphics.glutils.GLFrameBuffer; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.Event; +import com.badlogic.gdx.scenes.scene2d.EventListener; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup; +import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.ui.TextField; +import com.badlogic.gdx.scenes.scene2d.ui.TextTooltip; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.ScreenUtils; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.World; +import com.bladecoder.engine.util.DPIUtils; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.ElementUtils; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.CellRenderer; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.ModelList; +import com.bladecoder.engineeditor.undo.UndoDeleteScene; +import com.bladecoder.engineeditor.undo.UndoOp; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class SceneList extends ModelList { + + private ImageButton initBtn; + private ImageButton reloadBtn; + private SelectBox chapters; + private HashMap bgIconCache = new HashMap<>(); + private boolean disposeBgCache = false; + private String filterText; + + public SceneList(final Skin skin) { + super(skin, true); + + HorizontalGroup chapterPanel = new HorizontalGroup(); + chapterPanel.padRight(DPIUtils.MARGIN_SIZE); + + chapters = new SelectBox<>(skin); + // chapters.setFillParent(true); + TextButton inkBtn = new TextButton("Ink", skin, "no-toggled"); + + TextTooltip t = new TextTooltip("Sets the Ink Story file", skin); + t.getContainer().pad(DPIUtils.getSpacing() / 2); + inkBtn.addListener(t); + + inkBtn.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + EditInkDialog dialog = new EditInkDialog(skin); + dialog.show(getStage()); + } + }); + + chapterPanel.addActor(new Label("CHAPTER ", skin, "big")); + chapterPanel.addActor(chapters); + chapterPanel.addActor(inkBtn); + + clearChildren(); + + add(chapterPanel).expandX().fillX(); + row(); + add(toolbar).expandX().fillX(); + row().fill(); + add(container).expandY().fill(); + + initBtn = new ImageButton(skin); + toolbar.addToolBarButton(initBtn, "ic_check", "Set init scene", "Set init scene"); + + initBtn.setDisabled(true); + + reloadBtn = new ImageButton(skin); + toolbar.addToolBarButton(reloadBtn, "ic_reload_small", "Reload Assets", "Reload current scene assets"); + + reloadBtn.setDisabled(true); + + TextField tf = toolbar.addFilterBox(new EventListener() { + + @Override + public boolean handle(Event e) { + if (((TextField) e.getTarget()).getText() != filterText) { + filterText = ((TextField) e.getTarget()).getText(); + + addFilteredElements(); + } + + return false; + } + + }); + + filterText = tf.getText(); + + list.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + int pos = list.getSelectedIndex(); + + if (pos == -1) { + Ctx.project.setSelectedScene(null); + } else { + Scene s = list.getItems().get(pos); + + Ctx.project.setSelectedScene(s); + } + + toolbar.disableEdit(pos == -1); + initBtn.setDisabled(pos == -1); + reloadBtn.setDisabled(pos == -1); + } + }); + + list.setCellRenderer(listCellRenderer); + + initBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + setDefault(); + } + + }); + + reloadBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + reloadAssets(); + } + + }); + + chapters.addListener(chapterListener); + chapters.getSelection().setProgrammaticChangeEvents(false); + + Ctx.project.addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + EditorLogger.debug(evt.getPropertyName() + " NEW:" + evt.getNewValue() + " OLD:" + evt.getOldValue()); + + if (evt.getPropertyName().equals(Project.CHAPTER_PROPERTY)) { + addChapters(); + } else if (evt.getPropertyName().equals(Project.NOTIFY_ELEMENT_DELETED)) { + if (evt.getNewValue() instanceof World) { + addChapters(); + } else if (evt.getNewValue() instanceof Scene) { + addFilteredElements(); + } + } else if (evt.getPropertyName().equals(Project.NOTIFY_PROJECT_LOADED)) { + toolbar.disableCreate(!Ctx.project.isLoaded()); + + disposeBgCache = true; + addChapters(); + } else if (evt.getPropertyName().equals(Project.NOTIFY_ELEMENT_CREATED)) { + if (evt.getNewValue() instanceof Scene && !(evt.getSource() instanceof EditSceneDialog)) { + addFilteredElements(); + } + } + } + }); + + } + + ChangeListener chapterListener = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + String selChapter = chapters.getSelected(); + + if (selChapter != null) { + + if (selChapter.equals(Ctx.project.getChapter().getId())) + return; + + // Save the project when changing chapter + try { + Ctx.project.saveProject(); + } catch (IOException e1) { + Message.showMsgDialog(getStage(), "Error saving project", e1.getMessage()); + EditorLogger.error(e1.getMessage()); + } + + try { + + if (selChapter != null) + Ctx.project.loadChapter(selChapter); + + String init = Ctx.project.getEditorConfig().getProperty("project.selectedScene", + Ctx.project.getWorld().getInitScene()); + + addFilteredElements(); + + if (init != null) { + Scene s = Ctx.project.getWorld().getScenes().get(init); + + if (s == null && Ctx.project.getWorld().getInitScene() != null) + s = Ctx.project.getWorld().getScenes().get(Ctx.project.getWorld().getInitScene()); + + if (s != null) { + int indexOf = list.getItems().indexOf(s, true); + list.setSelectedIndex(indexOf); + } + } + } catch (IOException e1) { + String msg = "Something went wrong while loading the project.\n\n" + + e1.getClass().getSimpleName() + + " - " + + e1.getMessage(); + Message.showMsg(getStage(), msg, 3); + + EditorLogger.printStackTrace(e1); + } + } else { + addElements(null, null); + } + } + }; + + public void addChapters() { + Array array = new Array<>(); + + if (Ctx.project.isLoaded()) { + + String[] nl = Ctx.project.getChapter().getChapters(); + + for (int i = 0; i < nl.length; i++) { + array.add(nl[i]); + } + + chapters.setItems(array); + + String init = Ctx.project.getEditorConfig().getProperty("project.selectedChapter", + Ctx.project.getWorld().getInitChapter()); + + if (init != null) { + if (array.contains(init, false)) { + chapters.setSelected(init); + } else if (array.size > 0) { + chapters.setSelected(Ctx.project.getChapter().getInitChapter()); + } + } + } else { + chapters.setItems(array); + } + + chapterListener.changed(null, null); + + invalidate(); + } + + private void addFilteredElements() { + + List filtered = new ArrayList<>(); + + for (Scene s : Ctx.project.getWorld().getScenes().values()) { + if (filterText == null || filterText.isEmpty() || s.getId().contains(filterText)) { + filtered.add(s); + } + } + + addElements(Ctx.project.getWorld(), filtered); + + } + + private void setDefault() { + + int pos = list.getSelectedIndex(); + + if (pos == -1) + return; + + String id = list.getItems().get(pos).getId(); + Ctx.project.getWorld().setInitScene(id); + Ctx.project.setModified(); + } + + private void reloadAssets() { + Ctx.project.setSelectedScene(list.getSelected()); + } + + @Override + protected void delete() { + Scene s = removeSelected(); + + parent.getScenes().remove(s.getId()); + + // delete init_scene attr if the scene to delete is the chapter + // init_scene + if (parent.getInitScene() != null && parent.getInitScene().equals(s.getId())) { + if (parent.getScenes().size() > 0) + parent.setInitScene(parent.getScenes().values().iterator().next().getId()); + else + parent.setInitScene(null); + } + + // TRANSLATIONS + Ctx.project.getI18N().putTranslationsInElement(s); + + // UNDO + UndoOp undoOp = new UndoDeleteScene(s); + Ctx.project.getUndoStack().add(undoOp); + + Ctx.project.setModified(); + } + + @Override + protected void copy() { + Scene e = list.getSelected(); + + if (e == null) + return; + + clipboard = (Scene) ElementUtils.cloneElement(e); + toolbar.disablePaste(false); + + // TRANSLATIONS + Ctx.project.getI18N().putTranslationsInElement(clipboard); + } + + @Override + protected void paste() { + Scene newElement = (Scene) ElementUtils.cloneElement(clipboard); + + newElement.setId(ElementUtils.getCheckedId(newElement.getId(), + Ctx.project.getWorld().getScenes().keySet().toArray(new String[0]))); + + int pos = list.getSelectedIndex() + 1; + + list.getItems().insert(pos, newElement); + + Ctx.project.getWorld().addScene(newElement); + Ctx.project.getI18N().extractStrings(newElement); + + if (parent.getInitScene() == null) { + parent.setInitScene(newElement.getId()); + } + + list.setSelectedIndex(pos); + list.invalidateHierarchy(); + + Ctx.project.setModified(); + } + + @Override + protected EditModelDialog getEditElementDialogInstance(Scene e) { + + EditSceneDialog dialog = new EditSceneDialog(skin, parent, e); + + if (e != null) { + dialog.setListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + Ctx.project.setSelectedScene(list.getSelected()); + } + }); + } + + return dialog; + } + + public TextureRegion getBgIcon(String atlas, String region) { + + // check here for dispose instead in project loading because the opengl + // context lost in new project thread + if (disposeBgCache) { + dispose(); + disposeBgCache = false; + } + + String s = atlas + "#" + region; + TextureRegion icon = bgIconCache.get(s); + + if (icon == null) { + Batch batch = getStage().getBatch(); + + boolean wasDrawing = batch.isDrawing(); + + if (batch.isDrawing()) + batch.end(); + + try { + icon = createBgIcon(atlas, region); + } catch (Exception e) { + EditorLogger.error("Error creating Background icon: " + atlas + "." + region); + } + + if (icon == null) { + EditorLogger.error("Error creating Background icon: " + atlas + "." + region); + icon = Ctx.assetManager.getIcon("ic_no_scene"); + } + + bgIconCache.put(s, icon); + + if (wasDrawing) + batch.begin(); + } + + return icon; + } + + public void dispose() { + for (TextureRegion r : bgIconCache.values()) + r.getTexture().dispose(); + + bgIconCache.clear(); + } + + private TextureRegion createBgIcon(String atlas, String region) { + TextureAtlas a = new TextureAtlas( + Gdx.files.absolute(Ctx.project.getAssetPath() + Project.ATLASES_PATH + "/1/" + atlas + ".atlas")); + AtlasRegion r = a.findRegion(region); + + if (r == null) { + a.dispose(); + return null; + } + + GLFrameBuffer.FrameBufferBuilder frameBufferBuilder = new GLFrameBuffer.FrameBufferBuilder(200, + (int) (r.getRegionHeight() * 200f / r.getRegionWidth())); + + frameBufferBuilder.addColorTextureAttachment(GL30.GL_RGBA8, GL30.GL_RGBA, GL30.GL_UNSIGNED_BYTE); + FrameBuffer fbo = frameBufferBuilder.build(); + + SpriteBatch fboBatch = new SpriteBatch(); + fboBatch.setColor(Color.WHITE); + OrthographicCamera camera = new OrthographicCamera(); + camera.setToOrtho(false, fbo.getWidth(), fbo.getHeight()); + fboBatch.setProjectionMatrix(camera.combined); + + Gdx.gl.glDisable(GL20.GL_SCISSOR_TEST); + fbo.begin(); + fboBatch.begin(); + fboBatch.draw(r, 0, 0, fbo.getWidth(), fbo.getHeight()); + fboBatch.end(); + + TextureRegion tex = ScreenUtils.getFrameBufferTexture(0, 0, fbo.getWidth(), fbo.getHeight()); + // tex.flip(false, true); + + fbo.end(); + Gdx.gl.glEnable(GL20.GL_SCISSOR_TEST); + + fbo.dispose(); + a.dispose(); + fboBatch.dispose(); + + return tex; + } + + // ------------------------------------------------------------------------- + // ListCellRenderer + // ------------------------------------------------------------------------- + private final CellRenderer listCellRenderer = new CellRenderer() { + + @Override + protected String getCellTitle(Scene e) { + String name = e.getId(); + + // TODO SET INIT SCENE + String init = Ctx.project.getWorld().getInitScene(); + + if (name.equals(init)) + name += " "; + + return name; + } + + @Override + protected String getCellSubTitle(Scene e) { + return e.getBackgroundAtlas(); + } + + @Override + public TextureRegion getCellImage(Scene e) { + String atlas = e.getBackgroundAtlas(); + String region = e.getBackgroundRegionId(); + + TextureRegion r = null; + + if (atlas != null && region != null && !atlas.isEmpty() && !region.isEmpty()) { + r = getBgIcon(atlas, region); + } + + if (r == null) + r = Ctx.assetManager.getIcon("ic_no_scene"); + + return r; + } + + @Override + protected boolean hasSubtitle() { + return true; + } + + @Override + protected boolean hasImage() { + return true; + } + }; +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ScenePanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ScenePanel.java similarity index 61% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ScenePanel.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ScenePanel.java index 14e9106cf..7f9a79ba6 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/ScenePanel.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/ScenePanel.java @@ -17,51 +17,56 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; - -import org.w3c.dom.Element; +import java.util.Arrays; import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.Scene; import com.bladecoder.engineeditor.Ctx; -import com.bladecoder.engineeditor.model.ChapterDocument; import com.bladecoder.engineeditor.model.Project; -import com.bladecoder.engineeditor.ui.components.HeaderPanel; -import com.bladecoder.engineeditor.ui.components.TabPanel; +import com.bladecoder.engineeditor.ui.panels.HeaderPanel; +import com.bladecoder.engineeditor.ui.panels.TabPanel; public class ScenePanel extends HeaderPanel { private TabPanel tabPanel; - private VerbList verbList; +// private VerbList verbList; private ActorList actorList; - private SceneProps sceneProps; + private LayerList layerList; +// private SceneProps sceneProps; public ScenePanel(Skin skin) { super(skin, "SCENE"); tabPanel = new TabPanel(skin); - verbList = new VerbList(skin); +// verbList = new VerbList(skin); actorList = new ActorList(skin); - sceneProps = new SceneProps(skin); + layerList = new LayerList(skin); +// sceneProps = new SceneProps(skin); setContent(tabPanel); tabPanel.addTab("Actors", actorList); - tabPanel.addTab("Verbs", verbList); - tabPanel.addTab("Properties", sceneProps); +// tabPanel.addTab("Verbs", verbList); + tabPanel.addTab("Layers", layerList); +// tabPanel.addTab("Scene Props", sceneProps); Ctx.project.addPropertyChangeListener(Project.NOTIFY_SCENE_SELECTED, new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { - ChapterDocument doc = Ctx.project.getSelectedChapter(); - Element scn = Ctx.project.getSelectedScene(); + Scene s = Ctx.project.getSelectedScene(); - if(scn != null) { - setTile("SCENE " + doc.getId(scn)); + if(s != null) { + setTile("SCENE " + s.getId()); + actorList.addElements(s, Arrays.asList(s.getActors().values().toArray(new BaseActor[0]))); + layerList.addElements(s, s.getLayers()); } else { setTile("SCENE"); + actorList.addElements(null, null); + layerList.addElements(null, null); } - actorList.addElements(doc, scn, "actor"); - verbList.addElements(doc, scn, "verb"); - sceneProps.setSceneDocument(doc, scn); +// verbList.addElements(doc, scn, "verb"); +// sceneProps.setSceneDocument(doc, scn); } }); diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/SceneProps.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/SceneProps.java similarity index 60% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/SceneProps.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/SceneProps.java index 109c39cba..b992d69ae 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/SceneProps.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/SceneProps.java @@ -22,8 +22,8 @@ import org.w3c.dom.Element; import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.bladecoder.engineeditor.model.ChapterDocument; -import com.bladecoder.engineeditor.ui.components.PropertyTable; +import com.bladecoder.engineeditor.model.Chapter; +import com.bladecoder.engineeditor.ui.panels.PropertyTable; public class SceneProps extends PropertyTable { public static final String MUSIC_PROP = "Music filename"; @@ -33,7 +33,7 @@ public class SceneProps extends PropertyTable { public static final String INITIAL_MUSIC_DELAY_PROP = "Initial Music Delay"; public static final String REPEAT_MUSIC_DELAY_PROP = "Repeat Music Delay"; - ChapterDocument doc; + Chapter doc; Element scn; // TableModelListener tableModelListener = new TableModelListener() { @@ -59,41 +59,35 @@ public SceneProps(Skin skin) { super(skin); } - public void setSceneDocument(ChapterDocument doc, Element scn) { + public void setSceneDocument(Chapter doc, Element scn) { - this.scn = scn; - this.doc = doc; - - clear(); - - if (scn != null) { - addProperty(BACKGROUND_PROP, doc.getBackground(scn)); - addProperty(LIGHTMAP_PROP, doc.getLightmap(scn)); - addProperty(MUSIC_PROP, doc.getMusic(scn)); - addProperty(LOOP_MUSIC_PROP, doc.getRootAttr(scn,"loop_music"), Types.BOOLEAN); - addProperty(INITIAL_MUSIC_DELAY_PROP, doc.getRootAttr(scn,"initial_music_delay"), Types.FLOAT); - addProperty(REPEAT_MUSIC_DELAY_PROP, doc.getRootAttr(scn,"repeat_music_delay"), Types.FLOAT); - - this.doc.addPropertyChangeListener("scene", propertyChangeListener); - - invalidateHierarchy(); - } +// this.scn = scn; +// this.doc = doc; +// +// clearProps(); +// +// if (scn != null) { +// addProperty(MUSIC_PROP, doc.getMusic(scn)); +// addProperty(LOOP_MUSIC_PROP, doc.getRootAttr(scn,XMLConstants.LOOP_MUSIC_ATTR), Types.BOOLEAN); +// addProperty(INITIAL_MUSIC_DELAY_PROP, doc.getRootAttr(scn, XMLConstants.INITIAL_MUSIC_DELAY_ATTR), Types.FLOAT); +// addProperty(REPEAT_MUSIC_DELAY_PROP, doc.getRootAttr(scn, XMLConstants.REPEAT_MUSIC_DELAY_ATTR), Types.FLOAT); +// +// this.doc.addPropertyChangeListener("scene", propertyChangeListener); +// +// invalidateHierarchy(); +// } } @Override protected void updateModel(String property, String value) { - if (property.equals(MUSIC_PROP)) { - doc.setRootAttr(scn,"music", value); - } else if (property.equals(LOOP_MUSIC_PROP)) { - doc.setRootAttr(scn,"loop_music", value); - } else if (property.equals(BACKGROUND_PROP)) { - doc.setBackground(scn,value); - } else if (property.equals(LIGHTMAP_PROP)) { - doc.setLightmap(scn,value); - } else if (property.equals(INITIAL_MUSIC_DELAY_PROP)) { - doc.setRootAttr(scn,"initial_music_delay", value); - } else if (property.equals(REPEAT_MUSIC_DELAY_PROP)) { - doc.setRootAttr(scn,"repeat_music_delay", value); - } +// if (property.equals(MUSIC_PROP)) { +// doc.setRootAttr(scn,"music", value); +// } else if (property.equals(LOOP_MUSIC_PROP)) { +// doc.setRootAttr(scn, XMLConstants.LOOP_MUSIC_ATTR, value); +// } else if (property.equals(INITIAL_MUSIC_DELAY_PROP)) { +// doc.setRootAttr(scn,XMLConstants.INITIAL_MUSIC_DELAY_ATTR, value); +// } else if (property.equals(REPEAT_MUSIC_DELAY_PROP)) { +// doc.setRootAttr(scn,XMLConstants.REPEAT_MUSIC_DELAY_ATTR, value); +// } } } diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/SoundList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/SoundList.java new file mode 100644 index 000000000..a974b5f56 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/SoundList.java @@ -0,0 +1,194 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.audio.Sound; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.utils.Timer; +import com.badlogic.gdx.utils.Timer.Task; +import com.bladecoder.engine.model.SoundDesc; +import com.bladecoder.engine.model.World; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.ElementUtils; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.CellRenderer; +import com.bladecoder.engineeditor.ui.panels.ModelList; +import com.bladecoder.engineeditor.undo.UndoDeleteSound; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Arrays; + +public class SoundList extends ModelList { + + private ImageButton playBtn; + private Sound playingSound = null; + + public SoundList(Skin skin) { + super(skin, true); + + playBtn = new ImageButton(skin); + toolbar.addToolBarButton(playBtn, "ic_check", "Play Sound", "Plays the selected sound"); + playBtn.setDisabled(true); + + setCellRenderer(listCellRenderer); + + Ctx.project.addPropertyChangeListener(Project.NOTIFY_CHAPTER_LOADED, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + addElements(Ctx.project.getWorld(), + Arrays.asList(Ctx.project.getWorld().getSounds().values().toArray(new SoundDesc[0]))); + } + }); + + list.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + int pos = list.getSelectedIndex(); + + toolbar.disableEdit(pos == -1); + playBtn.setDisabled(pos == -1); + } + }); + + playBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + SoundDesc selected = list.getSelected(); + + if (playingSound != null) { + playingSound.stop(); + playingSound.dispose(); + playingSound = null; + } + + try { + playingSound = Gdx.audio.newSound( + new FileHandle( + Ctx.project.getAssetPath() + Project.SOUND_PATH + "/" + selected.getFilename())); + + playingSound.play(selected.getVolume(), 1, selected.getPan()); + + Timer.schedule(new Task() { + + @Override + public void run() { + if (playingSound != null) { + playingSound.stop(); + playingSound.dispose(); + playingSound = null; + } + } + }, 5); + } catch (Exception e) { + Message.showMsg(getStage(), "Could not play sound: " + e.getMessage(), 4); + } + } + }); + } + + @Override + protected EditSoundDialog getEditElementDialogInstance(SoundDesc s) { + return new EditSoundDialog(skin, parent, s); + } + + @Override + protected void delete() { + + SoundDesc s = removeSelected(); + + parent.getSounds().remove(s.getId()); + + // UNDO + Ctx.project.getUndoStack().add(new UndoDeleteSound(s)); + Ctx.project.setModified(); + } + + @Override + protected void copy() { + SoundDesc e = list.getSelected(); + + if (e == null) + return; + + clipboard = (SoundDesc) ElementUtils.cloneElement(e); + toolbar.disablePaste(false); + } + + @Override + protected void paste() { + SoundDesc newElement = (SoundDesc) ElementUtils.cloneElement(clipboard); + + int pos = list.getSelectedIndex() + 1; + + list.getItems().insert(pos, newElement); + + String id = newElement.getId(); + + if (parent.getSounds() != null) + id = ElementUtils.getCheckedId(newElement.getId(), + parent.getSounds().keySet().toArray(new String[parent.getSounds().size()])); + + newElement.setId(id); + + parent.getSounds().put(newElement.getId(), newElement); + + list.setSelectedIndex(pos); + list.invalidateHierarchy(); + + Ctx.project.setModified(); + } + + // ------------------------------------------------------------------------- + // ListCellRenderer + // ------------------------------------------------------------------------- + private static final CellRenderer listCellRenderer = new CellRenderer() { + + @Override + protected String getCellTitle(SoundDesc e) { + return e.getId(); + } + + StringBuilder sb = new StringBuilder(); + + @Override + protected String getCellSubTitle(SoundDesc e) { + sb.setLength(0); + + String filename = e.getFilename(); + if (filename != null && !filename.isEmpty()) + sb.append("filename: ").append(filename); + + sb.append(" loop: ").append(e.getLoop()); + sb.append(" volume: ").append(e.getVolume()); + + return sb.toString(); + } + + @Override + protected boolean hasSubtitle() { + return true; + } + }; + +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/SpriteList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/SpriteList.java new file mode 100644 index 000000000..dc0796119 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/SpriteList.java @@ -0,0 +1,269 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Arrays; +import java.util.HashMap; + +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.bladecoder.engine.anim.AnimationDesc; +import com.bladecoder.engine.anim.Tween.Type; +import com.bladecoder.engine.model.AnimationRenderer; +import com.bladecoder.engine.model.Dialog; +import com.bladecoder.engine.model.SpriteActor; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.ElementUtils; +import com.bladecoder.engineeditor.common.Message; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.CellRenderer; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.ModelList; +import com.bladecoder.engineeditor.undo.UndoDeleteAnimation; + +public class SpriteList extends ModelList { + + private ImageButton initBtn; + private ImageButton flipInitBtn; + + public SpriteList(Skin skin) { + super(skin, true); + + initBtn = new ImageButton(skin); + toolbar.addToolBarButton(initBtn, "ic_check", "Set init animation", "Set init animation"); + initBtn.setDisabled(true); + + flipInitBtn = new ImageButton(skin); + toolbar.addToolBarButton(flipInitBtn, "ic_flip", "Set init animation flipped", "Set init animation flipped"); + flipInitBtn.setDisabled(true); + + setCellRenderer(listCellRenderer); + + list.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + int pos = list.getSelectedIndex(); + + String id = null; + + if (pos != -1) + id = list.getItems().get(pos).id; + + Ctx.project.setSelectedFA(id); + + toolbar.disableEdit(pos == -1); + initBtn.setDisabled(pos == -1); + flipInitBtn.setDisabled(pos == -1); + } + }); + + initBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + setDefault(); + } + }); + + flipInitBtn.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + flipInit(); + } + }); + + Ctx.project.addPropertyChangeListener(Project.NOTIFY_ELEMENT_CREATED, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getNewValue() instanceof Dialog && !(evt.getSource() instanceof EditDialogDialog) + && parent instanceof SpriteActor) { + HashMap animations = ((AnimationRenderer) parent.getRenderer()) + .getAnimations(); + addElements(parent, Arrays.asList(animations.values().toArray(new AnimationDesc[0]))); + } + } + }); + } + + private void setDefault() { + int pos = list.getSelectedIndex(); + + if (pos == -1) + return; + + AnimationRenderer renderer = (AnimationRenderer) ((SpriteActor) Ctx.project.getSelectedActor()).getRenderer(); + + String id = list.getItems().get(pos).id; + String oldId = renderer.getInitAnimation(); + + renderer.setInitAnimation(id); + + Ctx.project.setModified(this, "init_animation", oldId, id); + } + + private void flipInit() { + int pos = list.getSelectedIndex(); + + if (pos == -1) + return; + + AnimationRenderer renderer = (AnimationRenderer) ((SpriteActor) Ctx.project.getSelectedActor()).getRenderer(); + + String id = list.getItems().get(pos).id; + + String newValue = AnimationRenderer.getFlipId(id); + + renderer.setInitAnimation(newValue); + + Ctx.project.setModified(this, "init_animation", id, newValue); + } + + @Override + protected void delete() { + AnimationDesc d = removeSelected(); + + AnimationRenderer renderer = (AnimationRenderer) parent.getRenderer(); + + renderer.getAnimations().remove(d.id); + + // UNDO + Ctx.project.getUndoStack().add(new UndoDeleteAnimation(parent, d)); + + // delete init_animation attr if the animation to delete is the chapter + // init_animation + if (d.id.equals(renderer.getInitAnimation())) { + HashMap animations = renderer.getAnimations(); + String newValue = null; + + if (animations.size() > 0) + newValue = animations.keySet().iterator().next(); + + renderer.setInitAnimation(newValue); + + Ctx.project.setModified(this, "init_animation", d.id, newValue); + } + + Ctx.project.setModified(); + } + + @Override + protected void copy() { + AnimationDesc e = list.getSelected(); + + if (e == null) + return; + + clipboard = (AnimationDesc) ElementUtils.cloneElement(e); + toolbar.disablePaste(false); + } + + @Override + protected void paste() { + AnimationDesc newElement = (AnimationDesc) ElementUtils.cloneElement(clipboard); + + if (((AnimationRenderer) parent.getRenderer()).getAnimations().get(newElement.id) != null) { + Message.showMsg(getStage(), "Animation already exists.", 2); + + return; + } + + int pos = list.getSelectedIndex() + 1; + + list.getItems().insert(pos, newElement); + + ((AnimationRenderer) parent.getRenderer()).addAnimation(newElement); + + list.setSelectedIndex(pos); + list.invalidateHierarchy(); + + Ctx.project.setModified(); + } + + @Override + protected EditModelDialog getEditElementDialogInstance(AnimationDesc e) { + return new EditAnimationDialog(skin, parent, e); + } + + // ------------------------------------------------------------------------- + // ListCellRenderer + // ------------------------------------------------------------------------- + private final CellRenderer listCellRenderer = new CellRenderer() { + + @Override + protected String getCellTitle(AnimationDesc e) { + String name = e.id; + SpriteActor actor = (SpriteActor) Ctx.project.getSelectedActor(); + AnimationRenderer renderer = (AnimationRenderer) actor.getRenderer(); + + String init = renderer.getInitAnimation(); + + if (init == null || init.isEmpty()) { + if (renderer.getAnimations().values().size() > 0) + init = renderer.getAnimations().values().iterator().next().id; + else + init = ""; + } + + if (init.equals(name) || AnimationRenderer.getFlipId(init).equals(name)) + name += " "; + + return name; + } + + @Override + protected String getCellSubTitle(AnimationDesc e) { + StringBuilder sb = new StringBuilder(); + + if (e.source != null && !e.source.isEmpty()) + sb.append("source: ").append(e.source); + + sb.append(" speed: ").append(e.duration); + sb.append(" count: ").append(e.count); + + return sb.toString(); + } + + @Override + public TextureRegion getCellImage(AnimationDesc a) { + String u = null; + + if (a.animationType == Type.REPEAT) { + u = "ic_repeat"; + } else if (a.animationType == Type.YOYO) { + u = "ic_yoyo"; + } else { + u = "ic_sprite_actor"; + } + + return Ctx.assetManager.getIcon(u); + } + + @Override + protected boolean hasSubtitle() { + return true; + } + + @Override + protected boolean hasImage() { + return true; + } + }; +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/VerbList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/VerbList.java new file mode 100644 index 000000000..c3893020e --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/VerbList.java @@ -0,0 +1,294 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.List; + +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.InteractiveActor; +import com.bladecoder.engine.model.Verb; +import com.bladecoder.engine.model.VerbManager; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.common.ElementUtils; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.CellRenderer; +import com.bladecoder.engineeditor.ui.panels.EditModelDialog; +import com.bladecoder.engineeditor.ui.panels.ModelList; +import com.bladecoder.engineeditor.ui.panels.ScopePanel; +import com.bladecoder.engineeditor.undo.UndoDeleteVerb; + +public class VerbList extends ModelList { + + public static final String VERBS[] = { "lookat", "pickup", "talkto", "use", "leave", "enter", "exit", "init", + "test", "custom" }; + + private ActionList actionList; + + private ScopePanel scopePanel; + + public VerbList(Skin skin) { + super(skin, true); + + clearChildren(); + + scopePanel = new ScopePanel(skin) { + + @Override + public void scopeChanged(String scope) { + if (WORLD_SCOPE.equals(scope)) { + addElements(Ctx.project.getWorld().getVerbManager(), Arrays + .asList(Ctx.project.getWorld().getVerbManager().getVerbs().values().toArray(new Verb[0]))); + } else if (SCENE_SCOPE.equals(scope)) { + if (Ctx.project.getSelectedScene() != null) + addElements(Ctx.project.getSelectedScene().getVerbManager(), Arrays.asList(Ctx.project + .getSelectedScene().getVerbManager().getVerbs().values().toArray(new Verb[0]))); + else + addElements(null, null); + } else if (ACTOR_SCOPE.equals(scope)) { + BaseActor a = Ctx.project.getSelectedActor(); + if (a instanceof InteractiveActor) { + addElements(((InteractiveActor) a).getVerbManager(), Arrays.asList( + ((InteractiveActor) a).getVerbManager().getVerbs().values().toArray(new Verb[0]))); + } else { + addElements(null, null); + } + } + } + }; + + add(scopePanel).expandX().fillX(); + row(); + add(toolbar).expandX().fillX(); + row().fill(); + add(container).expandY().fill(); + + actionList = new ActionList(skin); + + row(); + add(actionList).expand().fill(); + + list.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + addActions(); + } + }); + + list.setCellRenderer(listCellRenderer); + listCellRenderer.layout(list.getStyle()); + container.minHeight(listCellRenderer.getItemHeight() * 5); + container.maxHeight(listCellRenderer.getItemHeight() * 5); + + Ctx.project.addPropertyChangeListener(Project.NOTIFY_ELEMENT_CREATED, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getNewValue() instanceof Verb && !(evt.getSource() instanceof EditVerbDialog)) { + if (ScopePanel.WORLD_SCOPE.equals(scopePanel.getScope())) { + addElements(Ctx.project.getWorld().getVerbManager(), Arrays.asList( + Ctx.project.getWorld().getVerbManager().getVerbs().values().toArray(new Verb[0]))); + } else if (ScopePanel.SCENE_SCOPE.equals(scopePanel.getScope())) { + addElements(Ctx.project.getSelectedScene().getVerbManager(), Arrays.asList(Ctx.project + .getSelectedScene().getVerbManager().getVerbs().values().toArray(new Verb[0]))); + } else if (ScopePanel.ACTOR_SCOPE.equals(scopePanel.getScope())) { + BaseActor a = Ctx.project.getSelectedActor(); + if (a instanceof InteractiveActor) { + addElements(((InteractiveActor) a).getVerbManager(), Arrays.asList( + ((InteractiveActor) a).getVerbManager().getVerbs().values().toArray(new Verb[0]))); + } else { + addElements(null, null); + } + } + } + } + }); + } + + public void changeActor() { + scopePanel.scopeChanged(scopePanel.getScope()); + } + + @Override + protected EditModelDialog getEditElementDialogInstance(Verb e) { + return new EditVerbDialog(skin, scopePanel.getScope(), parent, e); + } + + @Override + public void addElements(VerbManager vm, List elements) { + super.addElements(vm, elements); + addActions(); + } + + @Override + protected void delete() { + + Verb v = removeSelected(); + + parent.getVerbs().remove(v.getHashKey()); + + // TRANSLATIONS + if (scopePanel.getScope().equals(ScopePanel.WORLD_SCOPE)) + Ctx.project.getI18N().putTranslationsInElement(v, true); + else + Ctx.project.getI18N().putTranslationsInElement(v, false); + + // UNDO + Ctx.project.getUndoStack().add(new UndoDeleteVerb(parent, v)); + + // Clear actions here because change event doesn't call when deleting + // the last element + if (list.getSelectedIndex() == -1) + addActions(); + + Ctx.project.setModified(); + } + + @Override + protected void copy() { + Verb e = list.getSelected(); + + if (e == null) + return; + + clipboard = (Verb) ElementUtils.cloneElement(e); + toolbar.disablePaste(false); + + // TRANSLATIONS + if (scopePanel.getScope().equals(ScopePanel.WORLD_SCOPE)) + Ctx.project.getI18N().putTranslationsInElement(clipboard, true); + else + Ctx.project.getI18N().putTranslationsInElement(clipboard, false); + } + + @Override + protected void paste() { + Verb newElement = (Verb) ElementUtils.cloneElement(clipboard); + + // Check for id duplicates + String[] keys = new String[parent.getVerbs().size()]; + Verb[] values = parent.getVerbs().values().toArray(new Verb[0]); + + for (int i = 0; i < keys.length; i++) { + keys[i] = values[i].getId(); + } + + newElement.setId(ElementUtils.getCheckedId(newElement.getId(), keys)); + + int pos = list.getSelectedIndex() + 1; + + list.getItems().insert(pos, newElement); + + parent.addVerb(newElement); + + if (scopePanel.getScope().equals(ScopePanel.WORLD_SCOPE)) + Ctx.project.getI18N().extractStrings(null, null, newElement); + else if (scopePanel.getScope().equals(ScopePanel.SCENE_SCOPE)) + Ctx.project.getI18N().extractStrings(Ctx.project.getSelectedScene().getId(), null, newElement); + else + Ctx.project.getI18N().extractStrings(Ctx.project.getSelectedScene().getId(), + Ctx.project.getSelectedActor().getId(), newElement); + + list.setSelectedIndex(pos); + list.invalidateHierarchy(); + + Ctx.project.setModified(); + } + + private void addActions() { + int pos = list.getSelectedIndex(); + + Verb v = null; + + if (pos != -1) { + v = list.getItems().get(pos); + actionList.setScope(scopePanel.getScope()); + actionList.addElements(v, v.getActions()); + } else { + actionList.addElements(null, null); + actionList.setScope(null); + } + } + + // ------------------------------------------------------------------------- + // ListCellRenderer + // ------------------------------------------------------------------------- + private final CellRenderer listCellRenderer = new CellRenderer() { + + @Override + protected String getCellTitle(Verb e) { + return e.getId(); + } + + @Override + protected String getCellSubTitle(Verb e) { + String state = e.getState(); + String target = e.getTarget(); + + StringBuilder sb = new StringBuilder(); + + if (state != null) + sb.append("when ").append(state); + + if (target != null) + sb.append(" target: '").append(target).append("'"); + + if (e.getIcon() != null) + sb.append(" icon: '").append(e.getIcon()).append("'"); + + return sb.toString(); + } + + @Override + public TextureRegion getCellImage(Verb e) { + boolean custom = true; + + String verbName = e.getId(); + for (String v : VERBS) { + if (v.equals(verbName)) { + custom = false; + break; + } + } + + String iconName = MessageFormat.format("ic_{0}", e.getId()); + TextureRegion image = null; + + if (!custom) + image = Ctx.assetManager.getIcon(iconName); + else + image = Ctx.assetManager.getIcon("ic_custom"); + + return image; + } + + @Override + protected boolean hasSubtitle() { + return true; + } + + @Override + protected boolean hasImage() { + return true; + } + }; +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/WorldProps.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/WorldProps.java new file mode 100644 index 000000000..213d3f20a --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/WorldProps.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Locale; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.bladecoder.engine.util.Config; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.model.Project; +import com.bladecoder.engineeditor.ui.panels.PropertyTable; + +public class WorldProps extends PropertyTable { + public WorldProps(Skin skin) { + super(skin); + + Ctx.project.addPropertyChangeListener(Project.NOTIFY_PROJECT_LOADED, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent arg0) { + setProject(); + } + }); + } + + @Override + protected void updateModel(String property, String value) { + if (property.equals(Project.WIDTH_PROPERTY)) { + Ctx.project.getWorld().setWidth(Integer.parseInt(value)); + } else if (property.equals(Config.TITLE_PROP)) { + Ctx.project.getProjectConfig().setProperty(Config.TITLE_PROP, value); + } else if (property.equals(Project.HEIGHT_PROPERTY)) { + Ctx.project.getWorld().setHeight(Integer.parseInt(value)); + } else if (property.equals(Config.INVENTORY_POS_PROP)) { + Ctx.project.getProjectConfig().setProperty(Config.INVENTORY_POS_PROP, value); + } else if (property.equals(Config.INVENTORY_AUTOSIZE_PROP)) { + Ctx.project.getProjectConfig().setProperty(Config.INVENTORY_AUTOSIZE_PROP, value); + } else if (property.equals(Config.UI_MODE)) { + Ctx.project.getProjectConfig().setProperty(Config.UI_MODE, value); + } else if (property.equals(Config.SINGLE_ACTION_INVENTORY)) { + Ctx.project.getProjectConfig().setProperty(Config.SINGLE_ACTION_INVENTORY, value); + } else if (property.equals(Config.FAST_LEAVE)) { + Ctx.project.getProjectConfig().setProperty(Config.FAST_LEAVE, value); + } else if (property.equals(Config.DEBUG_PROP)) { + Ctx.project.getProjectConfig().setProperty(Config.DEBUG_PROP, value); + } else if (property.equals(Config.CHARACTER_ICON_ATLAS)) { + Ctx.project.getProjectConfig().setProperty(Config.CHARACTER_ICON_ATLAS, value); + } else if (property.equals(Config.SHOW_DESC_PROP)) { + Ctx.project.getProjectConfig().setProperty(Config.SHOW_DESC_PROP, value); + } else if (property.equals(Config.AUTO_HIDE_TEXTS)) { + Ctx.project.getProjectConfig().setProperty(Config.AUTO_HIDE_TEXTS, value); + } else if (property.equals(Config.EXTEND_VIEWPORT_PROP)) { + Ctx.project.getProjectConfig().setProperty(Config.EXTEND_VIEWPORT_PROP, value); + } else if (property.equals(Config.SHOW_HOTSPOTS)) { + Ctx.project.getProjectConfig().setProperty(Config.SHOW_HOTSPOTS, value); + } + + Ctx.project.setModified(); // TODO Add propertychange to Config + } + + private void setProject() { + clearProps(); + + if (Ctx.project.isLoaded()) { + addProperty(Project.WIDTH_PROPERTY, Ctx.project.getWorld().getWidth()); + addProperty(Project.HEIGHT_PROPERTY, Ctx.project.getWorld().getHeight()); + addProperty(Config.TITLE_PROP, Ctx.project.getTitle()); + addProperty( + Config.INVENTORY_POS_PROP, Ctx.project.getProjectConfig() + .getProperty(Config.INVENTORY_POS_PROP, "DOWN").toUpperCase(Locale.ENGLISH), + new String[] { "TOP", "DOWN", "LEFT", "RIGHT", "CENTER" }); + addProperty(Config.INVENTORY_AUTOSIZE_PROP, Boolean + .parseBoolean(Ctx.project.getProjectConfig().getProperty(Config.INVENTORY_AUTOSIZE_PROP, "true"))); + addProperty(Config.UI_MODE, Ctx.project.getProjectConfig().getProperty(Config.UI_MODE, "TWO_BUTTONS") + .toUpperCase(Locale.ENGLISH), new String[] { "TWO_BUTTONS", "PIE", "SINGLE_CLICK" }); + addProperty(Config.SINGLE_ACTION_INVENTORY, Boolean + .parseBoolean(Ctx.project.getProjectConfig().getProperty(Config.SINGLE_ACTION_INVENTORY, "false"))); + addProperty(Config.FAST_LEAVE, + Boolean.parseBoolean(Ctx.project.getProjectConfig().getProperty(Config.FAST_LEAVE, "false"))); + addProperty(Config.DEBUG_PROP, + Boolean.parseBoolean(Ctx.project.getProjectConfig().getProperty(Config.DEBUG_PROP, "false"))); + addProperty(Config.SHOW_DESC_PROP, + Boolean.parseBoolean(Ctx.project.getProjectConfig().getProperty(Config.SHOW_DESC_PROP, "true"))); + addProperty(Config.AUTO_HIDE_TEXTS, + Boolean.parseBoolean(Ctx.project.getProjectConfig().getProperty(Config.AUTO_HIDE_TEXTS, "true"))); + addProperty(Config.CHARACTER_ICON_ATLAS, + Ctx.project.getProjectConfig().getProperty(Config.CHARACTER_ICON_ATLAS, "")); + addProperty(Config.EXTEND_VIEWPORT_PROP, Boolean + .parseBoolean(Ctx.project.getProjectConfig().getProperty(Config.EXTEND_VIEWPORT_PROP, "false"))); + addProperty(Config.SHOW_HOTSPOTS, + Boolean.parseBoolean(Ctx.project.getProjectConfig().getProperty(Config.SHOW_HOTSPOTS, "true"))); + } + + invalidateHierarchy(); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ActorAnimationInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ActorAnimationInputPanel.java new file mode 100644 index 000000000..5b817feeb --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ActorAnimationInputPanel.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; + +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.bladecoder.engine.actions.ActorAnimationRef; +import com.bladecoder.engine.anim.AnimationDesc; +import com.bladecoder.engine.model.AnimationRenderer; +import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.SpriteActor; +import com.bladecoder.engineeditor.Ctx; + +public class ActorAnimationInputPanel extends InputPanel { + EditableSelectBox animation; + EditableSelectBox actor; + Table panel; + + ActorAnimationInputPanel(Skin skin, String title, String desc, + boolean mandatory, String defaultValue) { + panel = new Table(skin); + animation = new EditableSelectBox<>(skin); + actor = new EditableSelectBox<>(skin); + + panel.add(new Label(" Actor ", skin)); + panel.add(actor); + panel.add(new Label(" Animation ", skin)); + panel.add(animation); + + + ArrayList values = new ArrayList(); + + // values.add(""); + + for (BaseActor a: Ctx.project.getSelectedScene().getActors().values()) { + + if (a instanceof SpriteActor) { + values.add(a.getId()); + } + } + + values.add(Scene.VAR_PLAYER); + + actor.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + actorSelected(); + } + }); + + init(skin, title, desc, panel, mandatory, defaultValue); + String[] array = values.toArray(new String[values.size()]); + Arrays.sort(array); + actor.setItems(array); + + if (values.size() > 0) { + if (defaultValue != null) + setText(defaultValue); + else + actor.setSelected(""); + } + + } + + private void actorSelected() { + String s = actor.getSelected(); + SpriteActor a = null; + + if(Ctx.project.getSelectedActor() instanceof SpriteActor) + a = (SpriteActor) Ctx.project.getSelectedActor(); + + ArrayList values = new ArrayList(); + + if (s != null && !s.isEmpty()) { + a = (SpriteActor)Ctx.project.getSelectedScene().getActor(s, false); + } + + if (a != null && a.getRenderer() instanceof AnimationRenderer) { + + HashMap animations = ((AnimationRenderer)a.getRenderer()).getAnimations(); + + if (!isMandatory()) { + values.add(""); + } + + for (AnimationDesc anim:animations.values()) { + values.add(anim.id); + + String flipped = AnimationRenderer.getFlipId(anim.id); + + if (!flipped.isEmpty()) { + values.add(flipped); + } + } + } + + String[] array = values.toArray(new String[values.size()]); + Arrays.sort(array); + animation.setItems(array); + + if (values.size() > 0) + animation.setSelected(""); + + } + + public String getText() { + + String selectedActor = !actor.getSelected().isEmpty() ? actor.getSelected():Ctx.project.getSelectedActor().getId(); + + return (new ActorAnimationRef(selectedActor, animation.getSelected())).toString(); + } + + public void setText(String s) { + ActorAnimationRef aa = new ActorAnimationRef(s); + + actor.setSelected(aa.getActorId() == null?"":aa.getActorId()); + actorSelected(); + animation.setSelected(aa.getAnimationId()); + } + + @Override + public boolean validateField() { + + ActorAnimationRef a = new ActorAnimationRef(getText()); + + if(isMandatory()) { + if(a.getActorId() == null || a.getActorId().trim().isEmpty() || + a.getAnimationId() == null || a.getAnimationId().trim().isEmpty()) { + setError(true); + return false; + } + } + + setError(false); + return true; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ActorInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ActorInputPanel.java new file mode 100644 index 000000000..5e4e86af8 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ActorInputPanel.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Map; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.CharacterActor; +import com.bladecoder.engine.model.InteractiveActor; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.SpriteActor; +import com.bladecoder.engine.model.WalkZoneActor; +import com.bladecoder.engineeditor.Ctx; + +public class ActorInputPanel extends EditableOptionsInputPanel { + + ActorInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue, Param.Type type) { + super(skin, title, desc, mandatory, defaultValue, getValues(mandatory, type)); + + if (mandatory) + if (type == Param.Type.ACTOR) + setText(Ctx.project.getSelectedActor().getId()); + else + input.setSelectedIndex(0); + } + + private static String[] getValues(boolean mandatory, Param.Type type) { + + ArrayList filteredActors = new ArrayList<>(); + + if (Ctx.project.getSelectedScene() != null) { + Map actors = Ctx.project.getSelectedScene().getActors(); + + for (BaseActor a : actors.values()) { + if (type == Param.Type.CHARACTER_ACTOR) { + if (a instanceof CharacterActor) + filteredActors.add(a); + } else if (type == Param.Type.INTERACTIVE_ACTOR) { + if (a instanceof InteractiveActor) + filteredActors.add(a); + } else if (type == Param.Type.WALKZONE_ACTOR) { + if (a instanceof WalkZoneActor) + filteredActors.add(a); + } else if (type == Param.Type.SPRITE_ACTOR) { + if (a instanceof SpriteActor) + filteredActors.add(a); + } else { + filteredActors.add(a); + } + } + } + + String[] result = null; + + if (type != Param.Type.WALKZONE_ACTOR) { + // Add player variable to the list + result = new String[filteredActors.size() + 1]; + + result[0] = Scene.VAR_PLAYER; + + for (int i = 0; i < filteredActors.size(); i++) { + result[i + 1] = filteredActors.get(i).getId(); + } + } else { + result = new String[filteredActors.size()]; + + for (int i = 0; i < filteredActors.size(); i++) { + result[i] = filteredActors.get(i).getId(); + } + + } + + Arrays.sort(result); + return result; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/BooleanInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/BooleanInputPanel.java new file mode 100644 index 000000000..89bc7c462 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/BooleanInputPanel.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; + +public class BooleanInputPanel extends StringOptionsInputPanel { + private static final String[] booleanValues = {"true", "false"}; + + BooleanInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue) { + super(skin, title, desc, mandatory, defaultValue, booleanValues); + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/CellRenderer.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/CellRenderer.java similarity index 64% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/CellRenderer.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/CellRenderer.java index 7de907621..7f95dfd73 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/CellRenderer.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/CellRenderer.java @@ -13,101 +13,102 @@ * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ -package com.bladecoder.engineeditor.ui.components; +package com.bladecoder.engineeditor.ui.panels; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.utils.Drawable; -import com.bladecoder.engineeditor.ui.components.CustomList.CustomListStyle; +import com.bladecoder.engineeditor.ui.panels.CustomList.CustomListStyle; public class CellRenderer { private static final float MARGIN = 10; - + private CustomListStyle style; private float itemHeight; private float textOffsetX, textOffsetY; - public CellRenderer() { + public CellRenderer() { } - public void draw(Batch batch, float parentAlpha, T item, boolean selected, float x, float y, float width, float height) { + public void draw(Batch batch, float parentAlpha, T item, boolean selected, float x, float y, float width, + float height) { BitmapFont font = style.font; Drawable selectedDrawable = style.selection; Color fontColorSelected = style.fontColorSelected; Color fontColorUnselected = style.fontColorUnselected; - - - + if (selected) { - selectedDrawable.draw(batch, x, - y - height, width, - height); - font.setColor(fontColorSelected.r, fontColorSelected.g, - fontColorSelected.b, fontColorSelected.a * parentAlpha); + selectedDrawable.draw(batch, x, y - height, width, height); + font.setColor(fontColorSelected.r, fontColorSelected.g, fontColorSelected.b, + fontColorSelected.a * parentAlpha); } else { - font.setColor(fontColorUnselected.r, fontColorUnselected.g, fontColorUnselected.b, fontColorUnselected.a * parentAlpha); + font.setColor(fontColorUnselected.r, fontColorUnselected.g, fontColorUnselected.b, + fontColorUnselected.a * parentAlpha); } - - if(hasImage()) { + + if (hasImage()) { TextureRegion r = getCellImage(item); - + float ih = r.getRegionHeight(); float iw = r.getRegionWidth(); - - if(ih > getItemHeight() - MARGIN) { + + if (ih > getItemHeight() - MARGIN) { ih = getItemHeight() - MARGIN; iw *= ih / r.getRegionHeight(); } - - batch.draw(r, x, y - ih - MARGIN/2, iw, ih); + + batch.draw(r, x, y - ih - MARGIN / 2, iw, ih); x += iw; } - - - font.draw(batch, getCellTitle(item), x + textOffsetX, - y - textOffsetY); - - if(hasSubtitle()) { - if (selected) { - style.subtitleFont.setColor(fontColorSelected.r, fontColorSelected.g, - fontColorSelected.b, fontColorSelected.a * parentAlpha * 0.5f); - } else { - style.subtitleFont.setColor(fontColorUnselected.r, fontColorUnselected.g, fontColorUnselected.b, fontColorUnselected.a * parentAlpha * 0.5f); - } - - style.subtitleFont.draw(batch, getCellSubTitle(item), x + textOffsetX, - y - textOffsetY - (font.getCapHeight() - font.getDescent() * 2)); + + font.draw(batch, getCellTitle(item), x + textOffsetX, y - textOffsetY); + + if (hasSubtitle()) { + String sub = getCellSubTitle(item); + + if (sub != null) { + if (selected) { + style.subtitleFont.setColor(fontColorSelected.r, fontColorSelected.g, fontColorSelected.b, + fontColorSelected.a * parentAlpha * 0.5f); + } else { + style.subtitleFont.setColor(fontColorUnselected.r, fontColorUnselected.g, fontColorUnselected.b, + fontColorUnselected.a * parentAlpha * 0.5f); + } + + style.subtitleFont.draw(batch, sub, x + textOffsetX, + y - textOffsetY - (font.getCapHeight() - font.getDescent() * 2)); + } } } - + protected boolean hasSubtitle() { return false; } - + protected boolean hasImage() { return false; } - + public void layout(CustomListStyle style) { this.style = style; - + BitmapFont font = style.font; Drawable selectedDrawable = style.selection; textOffsetX = selectedDrawable.getLeftWidth(); textOffsetY = selectedDrawable.getTopHeight() - font.getDescent(); - + itemHeight = font.getCapHeight() - font.getDescent() * 2; - - if(hasSubtitle()) { - itemHeight += style.subtitleFont.getCapHeight() - style.subtitleFont.getDescent() * 2;; + + if (hasSubtitle()) { + itemHeight += style.subtitleFont.getCapHeight() - style.subtitleFont.getDescent() * 2; + ; } - - itemHeight += selectedDrawable.getTopHeight() - + selectedDrawable.getBottomHeight(); - } + + itemHeight += selectedDrawable.getTopHeight() + selectedDrawable.getBottomHeight(); + } public float getItemHeight() { return itemHeight; diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ChapterInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ChapterInputPanel.java new file mode 100644 index 000000000..acd66cfd9 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ChapterInputPanel.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.bladecoder.engineeditor.Ctx; + +public class ChapterInputPanel extends StringOptionsInputPanel { + ChapterInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue) { + super(skin, title, desc, mandatory, defaultValue, Ctx.project.getChapter().getChapters()); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ColorInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ColorInputPanel.java new file mode 100644 index 000000000..fc58eddf7 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ColorInputPanel.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.bladecoder.engine.actions.Param; +import com.kotcrab.vis.ui.widget.color.ColorPicker; +import com.kotcrab.vis.ui.widget.color.ColorPickerAdapter; + +public class ColorInputPanel extends InputPanel { + + private final static String SELECT_TEXT = "Select Color"; + + private ColorPicker colorPicker; + private TextButton button; + private Color selected; + + private TextButtonStyle buttonStyle; + private TextButtonStyle oldButtonStyle; + + public ColorInputPanel(Skin skin, String title, String desc) { + this(skin, title, desc, false, null); + } + + public ColorInputPanel(Skin skin, String title, String desc, boolean mandatory) { + this(skin, title, desc, mandatory, null); + } + + public ColorInputPanel(Skin skin, String title, String desc, boolean mandatory, String current ) { + + Table t = new Table(); + + oldButtonStyle = skin.get("no-toggled", TextButtonStyle.class); + buttonStyle = new TextButtonStyle(oldButtonStyle); + + buttonStyle.up = skin.newDrawable("white_pixel", Color.WHITE); + + button = new TextButton(SELECT_TEXT, buttonStyle); + + t.add(button); + + init(skin, title, desc, t, + mandatory, null); + + colorPicker = new ColorPicker(new ColorPickerAdapter() { + @Override + public void finished (Color newColor) { + setText(newColor.toString()); + } + }); + + + button.addListener(new ClickListener() { + public void clicked(InputEvent event, float x, float y) { + if(selected != null) + colorPicker.setColor(selected); + + //displaying picker with fade in animation + getStage().addActor(colorPicker.fadeIn()); + } + }); + + setText(current); + + // Adds clear button if not mandatory + if(!mandatory) { + TextButton clearButton = new TextButton("Clear", skin, "no-toggled"); + + clearButton.addListener(new ClickListener() { + public void clicked(InputEvent event, float x, float y) { + setText(null); + } + }); + + t.add(clearButton); + } + } + + @Override + public String getText() { + return selected==null?null:selected.toString(); + } + + @Override + public void setText(String text) { + selected = Param.parseColor(text); + + if(selected != null) { + button.setText(text); + button.setColor(selected); + button.setStyle(buttonStyle); + } else { + button.setText(SELECT_TEXT); + button.setColor(Color.WHITE); + button.setStyle(oldButtonStyle); + } + } + +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/CustomList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/CustomList.java similarity index 81% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/CustomList.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/CustomList.java index 61319740a..811fe09cf 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/CustomList.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/CustomList.java @@ -13,13 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ -package com.bladecoder.engineeditor.ui.components; +package com.bladecoder.engineeditor.ui.panels; + +import java.util.Comparator; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.InputListener; @@ -52,7 +54,7 @@ public class CustomList extends Widget implements Cullable { public CustomList(Skin skin, CellRenderer r) { this(skin.get(CustomListStyle.class), r); } - + public CustomList(Skin skin) { this(skin.get(CustomListStyle.class), new CellRenderer()); } @@ -65,15 +67,14 @@ public CustomList(CustomListStyle style, CellRenderer r) { selection = new ArraySelection(items); selection.setActor(this); selection.setRequired(true); - + cellRenderer = r; setStyle(style); setSize(getPrefWidth(), getPrefHeight()); addListener(new InputListener() { - public boolean touchDown(InputEvent event, float x, float y, - int pointer, int button) { + public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { if (pointer == 0 && button != 0) return false; if (selection.isDisabled()) @@ -85,16 +86,15 @@ public boolean touchDown(InputEvent event, float x, float y, } public void setCellRenderer(CellRenderer r) { - cellRenderer = r; + cellRenderer = r; } - + void touchDown(float y) { if (items.size == 0) return; float height = getHeight(); if (style.background != null) { - height -= style.background.getTopHeight() - + style.background.getBottomHeight(); + height -= style.background.getTopHeight() + style.background.getBottomHeight(); y -= style.background.getBottomHeight(); } int index = (int) ((height - y) / cellRenderer.getItemHeight()); @@ -120,50 +120,57 @@ public CustomListStyle getStyle() { public void layout() { final BitmapFont font = style.font; + final BitmapFont subfont = style.subtitleFont; final Drawable selectedDrawable = style.selection; - + cellRenderer.layout(style); + GlyphLayout textLayout = new GlyphLayout(); + prefWidth = 0; for (int i = 0; i < items.size; i++) { - TextBounds bounds = font.getBounds(cellRenderer.getCellTitle(items.get(i))); - prefWidth = Math.max(bounds.width, prefWidth); - - if(cellRenderer.hasSubtitle()) { - bounds = font.getBounds(cellRenderer.getCellSubTitle(items.get(i))); - prefWidth = Math.max(bounds.width, prefWidth); - } + + textLayout.setText(font, cellRenderer.getCellTitle(items.get(i))); + + prefWidth = Math.max(textLayout.width, prefWidth); - if(cellRenderer.hasImage()) { + if (cellRenderer.hasImage()) { TextureRegion r = cellRenderer.getCellImage(items.get(i)); - + float ih = r.getRegionHeight(); float iw = r.getRegionWidth(); - - if(ih > getItemHeight() - 10) { + + if (ih > getItemHeight() - 10) { ih = getItemHeight() - 10; iw *= ih / r.getRegionHeight(); } - - prefWidth = Math.max(iw, prefWidth); + + prefWidth = Math.max(iw + textLayout.width, prefWidth); + } + + if (cellRenderer.hasSubtitle()) { + String subtitle = cellRenderer.getCellSubTitle(items.get(i)); + + if (subtitle != null) { + textLayout.setText(subfont, subtitle); + prefWidth = Math.max(textLayout.width, prefWidth); + } } } - prefWidth += selectedDrawable.getLeftWidth() - + selectedDrawable.getRightWidth(); - + prefWidth += selectedDrawable.getLeftWidth() + selectedDrawable.getRightWidth(); + prefHeight = items.size * cellRenderer.getItemHeight(); Drawable background = style.background; if (background != null) { prefWidth += background.getLeftWidth() + background.getRightWidth(); - prefHeight += background.getTopHeight() - + background.getBottomHeight(); + prefHeight += background.getTopHeight() + background.getBottomHeight(); } } @Override - public void draw (Batch batch, float parentAlpha) { + public void draw(Batch batch, float parentAlpha) { validate(); Color color = getColor(); @@ -182,18 +189,36 @@ public void draw (Batch batch, float parentAlpha) { } for (int i = 0; i < items.size; i++) { - if (cullingArea == null || (itemY - cellRenderer.getItemHeight() <= cullingArea.y + cullingArea.height && itemY >= cullingArea.y)) { + if (cullingArea == null || (itemY - cellRenderer.getItemHeight() <= cullingArea.y + cullingArea.height + && itemY >= cullingArea.y)) { T item = items.get(i); boolean selected = selection.contains(item); - - cellRenderer.draw(batch, parentAlpha, item, selected, x, y + itemY, width, cellRenderer.getItemHeight()); - + + cellRenderer.draw(batch, parentAlpha, item, selected, x, y + itemY, width, + cellRenderer.getItemHeight()); + } else if (itemY < cullingArea.y) { break; } itemY -= cellRenderer.getItemHeight(); } } + + public void sortByTitle() { + getItems().sort(new Comparator() { + @Override + public int compare(T o1, T o2) { + String s1 = cellRenderer.getCellTitle(o1); + String s2 = cellRenderer.getCellTitle(o2); + + if(s1 == null) { + System.out.println("nul"); + } + + return s1.compareTo(s2); + } + }); + } public ArraySelection getSelection() { return selection; @@ -205,8 +230,8 @@ public T getSelected() { } /** - * @return The index of the first selected item. The top item has an index of - * 0. Nothing selected has an index of -1. + * @return The index of the first selected item. The top item has an index + * of 0. Nothing selected has an index of -1. */ public int getSelectedIndex() { ObjectSet selected = selection.items(); @@ -216,26 +241,10 @@ public int getSelectedIndex() { /** Sets the selection to only the selected index. */ public void setSelectedIndex(int index) { if (index < -1 || index >= items.size) - throw new IllegalArgumentException("index must be >= -1 and < " - + items.size + ": " + index); + throw new IllegalArgumentException("index must be >= -1 and < " + items.size + ": " + index); selection.set(items.get(index)); } - public void setItems(T... newItems) { - if (newItems == null) - throw new IllegalArgumentException("newItems cannot be null."); - - items.clear(); - items.addAll(newItems); - - if (selection.getRequired() && items.size > 0) - selection.set(items.first()); - else - selection.clear(); - - invalidateHierarchy(); - } - /** * Sets the current items, clearing the selection if it is no longer valid. * If a selection is {@link ArraySelection#getRequired()}, the first item is @@ -299,8 +308,8 @@ static public class CustomListStyle { public CustomListStyle() { } - public CustomListStyle(BitmapFont font, Color fontColorSelected, - Color fontColorUnselected, Drawable selection) { + public CustomListStyle(BitmapFont font, Color fontColorSelected, Color fontColorUnselected, + Drawable selection) { this.font = font; this.fontColorSelected.set(fontColorSelected); this.fontColorUnselected.set(fontColorUnselected); diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/DimPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/DimensionInputPanel.java similarity index 72% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/DimPanel.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/DimensionInputPanel.java index 665520021..cf5b4b823 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/DimPanel.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/DimensionInputPanel.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ -package com.bladecoder.engineeditor.ui.components; +package com.bladecoder.engineeditor.ui.panels; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.ui.Label; @@ -22,19 +22,22 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextField; import com.bladecoder.engine.actions.Param; -public class DimPanel extends Table { - +public class DimensionInputPanel extends InputPanel { TextField width; TextField height; - - public DimPanel(Skin skin) { + Table dimPanel; + + DimensionInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue) { + dimPanel = new Table(skin); width = new TextField("", skin); height = new TextField("", skin); - add(new Label(" width ", skin)); - add(width); - add(new Label(" height ", skin)); - add(height); + dimPanel.add(new Label(" width ", skin)); + dimPanel.add(width); + dimPanel.add(new Label(" height ", skin)); + dimPanel.add(height); + + init(skin, title, desc, dimPanel, mandatory, defaultValue); } public String getText() { @@ -57,13 +60,28 @@ public void setText(String s) { } public boolean validateField() { + + String s = getText(); + + if(s == null || s.trim().isEmpty()) { + if(isMandatory()) { + setError(true); + return false; + } else { + setError(false); + return true; + } + } + try { Integer.parseInt(width.getText()); Integer.parseInt(height.getText()); } catch (NumberFormatException e) { + setError(true); return false; } + setError(false); return true; } } diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditDialog.java similarity index 78% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditDialog.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditDialog.java index cb1950dff..7b6afc57a 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditDialog.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditDialog.java @@ -13,10 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ -package com.bladecoder.engineeditor.ui.components; +package com.bladecoder.engineeditor.ui.panels; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; +import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.InputListener; import com.badlogic.gdx.scenes.scene2d.ui.Cell; @@ -26,7 +27,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.ui.Widget; -import com.bladecoder.engineeditor.utils.EditorLogger; public abstract class EditDialog extends Dialog { @@ -45,18 +45,22 @@ public EditDialog(String title, Skin skin) { this.skin = skin; setResizable(false); + setKeepWithinStage(false); infoLbl = new Label("", skin); infoLbl.setWrap(true); centerPanel = new Table(skin); - infoCell = getContentTable().add((Widget) infoLbl).prefWidth(200); - getContentTable().add(new ScrollPane(centerPanel, skin)) - .maxHeight(Gdx.graphics.getHeight() * 0.8f) - .maxWidth(Gdx.graphics.getWidth() * 0.7f); - + infoCell = getContentTable().add((Widget) infoLbl).prefWidth(200).height(Gdx.graphics.getHeight() * 0.5f); + getContentTable().add(new ScrollPane(centerPanel, skin)).maxHeight(Gdx.graphics.getHeight() * 0.8f) + .maxWidth(Gdx.graphics.getWidth() * 0.7f).minHeight(Gdx.graphics.getHeight() * 0.5f) + .minWidth(Gdx.graphics.getWidth() * 0.5f); + + getContentTable().setHeight(Gdx.graphics.getHeight() * 0.7f); + centerPanel.addListener(new InputListener() { @Override - public void enter(InputEvent event, float x, float y, int pointer, com.badlogic.gdx.scenes.scene2d.Actor fromActor) { + public void enter(InputEvent event, float x, float y, int pointer, + com.badlogic.gdx.scenes.scene2d.Actor fromActor) { // EditorLogger.debug("ENTER - X: " + x + " Y: " + y); getStage().setScrollFocus(centerPanel); } @@ -64,32 +68,34 @@ public void enter(InputEvent event, float x, float y, int pointer, com.badlogic button("OK", true); button("Cancel", false); - key(Keys.ENTER, true); + // DISABLE the enter key because conflicts when newline in TextFields +// key(Keys.ENTER, true); key(Keys.ESCAPE, false); padBottom(10); padLeft(10); padRight(10); } - + public void addInputPanel(InputPanel i) { getCenterPanel().row().fill().expandX(); getCenterPanel().add(i); } - + public void setVisible(InputPanel i, boolean v) { i.setVisible(v); - Cell c = getCenterPanel().getCell(i); - - if(v) { + Cell c = getCenterPanel().getCell(i); + + if (v) { c.height(i.getPrefHeight()); } else { c.height(1); } - + i.invalidateHierarchy(); - } + } + @Override public Skin getSkin() { return skin; } @@ -102,19 +108,20 @@ public void setInfo(String text) { infoLbl.setText(text); } - public void setInfoWidget(Widget c) { + public void setInfoWidget(Actor c) { infoCell.setActor(null); infoCell.setActor(c).fill(); } public void setTitle(String title) { - super.setTitle(title); + getTitleLabel().setText(title); } public boolean isCancel() { return cancelled; } + @Override protected void result(Object object) { if (((boolean) object) == true) { if (validateFields()) { diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditList.java similarity index 94% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditList.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditList.java index 80cc423de..89c953bc5 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditList.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditList.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ -package com.bladecoder.engineeditor.ui.components; +package com.bladecoder.engineeditor.ui.panels; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; @@ -24,7 +24,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.utils.Array; -import com.bladecoder.engineeditor.utils.EditorLogger; public abstract class EditList extends Table { @@ -47,13 +46,15 @@ public EditList(Skin skin) { ScrollPane scrollPane = new ScrollPane(list, skin); container = new Container(scrollPane); container.fill(); - container.prefHeight(100); + container.prefHeight(1000); + + scrollPane.setFadeScrollBars(false); toolbar = new EditToolbar(skin); // debug(); add(toolbar).expandX().fillX(); - row().fill(); - add(container).expandY().fill(); + row(); + add(container).expand().fill(); toolbar.addCreateListener(new ChangeListener() { @@ -104,6 +105,8 @@ public void enter(InputEvent event, float x, float y, int pointer, com.badlogic }); } + + public void setCellRenderer(CellRenderer r) { list.setCellRenderer(r); } diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditModelDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditModelDialog.java new file mode 100644 index 000000000..10f718404 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditModelDialog.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.ChangeEvent; +import com.bladecoder.engineeditor.common.EditorLogger; +import com.bladecoder.engineeditor.common.Message; + +public abstract class EditModelDialog extends EditDialog { + + protected T e; + protected PARENT parent; + protected InputPanel[] i; + + protected ChangeListener listener; + + public EditModelDialog(Skin skin) { + super("", skin); + } + + protected void init(PARENT parent, T e, InputPanel[] inputs) { + this.e = e; + this.parent = parent; + this.i = inputs; + + getCenterPanel().clear(); + + for (InputPanel i : inputs) { + addInputPanel(i); + } + + if (e == null) { + setTitle("CREATE OBJECT"); + } else { + setTitle("EDITING " + e.getClass().getSimpleName()); + + try{ + modelToInputs(); + } catch (Exception e1) { + EditorLogger.error(e1.getMessage(), e1); + } + } + + // TODO Set focus to the 1st element + // if(inputs.length > 0) { + // getStage().setKeyboardFocus(inputs[0].getField()); + // } + } + + @Override + protected void ok() { + try{ + inputsToModel(e==null); + } catch (Exception e1) { + Message.showMsg(getStage(), "Error getting fields " + e1.getMessage(), 4); + EditorLogger.printStackTrace(e1); + } + + if (listener != null) + listener.changed(new ChangeEvent(), this); + } + + public void setListener(ChangeListener l) { + listener = l; + } + + protected abstract void inputsToModel(boolean create); + + protected abstract void modelToInputs(); + + public T getElement() { + return e; + } + + @Override + protected boolean validateFields() { + for (InputPanel p : i) { + if (p.isVisible() && !p.validateField()) + return false; + } + + return true; + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditToolbar.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditToolbar.java similarity index 62% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditToolbar.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditToolbar.java index fbfe3c186..34627166a 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditToolbar.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditToolbar.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ -package com.bladecoder.engineeditor.ui.components; +package com.bladecoder.engineeditor.ui.panels; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.scenes.scene2d.EventListener; @@ -22,80 +22,100 @@ import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; import com.badlogic.gdx.scenes.scene2d.ui.ImageButton.ImageButtonStyle; import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextField; +import com.badlogic.gdx.scenes.scene2d.ui.TextTooltip; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.bladecoder.engine.util.DPIUtils; import com.bladecoder.engineeditor.Ctx; public class EditToolbar extends HorizontalGroup { - - private ImageButton createBtn; - private ImageButton deleteBtn; - private ImageButton editBtn; - private ImageButton copyBtn; - private ImageButton pasteBtn; - - private Skin skin; - + + private ImageButton createBtn; + private ImageButton deleteBtn; + private ImageButton editBtn; + private ImageButton copyBtn; + private ImageButton pasteBtn; + + private Skin skin; + public EditToolbar(Skin skin) { super(); - + this.skin = skin; pad(0); - - createBtn = new ImageButton(skin); - editBtn = new ImageButton(skin); - deleteBtn = new ImageButton(skin); - copyBtn = new ImageButton(skin); - pasteBtn = new ImageButton(skin); - - addToolBarButton(createBtn, "ic_add","New", "Create a new Element"); - addToolBarButton(editBtn, "ic_edit","Edit", "Edit the selected Element"); - addToolBarButton(deleteBtn, "ic_delete","Delete", "Delete and put in the clipboard"); - addToolBarButton(copyBtn, "ic_copy","Copy", "Copy to the clipboard"); - addToolBarButton(pasteBtn, "ic_paste","Paste", "Paste from the clipboard"); - } - + + createBtn = new ImageButton(skin); + editBtn = new ImageButton(skin); + deleteBtn = new ImageButton(skin); + copyBtn = new ImageButton(skin); + pasteBtn = new ImageButton(skin); + + addToolBarButton(createBtn, "ic_add", "New", "Create a new Element"); + addToolBarButton(editBtn, "ic_edit", "Edit", "Edit the selected Element"); + addToolBarButton(deleteBtn, "ic_delete", "Delete", "Delete and put in the clipboard"); + addToolBarButton(copyBtn, "ic_copy", "Copy", "Copy to the clipboard"); + addToolBarButton(pasteBtn, "ic_paste", "Paste", "Paste from the clipboard"); + } + public void hideCopyPaste() { copyBtn.setVisible(false); pasteBtn.setVisible(false); } - + public void disableCreate(boolean v) { createBtn.setDisabled(v); } - + public void disableEdit(boolean v) { deleteBtn.setDisabled(v); editBtn.setDisabled(v); copyBtn.setDisabled(v); } - + public void disablePaste(boolean v) { pasteBtn.setDisabled(v); } - + public void addToolBarButton(ImageButton button, String icon, String text, String tooltip) { - + TextureRegion image = Ctx.assetManager.getIcon(icon); TextureRegion imageDisabled = Ctx.assetManager.getIcon(icon + "_disabled"); - + ImageButtonStyle style = new ImageButtonStyle(skin.get("plain", ButtonStyle.class)); style.imageUp = new TextureRegionDrawable(image); - style.imageDisabled = new TextureRegionDrawable(imageDisabled); + + if (imageDisabled != null) + style.imageDisabled = new TextureRegionDrawable(imageDisabled); button.setStyle(style); -// button.pad(4, 2, 4, 2); - addActor(button); - button.setDisabled(true); + button.pad(6, 3, 6, 3); + addActor(button); + button.setDisabled(true); + TextTooltip t = new TextTooltip(tooltip, skin); + t.getContainer().pad(DPIUtils.getSpacing() / 2); + button.addListener(t); + } + + public TextField addFilterBox(EventListener e) { + TextField tf = new TextField("", skin); + addActor(tf); + + TextTooltip t = new TextTooltip("Filter list", skin); + t.getContainer().pad(DPIUtils.getSpacing() / 2); + tf.addListener(t); + + tf.addListener(e); + + return tf; } - - + public void addCreateListener(EventListener e) { createBtn.addListener(e); - } - + } + public void addEditListener(EventListener e) { editBtn.addListener(e); } - + public void addDeleteListener(EventListener e) { deleteBtn.addListener(e); } @@ -103,7 +123,7 @@ public void addDeleteListener(EventListener e) { public void addCopyListener(EventListener e) { copyBtn.addListener(e); } - + public void addPasteListener(EventListener e) { pasteBtn.addListener(e); } diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditTree.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditTree.java similarity index 83% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditTree.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditTree.java index 23c3aab42..541292b2f 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/EditTree.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditTree.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ -package com.bladecoder.engineeditor.ui.components; +package com.bladecoder.engineeditor.ui.panels; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.ui.Container; @@ -25,13 +25,14 @@ import com.badlogic.gdx.scenes.scene2d.ui.Tree.Node; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.Selection; +import com.badlogic.gdx.utils.Array; public abstract class EditTree extends Table { protected EditToolbar toolbar; protected Tree tree; protected Skin skin; - protected Container container; + protected Container container; private ImageButton upBtn; private ImageButton downBtn; @@ -50,9 +51,9 @@ public EditTree(Skin skin) { tree = new Tree(skin); ScrollPane scrollPane = new ScrollPane(tree, skin); - container = new Container(scrollPane); + container = new Container(scrollPane); container.fill(); - container.prefHeight(100); + container.prefHeight(1000); toolbar = new EditToolbar(skin); // debug(); @@ -143,7 +144,7 @@ public void changed(ChangeEvent event, Actor actor) { public void changed(ChangeEvent event, Actor actor) { Selection selection = tree.getSelection(); - if (selection.size() == 0) { + if (selection.isEmpty()) { upBtn.setDisabled(true); downBtn.setDisabled(true); @@ -151,14 +152,17 @@ public void changed(ChangeEvent event, Actor actor) { rightBtn.setDisabled(true); } else { - Node nodeSel = selection.getLastSelected(); + Node nodeSel = selection.first(); + + int level = nodeSel.getLevel(); + Array siblings = getSiblings(); + - upBtn.setDisabled(nodeSel.getParent() == null || nodeSel.getParent().getChildren().get(0) == nodeSel); - downBtn.setDisabled(nodeSel.getParent() == null || nodeSel.getParent().getChildren().get( - nodeSel.getParent().getChildren().size - 1) == nodeSel); + upBtn.setDisabled(siblings.get(0) == nodeSel); + downBtn.setDisabled(siblings.get(siblings.size - 1) == nodeSel); - leftBtn.setDisabled(nodeSel.getParent() != null); - rightBtn.setDisabled(nodeSel.getParent() == null || nodeSel.getParent().getChildren().get(0) == nodeSel); + leftBtn.setDisabled(level==1); + rightBtn.setDisabled(siblings.get(0) == nodeSel); } toolbar.disableEdit(selection == null); @@ -167,6 +171,16 @@ public void changed(ChangeEvent event, Actor actor) { }); } + public Array getSiblings() { + Selection selection = tree.getSelection(); + Node nodeSel = selection.first(); + + int level = nodeSel.getLevel(); + Array siblings = (level == 1) ? tree.getRootNodes(): nodeSel.getParent().getChildren(); + + return siblings; + } + abstract protected void create(); abstract protected void edit(); abstract protected void delete(); diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditableOptionsInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditableOptionsInputPanel.java new file mode 100644 index 000000000..511e6e85a --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditableOptionsInputPanel.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; + +public class EditableOptionsInputPanel extends InputPanel implements OptionsInputPanel { + protected final EditableSelectBox input; + + EditableOptionsInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue, T[] options) { + input = new EditableSelectBox<>(skin); + init(skin, title, desc, input, mandatory, defaultValue); + + if(options != null) + input.setItems(options); + } + + public String getText() { + if(input.getSelected().isEmpty()) + return null; + + return input.getSelected(); + } + + @Override + public void setText(String s) { + if(s == null) + return; + + input.setSelected(s); + } + + @Override + public int getSelectedIndex() { + return input.getSelectedIndex(); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditableSelectBox.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditableSelectBox.java new file mode 100644 index 000000000..1ec8f51ac --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EditableSelectBox.java @@ -0,0 +1,395 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeIn; +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeOut; +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.sequence; + +import java.util.ArrayList; + +import com.badlogic.gdx.Input.Keys; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.math.Interpolation; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.InputListener; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.Touchable; +import com.badlogic.gdx.scenes.scene2d.actions.Actions; +import com.badlogic.gdx.scenes.scene2d.ui.List; +import com.badlogic.gdx.scenes.scene2d.ui.List.ListStyle; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; +import com.badlogic.gdx.scenes.scene2d.ui.SelectBox.SelectBoxStyle; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.ui.TextField; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.scenes.scene2d.utils.Drawable; +import com.bladecoder.engineeditor.common.EditorLogger; + +public class EditableSelectBox extends Table { + static final Vector2 temp = new Vector2(); + + private TextField input; + private TextButton showListButton; + private SelectList selectList; + + private T[] items; + + private boolean disabled; + + public EditableSelectBox(Skin skin) { + super(skin); + + input = new TextField("", skin); + showListButton = new TextButton(">", skin); + selectList = new SelectList<>(skin, input); + + add(input); + add(showListButton); + + addListener(new ClickListener() { + @Override + public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { + if (pointer == 0 && button != 0) + return false; + + if (disabled) + return false; + +// if (selectList.getStage() == null) + showList(); + + return true; + } + + @Override + public boolean keyUp(InputEvent event, int keycode) { + if (keycode == Keys.ENTER) { + setSelectedIndex(selectList.list.getSelectedIndex()); + hideList(); + input.setCursorPosition(input.getText().length()); + } else if (keycode == Keys.UP) { + int idx = selectList.list.getSelectedIndex(); + + if (idx > 0) + selectList.list.setSelectedIndex(idx - 1); + + return true; + } else if (keycode == Keys.DOWN) { + int idx = selectList.list.getSelectedIndex(); + + if (idx < selectList.list.getItems().size - 1) + selectList.list.setSelectedIndex(idx + 1); + + return true; + } else { + if (selectList.getStage() == null && selectList.list.getItems().size > 0) { + showList(); + } + + filterItems(input.getText()); + } + + return false; + } + }); + + // selectList.getList().addListener(new ChangeListener() { + // @Override + // public void changed(ChangeEvent event, Actor actor) { + // fire(event); + // } + // }); + + input.setProgrammaticChangeEvents(true); + input.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + fire(event); + } + }); + } + + public String getSelected() { + return input.getText(); + } + + public void setSelected(String str) { + input.setText(str); + } + + public int getSelectedIndex() { + return selectList.list.getSelectedIndex(); + } + + public void setSelectedIndex(int idx) { + if (selectList.list.getItems().size == 0) + return; + + input.setText(selectList.list.getItems().get(idx).toString()); + } + + public TextField getInput() { + return input; + } + + public final void setItems(T[] newItems) { + + items = newItems; + + setListItems(items); + } + + private final void setListItems(T[] newItems) { + if (newItems == null) + throw new IllegalArgumentException("newItems cannot be null."); + + float oldPrefWidth = getPrefWidth(); + + selectList.list.setItems(newItems); + if (newItems.length > 0) + selectList.list.setSelectedIndex(0); + else + selectList.list.setSelectedIndex(-1); + + invalidate(); + if (oldPrefWidth != getPrefWidth()) + invalidateHierarchy(); + } + + public void showList() { + if (selectList.list.getItems().size == 0) + return; + + if (selectList.list.getSelectedIndex() >= selectList.list.getItems().size) + selectList.list.setSelectedIndex(selectList.list.getItems().size - 1); + + selectList.show(getStage()); + } + + public void hideList() { + selectList.hide(); + setListItems(items); + } + + @SuppressWarnings("unchecked") + private void filterItems(String s) { + + if (s == null || s.isEmpty()) { + setListItems(items); + } else { + + ArrayList filtered = new ArrayList<>(); + + String sl = s.toLowerCase(); + + for (T item : items) { + if (item.toString().toLowerCase().contains(sl)) + filtered.add(item); + } + + setListItems((T[]) filtered.toArray(new String[filtered.size()])); + } + + selectList.hide(); + selectList.invalidate(); + showList(); + } + + protected void onShow(Actor selectBoxList, boolean below) { + selectBoxList.getColor().a = 0; + selectBoxList.addAction(fadeIn(0.3f, Interpolation.fade)); + } + + static class SelectList extends ScrollPane { + private final TextField selectBox; + private int selectedIndex; + int maxListCount; + private final Vector2 screenPosition = new Vector2(); + final List list; + private InputListener hideListener; + private Actor previousScrollFocus; + + public SelectList(Skin skin, final TextField inputBox) { + super(null, skin.get(SelectBoxStyle.class).scrollStyle); + this.selectBox = inputBox; + + setOverscroll(false, false); + setFadeScrollBars(false); + + ListStyle listStyle = skin.get(SelectBoxStyle.class).listStyle; + + list = new List<>(listStyle); + list.setTouchable(Touchable.disabled); + setActor(list); + + list.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + selectBox.setText(list.getSelected().toString()); + selectedIndex = list.getSelectedIndex(); + hide(); + } + + @Override + public boolean mouseMoved(InputEvent event, float x, float y) { + list.setSelectedIndex( + Math.min(list.getItems().size - 1, (int) ((list.getHeight() - y) / list.getItemHeight()))); + return true; + } + }); + + addListener(new InputListener() { + @Override + public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) { + if (toActor == null || !isAscendantOf(toActor)) + if (selectedIndex < list.getItems().size) + list.setSelectedIndex(selectedIndex); + else + EditorLogger.error("EditableSelectBox:exit selectedIndex outOfBounds: " + selectedIndex); + } + }); + + hideListener = new InputListener() { + @Override + public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { + Actor target = event.getTarget(); + if (isAscendantOf(target)) + return false; + + if (selectedIndex < list.getItems().size) + list.setSelectedIndex(selectedIndex); + else + EditorLogger.error("EditableSelectBox:touchDown selectedIndex outOfBounds: " + selectedIndex); + + hide(); + return false; + } + + @Override + public boolean keyDown(InputEvent event, int keycode) { + if (keycode == Keys.ESCAPE) + hide(); + return false; + } + }; + } + + public void show(Stage stage) { + if (list.isTouchable()) + return; + + stage.removeCaptureListener(hideListener); + stage.addCaptureListener(hideListener); + stage.addActor(this); + + selectBox.localToStageCoordinates(screenPosition.set(0, 0)); + + // Show the list above or below the select box, limited to a number + // of items and the available height in the stage. + float itemHeight = list.getItemHeight(); + float height = itemHeight + * (maxListCount <= 0 ? list.getItems().size : Math.min(maxListCount, list.getItems().size)); + Drawable scrollPaneBackground = getStyle().background; + if (scrollPaneBackground != null) + height += scrollPaneBackground.getTopHeight() + scrollPaneBackground.getBottomHeight(); + Drawable listBackground = list.getStyle().background; + if (listBackground != null) + height += listBackground.getTopHeight() + listBackground.getBottomHeight(); + + float heightBelow = screenPosition.y; + float heightAbove = stage.getCamera().viewportHeight - screenPosition.y - selectBox.getHeight(); + boolean below = true; + if (height > heightBelow) { + if (heightAbove > heightBelow) { + below = false; + height = Math.min(height, heightAbove); + } else + height = heightBelow; + } + + if (below) + setY(screenPosition.y - height); + else + setY(screenPosition.y + selectBox.getHeight()); + setX(screenPosition.x); + setSize(Math.max(getPrefWidth(), selectBox.getWidth()), height); + + validate(); + scrollTo(0, list.getHeight() - selectedIndex * itemHeight - itemHeight / 2, 0, 0, true, true); + updateVisualScroll(); + + previousScrollFocus = null; + Actor actor = stage.getScrollFocus(); + if (actor != null && !actor.isDescendantOf(this)) + previousScrollFocus = actor; + stage.setScrollFocus(this); + + list.setTouchable(Touchable.enabled); + clearActions(); + // getColor().a = 0; + // addAction(fadeIn(0.3f, Interpolation.fade)); + } + + public void hide() { + if (!list.isTouchable() || !hasParent()) + return; + list.setTouchable(Touchable.disabled); + + Stage stage = getStage(); + if (stage != null) { + stage.removeCaptureListener(hideListener); + if (previousScrollFocus != null && previousScrollFocus.getStage() == null) + previousScrollFocus = null; + Actor actor = stage.getScrollFocus(); + if (actor == null || isAscendantOf(actor)) + stage.setScrollFocus(previousScrollFocus); + } + + clearActions(); + getColor().a = 1; + addAction(sequence(fadeOut(0.15f, Interpolation.fade), Actions.removeActor())); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + selectBox.localToStageCoordinates(temp.set(0, 0)); + if (!temp.equals(screenPosition)) + hide(); + super.draw(batch, parentAlpha); + } + + @Override + public void act(float delta) { + super.act(delta); + toFront(); + } + + public List getList() { + return list; + } + + public int getSelectedIndex() { + return list.getSelectedIndex(); + } + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EnumOptionsInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EnumOptionsInputPanel.java new file mode 100644 index 000000000..d127ceeaa --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/EnumOptionsInputPanel.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.utils.Array; + +public class EnumOptionsInputPanel extends InputPanel { + private enum Empty { + EMPTY; + + @Override + public String toString() { + return ""; + } + } + + private final SelectBox> input; + + EnumOptionsInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue, Enum[] options) { + input = new SelectBox<>(skin); + + int l = options.length; + if(!mandatory) l++; + Enum[] values = new Enum[l]; + + if(!mandatory) { + values[0] = Empty.EMPTY; + } + + System.arraycopy(options, 0, values, mandatory ? 0 : 1, options.length); + + input.setItems(values); + + init(skin, title, desc, input, mandatory, defaultValue); + } + + public String getText() { + final Enum selected = input.getSelected(); + return selected == Empty.EMPTY ? "" : selected.name(); + } + + public void setText(String s) { + if(s == null) + return; + + if ("".equals(s) && !isMandatory()) { + input.setSelectedIndex(0); + } + Array> items = input.getItems(); + for (Enum item : items) { + if (item != Empty.EMPTY && item.name().equalsIgnoreCase(s)) { + input.setSelected(item); + } + } + } + + public int getSelectedIndex() { + return input.getSelectedIndex(); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/FileInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/FileInputPanel.java new file mode 100644 index 000000000..83bd80002 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/FileInputPanel.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import java.io.File; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.Array; +import com.bladecoder.engineeditor.Ctx; +import com.kotcrab.vis.ui.widget.file.FileChooser; +import com.kotcrab.vis.ui.widget.file.FileChooser.Mode; +import com.kotcrab.vis.ui.widget.file.FileChooser.SelectionMode; +import com.kotcrab.vis.ui.widget.file.FileChooser.ViewMode; +import com.kotcrab.vis.ui.widget.file.FileChooserListener; +import com.kotcrab.vis.ui.widget.file.FileTypeFilter; + +public class FileInputPanel extends InputPanel { + public enum DialogType { + OPEN_FILE, SAVE_FILE, DIRECTORY + } + + private File cd; + private File selected; + private TextButton button; + + private final static String FILE_TEXT = "Select file"; + private final static String DIR_TEXT = "Select folder"; + private FileChooser fileChooser; + + public FileInputPanel(Skin skin, String title, String desc, DialogType dialogType) { + this(skin, title, desc, Ctx.project.getProjectDir() != null ? Ctx.project.getProjectDir() : new File("."), + dialogType, true); + } + + public FileInputPanel(Skin skin, String title, String desc, DialogType dialogType, boolean mandatory) { + this(skin, title, desc, Ctx.project.getProjectDir() != null ? Ctx.project.getProjectDir() : new File("."), + dialogType, mandatory); + } + + public FileInputPanel(Skin skin, String title, String desc, File current, final DialogType dialogType, + boolean mandatory) { + Table t = new Table(); + button = new TextButton(dialogType == DialogType.DIRECTORY ? DIR_TEXT : FILE_TEXT, skin, "no-toggled"); + + t.add(button); + + init(skin, title, desc, t, + mandatory, null); + + switch (dialogType) { + case DIRECTORY: + fileChooser = new FileChooser(Mode.OPEN); + fileChooser.setSelectionMode(SelectionMode.DIRECTORIES); + break; + case OPEN_FILE: + fileChooser = new FileChooser(Mode.OPEN); + fileChooser.setSelectionMode(SelectionMode.FILES); + break; + case SAVE_FILE: + fileChooser = new FileChooser(Mode.SAVE); + fileChooser.setSelectionMode(SelectionMode.FILES); + break; + default: + break; + } + + fileChooser.setSize(Gdx.graphics.getWidth() * 0.7f, Gdx.graphics.getHeight() * 0.7f); + fileChooser.setViewMode(ViewMode.LIST); + + button.addListener(new ClickListener() { + public void clicked(InputEvent event, float x, float y) { + if(cd != null) + fileChooser.setDirectory(cd); + + getStage().addActor(fileChooser); + + fileChooser.setListener(new FileChooserListener() { + + @Override + public void selected(Array files) { + selected = files.get(0).file(); + + button.setText(selected.getAbsolutePath()); + } + + @Override + public void canceled() { + } + }); + } + }); + + // Adds clear button if not mandatory + if(!mandatory) { + TextButton clearButton = new TextButton("Clear", skin, "no-toggled"); + + clearButton.addListener(new ClickListener() { + public void clicked(InputEvent event, float x, float y) { + button.setText(dialogType == DialogType.DIRECTORY ? DIR_TEXT : FILE_TEXT); + selected = null; + } + }); + + t.add(clearButton); + } + } + + public File getFile() { + return selected; + } + + @Override + public String getText() { + if (selected != null) + return selected.getAbsolutePath(); + else + return ""; + } + + @Override + public void setText(String text) { + button.setText(text); + selected = new File(text); + cd = new File(text); + } + + public void setFileTypeFilter(FileTypeFilter ftf) { + fileChooser.setFileTypeFilter(ftf); + } + +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/FilteredSelectBox.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/FilteredSelectBox.java new file mode 100644 index 000000000..e8d45dea0 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/FilteredSelectBox.java @@ -0,0 +1,705 @@ +package com.bladecoder.engineeditor.ui.panels; + +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeIn; +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeOut; +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.removeActor; +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.sequence; + +import java.util.ArrayList; + +import com.badlogic.gdx.Input.Keys; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.math.Interpolation; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.InputListener; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.Touchable; +import com.badlogic.gdx.scenes.scene2d.ui.List; +import com.badlogic.gdx.scenes.scene2d.ui.List.ListStyle; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane.ScrollPaneStyle; +import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextField; +import com.badlogic.gdx.scenes.scene2d.ui.TextField.TextFieldStyle; +import com.badlogic.gdx.scenes.scene2d.ui.Widget; +import com.badlogic.gdx.scenes.scene2d.utils.ArraySelection; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.ChangeEvent; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.scenes.scene2d.utils.Disableable; +import com.badlogic.gdx.scenes.scene2d.utils.Drawable; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.ObjectSet; +import com.badlogic.gdx.utils.Pool; +import com.badlogic.gdx.utils.Pools; + +/** + * A select box (aka a drop-down list) allows a user to choose one of a number + * of values from a list. When inactive, the selected value is displayed. When + * activated, it shows the list of values that may be selected. + *

+ * {@link ChangeEvent} is fired when the selectbox selection changes. + *

+ * The preferred size of the select box is determined by the maximum text bounds + * of the items and the size of the {@link FilteredSelectBoxStyle#background}. + * + * @author mzechner + * @author Nathan Sweet + * @author Rafael García + */ +public class FilteredSelectBox extends Widget implements Disableable { + + static final Vector2 temp = new Vector2(); + + FilteredSelectBoxStyle style; + final Array items = new Array<>(); + final ArraySelection selection = new ArraySelection<>(items); + SelectBoxList selectBoxList; + private float prefWidth, prefHeight; + private ClickListener clickListener; + boolean disabled; + private int alignment = Align.left; + + public FilteredSelectBox(Skin skin) { + this(skin.get(FilteredSelectBoxStyle.class)); + } + + public FilteredSelectBox(Skin skin, String styleName) { + this(skin.get(styleName, FilteredSelectBoxStyle.class)); + } + + public FilteredSelectBox(FilteredSelectBoxStyle style) { + setStyle(style); + setSize(getPrefWidth(), getPrefHeight()); + + selection.setActor(this); + selection.setRequired(true); + + selectBoxList = new SelectBoxList<>(this); + + addListener(clickListener = new ClickListener() { + @Override + public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { + if (pointer == 0 && button != 0) + return false; + if (disabled) + return false; + if (selectBoxList.hasParent()) + hideList(); + else + showList(); + return true; + } + }); + + } + + /** + * Set the max number of items to display when the select box is opened. Set to + * 0 (the default) to display as many as fit in the stage height. + */ + public void setMaxListCount(int maxListCount) { + selectBoxList.maxListCount = maxListCount; + } + + /** + * @return Max number of items to display when the box is opened, or <= 0 to + * display them all. + */ + public int getMaxListCount() { + return selectBoxList.maxListCount; + } + + @Override + protected void setStage(Stage stage) { + if (stage == null) + selectBoxList.hide(); + super.setStage(stage); + } + + public void setStyle(FilteredSelectBoxStyle style) { + if (style == null) + throw new IllegalArgumentException("style cannot be null."); + this.style = style; + if (selectBoxList != null) { + selectBoxList.setStyle(style.scrollStyle); + selectBoxList.list.setStyle(style.listStyle); + } + invalidateHierarchy(); + } + + /** + * Returns the select box's style. Modifying the returned style may not have an + * effect until {@link #setStyle(FilteredSelectBoxStyle)} is called. + */ + public FilteredSelectBoxStyle getStyle() { + return style; + } + + /** + * Set the backing Array that makes up the choices available in the SelectBox + */ + @SuppressWarnings("unchecked") + public void setItems(T... newItems) { + if (newItems == null) + throw new IllegalArgumentException("newItems cannot be null."); + float oldPrefWidth = getPrefWidth(); + + items.clear(); + items.addAll(newItems); + selection.validate(); + selectBoxList.list.setItems(items); + + invalidate(); + if (oldPrefWidth != getPrefWidth()) + invalidateHierarchy(); + } + + /** Sets the items visible in the select box. */ + public void setItems(Array newItems) { + if (newItems == null) + throw new IllegalArgumentException("newItems cannot be null."); + float oldPrefWidth = getPrefWidth(); + + items.clear(); + items.addAll(newItems); + selection.validate(); + selectBoxList.list.setItems(items); + + invalidate(); + if (oldPrefWidth != getPrefWidth()) + invalidateHierarchy(); + } + + public void clearItems() { + if (items.size == 0) + return; + items.clear(); + selection.clear(); + invalidateHierarchy(); + } + + /** + * Returns the internal items array. If modified, {@link #setItems(Array)} must + * be called to reflect the changes. + */ + public Array getItems() { + return items; + } + + @Override + public void layout() { + Drawable bg = style.background; + BitmapFont font = style.font; + + if (bg != null) { + prefHeight = Math.max( + bg.getTopHeight() + bg.getBottomHeight() + font.getCapHeight() - font.getDescent() * 2, + bg.getMinHeight()); + } else + prefHeight = font.getCapHeight() - font.getDescent() * 2; + + float maxItemWidth = 0; + Pool layoutPool = Pools.get(GlyphLayout.class); + GlyphLayout layout = layoutPool.obtain(); + for (int i = 0; i < items.size; i++) { + layout.setText(font, toString(items.get(i))); + maxItemWidth = Math.max(layout.width, maxItemWidth); + } + layoutPool.free(layout); + + prefWidth = maxItemWidth; + if (bg != null) + prefWidth += bg.getLeftWidth() + bg.getRightWidth(); + + ListStyle listStyle = style.listStyle; + ScrollPaneStyle scrollStyle = style.scrollStyle; + float listWidth = maxItemWidth + listStyle.selection.getLeftWidth() + listStyle.selection.getRightWidth(); + if (scrollStyle.background != null) + listWidth += scrollStyle.background.getLeftWidth() + scrollStyle.background.getRightWidth(); + if (selectBoxList == null || !selectBoxList.isScrollingDisabledY()) + listWidth += Math.max(style.scrollStyle.vScroll != null ? style.scrollStyle.vScroll.getMinWidth() : 0, + style.scrollStyle.vScrollKnob != null ? style.scrollStyle.vScrollKnob.getMinWidth() : 0); + prefWidth = Math.max(prefWidth, listWidth); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + validate(); + + Drawable background; + if (disabled && style.backgroundDisabled != null) + background = style.backgroundDisabled; + else if (selectBoxList.hasParent() && style.backgroundOpen != null) + background = style.backgroundOpen; + else if (clickListener.isOver() && style.backgroundOver != null) + background = style.backgroundOver; + else if (style.background != null) + background = style.background; + else + background = null; + BitmapFont font = style.font; + Color fontColor = (disabled && style.disabledFontColor != null) ? style.disabledFontColor : style.fontColor; + + Color color = getColor(); + float x = getX(), y = getY(); + float width = getWidth(), height = getHeight(); + + batch.setColor(color.r, color.g, color.b, color.a * parentAlpha); + if (background != null) + background.draw(batch, x, y, width, height); + + T selected = selection.first(); + if (selected != null) { + if (background != null) { + width -= background.getLeftWidth() + background.getRightWidth(); + height -= background.getBottomHeight() + background.getTopHeight(); + x += background.getLeftWidth(); + y += (int) (height / 2 + background.getBottomHeight() + font.getData().capHeight / 2); + } else { + y += (int) (height / 2 + font.getData().capHeight / 2); + } + font.setColor(fontColor.r, fontColor.g, fontColor.b, fontColor.a * parentAlpha); + drawItem(batch, font, selected, x, y, width); + } + } + + protected GlyphLayout drawItem(Batch batch, BitmapFont font, T item, float x, float y, float width) { + String string = toString(item); + return font.draw(batch, string, x, y, 0, string.length(), width, alignment, false, "..."); + } + + /** + * Sets the alignment of the selected item in the select box. See + * {@link #getList()} and {@link List#setAlignment(int)} to set the alignment in + * the list shown when the select box is open. + * + * @param alignment See {@link Align}. + */ + public void setAlignment(int alignment) { + this.alignment = alignment; + } + + /** + * Get the set of selected items, useful when multiple items are selected + * + * @return a Selection object containing the selected elements + */ + public ArraySelection getSelection() { + return selection; + } + + /** + * Returns the first selected item, or null. For multiple selections use + * {@link SelectBox#getSelection()}. + */ + public T getSelected() { + return selection.first(); + } + + /** + * Sets the selection to only the passed item, if it is a possible choice, else + * selects the first item. + */ + public void setSelected(T item) { +// T item = (T)i; + if (items.contains(item, false)) + selection.set(item); + else if (items.size > 0) + selection.set(items.first()); + else + selection.clear(); + } + + /** + * @return The index of the first selected item. The top item has an index of 0. + * Nothing selected has an index of -1. + */ + public int getSelectedIndex() { + ObjectSet selected = selection.items(); + return selected.size == 0 ? -1 : items.indexOf(selected.first(), false); + } + + /** Sets the selection to only the selected index. */ + public void setSelectedIndex(int index) { + selection.set(items.get(index)); + } + + @Override + public void setDisabled(boolean disabled) { + if (disabled && !this.disabled) + hideList(); + this.disabled = disabled; + } + + @Override + public boolean isDisabled() { + return disabled; + } + + @Override + public float getPrefWidth() { + validate(); + return prefWidth; + } + + @Override + public float getPrefHeight() { + validate(); + return prefHeight; + } + + protected String toString(T item) { + return item.toString(); + } + + public void showList() { + if (items.size == 0) + return; + selectBoxList.show(getStage()); + } + + public void hideList() { + selectBoxList.hide(); + } + + /** Returns the list shown when the select box is open. */ + public List getList() { + return selectBoxList.list; + } + + /** Disables scrolling of the list shown when the select box is open. */ + public void setScrollingDisabled(boolean y) { + selectBoxList.setScrollingDisabled(true, y); + invalidateHierarchy(); + } + + /** + * Returns the scroll pane containing the list that is shown when the select box + * is open. + */ + public ScrollPane getScrollPane() { + return selectBoxList; + } + + protected void onShow(Actor selectBoxList, boolean below) { + selectBoxList.getColor().a = 0; + selectBoxList.addAction(fadeIn(0.3f, Interpolation.fade)); + } + + protected void onHide(Actor selectBoxList) { + selectBoxList.getColor().a = 1; + selectBoxList.addAction(sequence(fadeOut(0.15f, Interpolation.fade), removeActor())); + } + + /** @author Nathan Sweet */ + final class SelectBoxList extends ScrollPane { + private final FilteredSelectBox selectBox; + int maxListCount; + private final Vector2 screenPosition = new Vector2(); + final List list; + private InputListener hideListener; + private Actor previousScrollFocus; + private TextField filterField; + + public SelectBoxList(final FilteredSelectBox selectBox) { + super(null, selectBox.style.scrollStyle); + this.selectBox = selectBox; + + setOverscroll(false, false); + setFadeScrollBars(false); + setScrollingDisabled(true, false); + + list = new List(selectBox.style.listStyle) { + @Override + public String toString(T obj) { + return selectBox.toString(obj); + } + }; + + list.setTouchable(Touchable.disabled); + setActor(list); + + filterField = new TextField("", selectBox.style.textFieldStyle); + + list.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + selectBox.selection.choose(list.getSelected()); + hide(); + } + + @Override + public boolean mouseMoved(InputEvent event, float x, float y) { + list.setSelectedIndex( + Math.min(list.getItems().size - 1, (int) ((list.getHeight() - y) / list.getItemHeight()))); + return true; + } + }); + + addListener(new InputListener() { + @Override + public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) { + if (toActor == null || !isAscendantOf(toActor)) + list.getSelection().set(selectBox.getSelected()); + } + }); + + hideListener = new InputListener() { + @Override + public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { + Actor target = event.getTarget(); + if (isAscendantOf(target)) + return false; + list.getSelection().set(selectBox.getSelected()); + hide(); + return false; + } + + @Override + public boolean keyDown(InputEvent event, int keycode) { + if (keycode == Keys.ESCAPE) + hide(); + return false; + } + }; + + filterField.addListener(new InputListener() { + @Override + public boolean keyUp(InputEvent event, int keycode) { + if (keycode == Keys.ENTER) { + setSelected(list.getSelected()); + hideList(); + filterField.setCursorPosition(filterField.getText().length()); + } else if (keycode == Keys.UP) { + int idx = list.getSelectedIndex(); + + if (idx > 0) + list.setSelectedIndex(idx - 1); + + return true; + } else if (keycode == Keys.DOWN) { + int idx = list.getSelectedIndex(); + + if (idx < list.getItems().size - 1) + list.setSelectedIndex(idx + 1); + + return true; + } else { + if (getStage() == null && list.getItems().size > 0) { + showList(); + } + + filterItems(filterField.getText()); + } + + return false; + } + }); + } + + @SuppressWarnings("unchecked") + private void filterItems(String s) { + + if (s == null || s.isEmpty()) { + setListItems(items.toArray()); + } else { + + ArrayList filtered = new ArrayList<>(); + + String sl = s.toLowerCase(); + + for (T item : items.toArray()) { + if (item.toString().toLowerCase().contains(sl)) + filtered.add(item); + } + + setListItems((T[]) filtered.toArray(new String[filtered.size()])); + } + +// hideList(); + invalidate(); +// showList(); + } + + private final void setListItems(T[] newItems) { + if (newItems == null) + throw new IllegalArgumentException("newItems cannot be null."); + + float oldPrefWidth = getPrefWidth(); + + list.setItems(newItems); + if (newItems.length > 0) + list.setSelectedIndex(0); + else + list.setSelectedIndex(-1); + + invalidate(); + if (oldPrefWidth != getPrefWidth()) + invalidateHierarchy(); + } + + public void show(Stage stage) { + if (list.isTouchable()) + return; + + stage.removeCaptureListener(hideListener); + stage.addCaptureListener(hideListener); + stage.addActor(this); + stage.addActor(filterField); + + selectBox.localToStageCoordinates(screenPosition.set(0, 0)); + + // Show the list above or below the select box, limited to a number of items and + // the available height in the stage. + float itemHeight = list.getItemHeight(); + float height = itemHeight + * (maxListCount <= 0 ? selectBox.items.size : Math.min(maxListCount, selectBox.items.size)); + Drawable scrollPaneBackground = getStyle().background; + if (scrollPaneBackground != null) + height += scrollPaneBackground.getTopHeight() + scrollPaneBackground.getBottomHeight(); + Drawable listBackground = list.getStyle().background; + if (listBackground != null) + height += listBackground.getTopHeight() + listBackground.getBottomHeight(); + + float heightBelow = screenPosition.y - itemHeight; + float heightAbove = stage.getCamera().viewportHeight - screenPosition.y - selectBox.getHeight(); + boolean below = true; + if (height > heightBelow) { + if (heightAbove > heightBelow) { + below = false; + height = Math.min(height, heightAbove); + } else + height = heightBelow; + } + + if (below) + setY(screenPosition.y - height); + else + setY(screenPosition.y + selectBox.getHeight()); + setX(screenPosition.x); + setHeight(height); + validate(); + float width = Math.max(getPrefWidth(), selectBox.getWidth()); + if (getPrefHeight() > height && !isScrollingDisabledY()) + width += getScrollBarWidth(); + setWidth(width); + + filterField.setX(getX()); + filterField.setWidth(getWidth()); + filterField.setHeight(filterField.getPrefHeight()); + filterField.setY(getY() + getHeight() - filterField.getHeight()); + stage.setKeyboardFocus(filterField); + filterField.validate(); + setY(getY() - filterField.getHeight()); + + validate(); + scrollTo(0, list.getHeight() - selectBox.getSelectedIndex() * itemHeight - itemHeight / 2, 0, 0, true, + true); + updateVisualScroll(); + + previousScrollFocus = null; + Actor actor = stage.getScrollFocus(); + if (actor != null && !actor.isDescendantOf(this)) + previousScrollFocus = actor; + stage.setScrollFocus(this); + + list.getSelection().set(selectBox.getSelected()); + list.setTouchable(Touchable.enabled); + clearActions(); + selectBox.onShow(this, below); + + filterField.setText(""); + setListItems(items.toArray()); + } + + public void hide() { + if (!list.isTouchable() || !hasParent()) + return; + list.setTouchable(Touchable.disabled); + + Stage stage = getStage(); + if (stage != null) { + stage.removeCaptureListener(hideListener); + if (previousScrollFocus != null && previousScrollFocus.getStage() == null) + previousScrollFocus = null; + Actor actor = stage.getScrollFocus(); + if (actor == null || isAscendantOf(actor)) + stage.setScrollFocus(previousScrollFocus); + } + + clearActions(); + selectBox.onHide(this); + filterField.remove(); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + selectBox.localToStageCoordinates(temp.set(0, 0)); + if (!temp.equals(screenPosition)) + hide(); + super.draw(batch, parentAlpha); + } + + @Override + public void act(float delta) { + super.act(delta); + toFront(); + filterField.toFront(); + } + } + + /** + * The style for a select box, see {@link SelectBox}. + * + * @author mzechner + * @author Nathan Sweet + */ + static public class FilteredSelectBoxStyle { + public BitmapFont font; + public Color fontColor = new Color(1, 1, 1, 1); + /** Optional. */ + public Color disabledFontColor; + /** Optional. */ + public Drawable background; + public ScrollPaneStyle scrollStyle; + public ListStyle listStyle; + public TextFieldStyle textFieldStyle; + /** Optional. */ + public Drawable backgroundOver, backgroundOpen, backgroundDisabled; + + public FilteredSelectBoxStyle() { + } + + public FilteredSelectBoxStyle(BitmapFont font, Color fontColor, Drawable background, + ScrollPaneStyle scrollStyle, ListStyle listStyle, TextFieldStyle textFieldStyle) { + this.font = font; + this.fontColor.set(fontColor); + this.background = background; + this.scrollStyle = scrollStyle; + this.listStyle = listStyle; + this.textFieldStyle = textFieldStyle; + } + + public FilteredSelectBoxStyle(FilteredSelectBoxStyle style) { + this.font = style.font; + this.fontColor.set(style.fontColor); + if (style.disabledFontColor != null) + this.disabledFontColor = new Color(style.disabledFontColor); + this.background = style.background; + this.backgroundOver = style.backgroundOver; + this.backgroundOpen = style.backgroundOpen; + this.backgroundDisabled = style.backgroundDisabled; + this.scrollStyle = new ScrollPaneStyle(style.scrollStyle); + this.listStyle = new ListStyle(style.listStyle); + this.textFieldStyle = new TextFieldStyle(style.textFieldStyle); + } + } + +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditDialogDialog.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/FloatInputPanel.java similarity index 51% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditDialogDialog.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/FloatInputPanel.java index 24f9c28f9..efb856d60 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/EditDialogDialog.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/FloatInputPanel.java @@ -13,32 +13,38 @@ * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ -package com.bladecoder.engineeditor.ui; - -import org.w3c.dom.Element; +package com.bladecoder.engineeditor.ui.panels; import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.bladecoder.engineeditor.model.BaseDocument; -import com.bladecoder.engineeditor.ui.components.EditElementDialog; -import com.bladecoder.engineeditor.ui.components.InputPanel; -public class EditDialogDialog extends EditElementDialog { - public static final String INFO = "Actors can have several dialogs defined. Dialogs have a tree of options to choose"; +public class FloatInputPanel extends StringInputPanel { - private InputPanel[] inputs; - - String attrs[] = { "id"}; - - public EditDialogDialog(Skin skin, BaseDocument doc, Element parent, Element e) { - super(skin); + FloatInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue) { + super(skin, title, desc, mandatory, defaultValue); + } + + @Override + public boolean validateField() { + String s = getText(); - inputs = new InputPanel[1]; + if(s == null || s.trim().isEmpty()) { + if(isMandatory()) { + setError(true); + return false; + } else { + setError(false); + return true; + } + } - inputs[0] = new InputPanel(skin, "Dialog ID", - "Select the dialog id to create.", true); - - setInfo(INFO); + try { + Float.parseFloat(s); + } catch (NumberFormatException e) { + setError(true); + return false; + } - init(inputs, attrs, doc, parent, "dialog", e); + setError(false); + return true; } } diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/HeaderPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/HeaderPanel.java similarity index 82% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/HeaderPanel.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/HeaderPanel.java index e5ebbc32f..c66625d57 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/HeaderPanel.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/HeaderPanel.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ -package com.bladecoder.engineeditor.ui.components; +package com.bladecoder.engineeditor.ui.panels; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.InputEvent; @@ -23,9 +23,9 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.utils.Align; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Scaling; import com.bladecoder.engineeditor.Ctx; @@ -37,6 +37,7 @@ public class HeaderPanel extends Table { private Image collapseImg; private Cell contentCell; + @SuppressWarnings("unchecked") public HeaderPanel(Skin skin, String title) { titleLbl = new Label(title, skin); north = new HorizontalGroup(); @@ -53,16 +54,18 @@ public HeaderPanel(Skin skin, String title) { north.addActor(titleLbl); north.align(Align.left); north.fill(); + north.wrap(true); + north.rowAlign(Align.left); add(north).expandX().fillX(); row(); Image image = new Image(skin.getDrawable("white_pixel")); - image.setColor(skin.getColor("holo-blue")); + image.setColor(skin.getColor("separator-color")); add(image).height(2).padBottom(4f).expandX().fill(); row().top().left(); contentCell = add().expand().fill(); - if (collapsable) + if (collapsable) { titleLbl.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { @@ -70,6 +73,17 @@ public void clicked(InputEvent event, float x, float y) { invalidateHierarchy(); } }); + + collapseImg.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + toggleCollapse(); + invalidateHierarchy(); + } + }); + } + +// setDebug(true); } public void setTile(String title) { @@ -77,8 +91,7 @@ public void setTile(String title) { } public void setContent(Actor center) { - removeActor(this.content); - + this.contentCell.clearActor(); this.content = center; this.contentCell.setActor(center); @@ -98,12 +111,15 @@ public void setCollapsable(boolean c) { public void toggleCollapse() { if (collapsable) { if (contentCell.getActor() != null) { - removeActor(this.content); +// if (this.content.isVisible()) { +// this.content.setVisible(false); + this.contentCell.clearActor(); invalidateHierarchy(); collapseImg.setDrawable(new TextureRegionDrawable(Ctx.assetManager.getIcon("ic_closed"))); } else { - this.contentCell.setActor(content); + this.contentCell.setActor(content); +// this.content.setVisible(true); invalidateHierarchy(); collapseImg.setDrawable(new TextureRegionDrawable(Ctx.assetManager.getIcon("ic_open"))); diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/InputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/InputPanel.java new file mode 100644 index 000000000..31dd717b1 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/InputPanel.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextTooltip; +import com.bladecoder.engine.util.DPIUtils; + +public abstract class InputPanel extends Table { + private static final boolean USE_TOOLTIPS = true; + + protected Actor field; + private Label title; + private Label desc; + private boolean mandatory = false; + + InputPanel() { + } + + protected void init(Skin skin, String title, String desc, Actor c, boolean mandatory, String defaultValue) { + // debug(); + + this.mandatory = mandatory; + + this.setSkin(skin); + LabelStyle style = new LabelStyle(skin.get(LabelStyle.class)); + this.title = new Label(title, style); + + this.desc = new Label(desc, skin, "subtitle"); + this.desc.setWrap(false); + + this.field = c; + + // row().expand(); + float titleWidth = this.title.getStyle().font.getSpaceXadvance() * 35; + add(this.title).width(titleWidth).left().top(); + this.title.setWidth(titleWidth); + this.title.setWrap(true); + // row().expand(); + add(field).expandX().left().top(); + + if (USE_TOOLTIPS) { + TextTooltip t = new TextTooltip(desc, skin); + t.getContainer().pad(DPIUtils.getSpacing() / 2); + this.title.addListener(t); + this.field.addListener(t); + } else { + row().expand(); + add(this.desc).colspan(2).left(); + } + + if (defaultValue != null) + setText(defaultValue); + } + + public void setMandatory(boolean value) { + mandatory = value; + } + + public boolean isMandatory() { + return mandatory; + } + + public void setError(boolean value) { + if (value) + title.getStyle().fontColor = Color.RED; + else + title.getStyle().fontColor = Color.WHITE; + } + + public abstract String getText(); + + public abstract void setText(String text); + + public String getTitle() { + return title.getText().toString(); + } + + public Actor getField() { + return field; + } + + public boolean validateField() { + + String s = getText(); + + if (mandatory) { + if (s == null || s.trim().isEmpty()) { + setError(true); + return false; + } + } + + setError(false); + return true; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/InputPanelFactory.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/InputPanelFactory.java new file mode 100644 index 000000000..47fa7481b --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/InputPanelFactory.java @@ -0,0 +1,228 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.Arrays; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engine.actions.Param.Type; +import com.bladecoder.engine.assets.EngineAssetManager; +import com.bladecoder.engineeditor.Ctx; +import com.bladecoder.engineeditor.model.Project; + +public class InputPanelFactory extends Table { + public static InputPanel createInputPanel(Skin skin, String title, String desc, String[] options, + boolean mandatory) { + return createInputPanel(skin, title, desc, Type.OPTION, mandatory, null, options); + } + + public static InputPanel createInputPanel(Skin skin, String title, String desc, Enum[] options, + boolean mandatory) { + return createInputPanel(skin, title, desc, Type.OPTION, mandatory, null, options); + } + + public static InputPanel createInputPanel(Skin skin, String title, String desc) { + return createInputPanel(skin, title, desc, Type.STRING, false, null); + } + + public static InputPanel createInputPanel(Skin skin, String title, String desc, boolean mandatory) { + return createInputPanel(skin, title, desc, Type.STRING, mandatory, null); + } + + public static InputPanel createInputPanel(Skin skin, String title, String desc, boolean mandatory, + String defaultValue) { + return createInputPanel(skin, title, desc, Type.STRING, mandatory, defaultValue); + } + + public static InputPanel createInputPanel(Skin skin, String title, String desc, Param.Type type, + boolean mandatory) { + return createInputPanel(skin, title, desc, type, mandatory, null, (String[]) null); + } + + public static InputPanel createInputPanel(Skin skin, String title, String desc, Param.Type type, boolean mandatory, + String defaultValue) { + return createInputPanel(skin, title, desc, type, mandatory, defaultValue, (String[]) null); + } + + public static InputPanel createInputPanel(Skin skin, String title, String desc, Param.Type type, boolean mandatory, + String defaultValue, Enum[] options) { + return createInputPanel(skin, title, desc, type, mandatory, defaultValue, (Object[]) options); + } + + public static InputPanel createInputPanel(Skin skin, String title, String desc, Param.Type type, boolean mandatory, + String defaultValue, String[] options) { + return createInputPanel(skin, title, desc, type, mandatory, defaultValue, (Object[]) options); + } + + private static InputPanel createInputPanel(Skin skin, String title, String desc, Param.Type type, boolean mandatory, + String defaultValue, Object[] options) { + switch (type) { + case ACTOR: + case CHARACTER_ACTOR: + case INTERACTIVE_ACTOR: + case SPRITE_ACTOR: + case WALKZONE_ACTOR: + return new ActorInputPanel(skin, title, desc, mandatory, defaultValue, type); + case LAYER: + return new LayerInputPanel(skin, title, desc, mandatory, defaultValue); + case BOOLEAN: + return new BooleanInputPanel(skin, title, desc, mandatory, defaultValue); + case CHAPTER: + return new ChapterInputPanel(skin, title, desc, mandatory, defaultValue); + case DIMENSION: + return new DimensionInputPanel(skin, title, desc, mandatory, defaultValue); + case FLOAT: + return new FloatInputPanel(skin, title, desc, mandatory, defaultValue); + case INTEGER: + return new IntegerInputPanel(skin, title, desc, mandatory, defaultValue); + case SCENE: + return new SceneInputPanel(skin, title, desc, mandatory, defaultValue); + case COLOR: + return new ColorInputPanel(skin, title, desc, mandatory, defaultValue); + case SOUND: + return new SoundInputPanel(skin, title, desc, mandatory, defaultValue); + case VOICE: + case TEXT_STYLE: + case STRING: + if (options != null) + return getReadOnlyOptionsInputPanel(skin, title, desc, mandatory, defaultValue, options); + + return new StringInputPanel(skin, title, desc, mandatory, defaultValue); + case VECTOR2: + return new Vector2InputPanel(skin, title, desc, mandatory, defaultValue); + case OPTION: + return getReadOnlyOptionsInputPanel(skin, title, desc, mandatory, defaultValue, options); + case EDITABLE_OPTION: + return new EditableOptionsInputPanel<>(skin, title, desc, mandatory, defaultValue, options); + case SCENE_ACTOR: + case SCENE_CHARACTER_ACTOR: + case SCENE_INTERACTIVE_ACTOR: + case SCENE_SPRITE_ACTOR: + case SCENE_WALKZONE_ACTOR: + return new SceneActorInputPanel(skin, title, desc, mandatory, defaultValue, type); + case ACTOR_ANIMATION: + return new ActorAnimationInputPanel(skin, title, desc, mandatory, defaultValue); + case VECTOR3: + break; + case FILE: + break; + case TEXT: + return new TextInputPanel(skin, title, desc, mandatory, defaultValue); + case BIG_TEXT: + TextInputPanel i = new TextInputPanel(skin, title, desc, mandatory, defaultValue); + i.setRows(20); + return i; + case SMALL_TEXT: + TextInputPanel i2 = new TextInputPanel(skin, title, desc, mandatory, defaultValue); + i2.setRows(5); + return i2; + + case ATLAS_ASSET: + case MUSIC_ASSET: + case SOUND_ASSET: + case PARTICLE_ASSET: + case FONT_ASSET: + return getReadOnlyOptionsInputPanel(skin, title, desc, mandatory, defaultValue, getAssetList(type)); + case NOT_SET: + break; + default: + break; + } + + return new StringInputPanel(skin, title, desc, mandatory, defaultValue); + } + + private static InputPanel getReadOnlyOptionsInputPanel(Skin skin, String title, String desc, boolean mandatory, + String defaultValue, Object[] options) { + if (options instanceof Enum[]) { + return new EnumOptionsInputPanel(skin, title, desc, mandatory, defaultValue, (Enum[]) options); + } else if (options instanceof String[]) { + return new StringOptionsInputPanel(skin, title, desc, mandatory, defaultValue, (String[]) options); + } else { + throw new RuntimeException("Unknown type of options: " + options.getClass()); + } + } + + private static String[] getAssetList(Param.Type type) { + String path = null; + final String exts[]; + boolean cutExt = false; + + if (type == Type.ATLAS_ASSET) { + path = Ctx.project.getAssetPath() + Project.ATLASES_PATH + "/" + Ctx.project.getResDir(); + exts = new String[1]; + exts[0] = EngineAssetManager.ATLAS_EXT; + cutExt = true; + } else if (type == Type.MUSIC_ASSET) { + path = Ctx.project.getAssetPath() + Project.MUSIC_PATH + "/"; + exts = new String[2]; + exts[0] = ".ogg"; + exts[1] = ".mp3"; + } else if (type == Type.SOUND_ASSET) { + path = Ctx.project.getAssetPath() + Project.SOUND_PATH + "/"; + exts = new String[2]; + exts[0] = ".ogg"; + exts[1] = ".mp3"; + } else if (type == Type.PARTICLE_ASSET) { + path = Ctx.project.getAssetPath() + Project.PARTICLE_PATH + "/"; + exts = null; + } else if (type == Type.FONT_ASSET) { + path = Ctx.project.getAssetPath() + Project.FONT_PATH + "/"; + exts = new String[1]; + exts[0] = ".ttf"; + cutExt = true; + } else { + exts = null; + } + + File f = new File(path); + + String list[] = f.list(new FilenameFilter() { + + @Override + public boolean accept(File arg0, String arg1) { + if (exts == null) + return true; + + for (String ext : exts) + if (arg1.endsWith(ext)) + return true; + + return false; + } + }); + + if(list == null) { + return new String[0]; + } + + Arrays.sort(list); + + if (cutExt) { + for (int i = 0; i < list.length; i++) { + int idx = list[i].lastIndexOf('.'); + if (idx != -1) + list[i] = list[i].substring(0, idx); + } + } + + return list; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/IntegerInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/IntegerInputPanel.java new file mode 100644 index 000000000..19bda2c9a --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/IntegerInputPanel.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; + +public class IntegerInputPanel extends StringInputPanel { + + IntegerInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue) { + super(skin, title, desc, mandatory, defaultValue); + } + + @Override + public boolean validateField() { + String s = getText(); + + if(s == null || s.trim().isEmpty()) { + if(isMandatory()) { + setError(true); + return false; + } else { + setError(false); + return true; + } + } + + try { + Integer.parseInt(s); + } catch (NumberFormatException e) { + setError(true); + return false; + } + + setError(false); + return true; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/LayerInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/LayerInputPanel.java new file mode 100644 index 000000000..a319aeff0 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/LayerInputPanel.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import java.util.List; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.bladecoder.engine.model.SceneLayer; +import com.bladecoder.engineeditor.Ctx; + +public class LayerInputPanel extends EditableOptionsInputPanel { + LayerInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue) { + super(skin, title, desc, mandatory, defaultValue, getValues(mandatory)); + } + + private static String[] getValues(boolean mandatory) { + List layers = Ctx.project.getSelectedScene().getLayers(); + + String[] result = new String[layers.size()]; + + + for(int i = 0; i < layers.size(); i++) { + result[i] = layers.get(i).getName(); + } + + return result; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ModelList.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ModelList.java new file mode 100644 index 000000000..6830c434d --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ModelList.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import java.util.List; + +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; + +public abstract class ModelList extends EditList { + + protected T clipboard; + protected PARENT parent; + + private boolean sorted; + + public ModelList(Skin skin, boolean sorted) { + super(skin); + + list.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + int pos = list.getSelectedIndex(); + + toolbar.disableEdit(pos == -1); + } + }); + + this.sorted = sorted; + } + + public void addElements(PARENT parent, List elements) { + + this.parent = parent; + list.getItems().clear(); + list.getSelection().clear(); + + if (elements != null) { + + for (T e : elements) { + addItem(e); + } + } + + toolbar.disableEdit(list.getSelectedIndex() < 0); + + if (sorted) { + list.sortByTitle(); + } + + if (getItems().size > 0) + list.getSelection().choose(list.getItems().get(0)); + + toolbar.disableCreate(parent == null); + // container.prefHeight(list.getItemHeight() * (list.getItems().size > + // 3?list.getItems().size:3)); + list.invalidateHierarchy(); + } + + @Override + protected void create() { + EditModelDialog dialog = getEditElementDialogInstance(null); + + dialog.show(getStage()); + dialog.setListener(new ChangeListener() { + @SuppressWarnings("unchecked") + @Override + public void changed(ChangeEvent event, Actor actor) { + T e = ((EditModelDialog) actor).getElement(); + + if (getItems().indexOf(e, true) == -1) { + addItem(e); + } + + if (sorted) { + list.sortByTitle(); + } + + int i = getItems().indexOf(e, true); + list.setSelectedIndex(i); + list.invalidateHierarchy(); + } + }); + } + + @Override + protected void edit() { + T e = list.getSelected(); + + if (e == null) + return; + + EditModelDialog dialog = getEditElementDialogInstance(e); + dialog.show(getStage()); + } + + protected abstract EditModelDialog getEditElementDialogInstance(T e); + + protected T removeSelected() { + int pos = list.getSelectedIndex(); + + if (pos == -1) + return null; + + T e = list.getItems().removeIndex(pos); + + clipboard = e; + + if (pos > 0) + list.setSelectedIndex(pos - 1); + else if (pos == 0 && list.getItems().size > 0) + list.setSelectedIndex(0); + else + list.getSelection().clear(); + + toolbar.disablePaste(false); + + return e; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/OptionsInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/OptionsInputPanel.java new file mode 100644 index 000000000..ad9f1ca0b --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/OptionsInputPanel.java @@ -0,0 +1,5 @@ +package com.bladecoder.engineeditor.ui.panels; + +public interface OptionsInputPanel { + int getSelectedIndex(); +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/PropertyTable.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/PropertyTable.java new file mode 100644 index 000000000..5a35a88e8 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/PropertyTable.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Container; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextField; +import com.badlogic.gdx.scenes.scene2d.ui.TextField.TextFieldListener; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.FocusListener; +import com.badlogic.gdx.utils.SnapshotArray; +import com.bladecoder.engineeditor.common.EditorLogger; + +public class PropertyTable extends Container

{ + private static final String[] BOOLEAN_VALUES = { "", "true", "false" }; + + Skin skin; + Table table; + + public enum Types { + INTEGER, BOOLEAN, FLOAT, STRING, OPTIONS + } + + public PropertyTable(Skin skin) { + // super(skin); + table = new Table(skin); + this.skin = skin; + top().left(); + table.top().left(); + + table.add(new Label("Name", skin)); + table.add(new Label("Value", skin)); + table.setFillParent(true); + + fill(); + prefHeight(1000); + + setActor(table); + } + + public void addProperty(String name, String value, Types type) { + + table.row(); + table.add(new Label(name, skin)).expandX().left(); + + if (type == Types.BOOLEAN) { + SelectBox sb = new SelectBox(skin); + sb.setItems(BOOLEAN_VALUES); + if (value != null) + sb.setSelected(value); + sb.setName(name); + table.add(sb).expandX().left(); + + sb.addListener(new ChangeListener() { + + @SuppressWarnings("unchecked") + @Override + public void changed(ChangeEvent event, Actor actor) { + updateModel(actor.getName(), ((SelectBox) actor).getSelected()); + + } + }); + } else { + TextField tf = new TextField(value == null ? "" : value, skin); + tf.setName(name); + table.add(tf).expandX().left(); + + if (type == Types.INTEGER) + tf.setTextFieldFilter(new TextField.TextFieldFilter.DigitsOnlyFilter()); + + tf.setTextFieldListener(new TextFieldListener() { + @Override + public void keyTyped(TextField actor, char c) { + if (c == 13) { // ENTER KEY + updateModel(actor.getName(), ((TextField) actor).getText()); + EditorLogger.debug("Updating property: " + actor.getName()); + } + } + }); + + tf.addListener(new FocusListener() { + + @Override + public void keyboardFocusChanged(FocusEvent event, Actor actor, boolean focused) { + if (!focused) { + updateModel(actor.getName(), ((TextField) actor).getText()); + EditorLogger.debug("Updating property: " + actor.getName()); + } + } + }); + } + } + + @SuppressWarnings("unchecked") + public void setProperty(String name, String value) { + SnapshotArray actors = table.getChildren(); + + for (Actor a : actors) { + if (name.equals(a.getName())) { + if (a instanceof SelectBox) { + ((SelectBox) a).setSelected(value == null ? "" : value); + } else { + ((TextField) a).setText(value == null ? "" : value); + } + + return; + } + } + } + + public void addProperty(String name, int value) { + addProperty(name, Integer.toString(value), Types.INTEGER); + } + + public void addProperty(String name, float value) { + addProperty(name, Float.toString(value), Types.FLOAT); + } + + public void addProperty(String name, String value) { + addProperty(name, value, Types.STRING); + } + + public void addProperty(String name, boolean value) { + addProperty(name, Boolean.toString(value), Types.BOOLEAN); + } + + public void addProperty(String name, String selected, String[] value) { + table.row(); + table.add(new Label(name, skin)).expandX().left(); + + SelectBox sb = new SelectBox(skin); + sb.setItems(value); + if (selected != null) + sb.setSelected(selected); + sb.setName(name); + table.add(sb).expandX().left(); + + sb.addListener(new ChangeListener() { + + @SuppressWarnings("unchecked") + @Override + public void changed(ChangeEvent event, Actor actor) { + updateModel(actor.getName(), ((SelectBox) actor).getSelected()); + } + }); + } + + protected void updateModel(String property, String value) { + + } + + protected void clearProps() { + table.clear(); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/SceneActorInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/SceneActorInputPanel.java new file mode 100644 index 000000000..99d7410b0 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/SceneActorInputPanel.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Map; + +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.bladecoder.engine.actions.Param; +import com.bladecoder.engine.actions.SceneActorRef; +import com.bladecoder.engine.model.BaseActor; +import com.bladecoder.engine.model.CharacterActor; +import com.bladecoder.engine.model.InteractiveActor; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.SpriteActor; +import com.bladecoder.engine.model.WalkZoneActor; +import com.bladecoder.engineeditor.Ctx; + +public class SceneActorInputPanel extends InputPanel { + FilteredSelectBox scene; + EditableSelectBox actor; + Table panel; + + private final Param.Type type; + + + SceneActorInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue, Param.Type type) { + + this.type = type; + + panel = new Table(skin); + scene = new FilteredSelectBox<>(skin); + actor = new EditableSelectBox<>(skin); + + panel.add(new Label(" Scene ", skin)); + panel.add(scene); + panel.add(new Label(" Actor ", skin)); + panel.add(actor); + + Scene[] scenes = Ctx.project.getWorld().getScenes().values().toArray(new Scene[0]); + + int l = scenes.length + 1; + + String values[] = new String[l]; + + values[0] = ""; + + for (int i = 0; i < scenes.length; i++) { + values[i + 1] = scenes[i].getId(); + } + + Arrays.sort(values); + + scene.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + sceneSelected(); + } + }); + + init(skin, title, desc, panel, mandatory, defaultValue); + + scene.setItems(values); + + if (values.length > 0) { + if (defaultValue != null) + setText(defaultValue); + else + scene.setSelectedIndex(0); + } + + + } + + private void sceneSelected() { + String s = scene.getSelected(); + + if(s == null || s.isEmpty()) { + s = Ctx.project.getSelectedScene().getId(); + } + + Scene scn = Ctx.project.getWorld().getScene(s); + + actor.setItems(getActorValues(scn)); + } + + public String getText() { + if(actor.getSelected().isEmpty()) + return null; + + return (new SceneActorRef(scene.getSelected(), actor.getSelected())).toString(); + } + + public void setText(String s) { + SceneActorRef aa = new SceneActorRef(s); + + scene.setSelected(aa.getSceneId() == null?"":aa.getSceneId()); + sceneSelected(); + actor.setSelected(aa.getActorId()); + } + + private String[] getActorValues(Scene scn) { + Map actors = scn.getActors(); + + ArrayList filteredActors = new ArrayList(); + + for(BaseActor a: actors.values()) { + if(type == Param.Type.SCENE_CHARACTER_ACTOR) { + if(a instanceof CharacterActor) + filteredActors.add(a); + } else if(type == Param.Type.SCENE_INTERACTIVE_ACTOR) { + if(a instanceof InteractiveActor) + filteredActors.add(a); + } else if(type == Param.Type.SCENE_SPRITE_ACTOR) { + if(a instanceof SpriteActor) + filteredActors.add(a); + } else if(type == Param.Type.SCENE_WALKZONE_ACTOR) { + if(a instanceof WalkZoneActor) + filteredActors.add(a); + } else { + filteredActors.add(a); + } + } + + String[] result = null; + + if (type != Param.Type.SCENE_WALKZONE_ACTOR) { + // Add player variable to the list + result = new String[filteredActors.size() + 1]; + + result[0] = Scene.VAR_PLAYER; + + for (int i = 0; i < filteredActors.size(); i++) { + result[i + 1] = filteredActors.get(i).getId(); + } + } else { + result = new String[filteredActors.size()]; + + for (int i = 0; i < filteredActors.size(); i++) { + result[i] = filteredActors.get(i).getId(); + } + } + + Arrays.sort(result); + + return result; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/SceneInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/SceneInputPanel.java new file mode 100644 index 000000000..b83cb1b30 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/SceneInputPanel.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import java.util.Arrays; +import java.util.Map; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.bladecoder.engine.model.Scene; +import com.bladecoder.engine.model.World; +import com.bladecoder.engineeditor.Ctx; + +public class SceneInputPanel extends StringOptionsInputPanel { + SceneInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue) { + super(skin, title, desc, mandatory, defaultValue, getValues(mandatory)); + } + + private static String[] getValues(boolean mandatory) { + Map scenes = Ctx.project.getWorld().getScenes(); + + String[] result = new String[scenes.size() + 1]; + + Scene[] v = scenes.values().toArray(new Scene[scenes.size()]); + + for(int i = 0; i < scenes.size(); i++) { + result[i] = v[i].getId(); + } + + result[scenes.size()] = "$" + World.WorldProperties.PREVIOUS_SCENE.toString(); + + Arrays.sort(result); + + return result; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ScopePanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ScopePanel.java new file mode 100644 index 000000000..5709f2a44 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/ScopePanel.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.ui.ButtonGroup; +import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.Array; + +abstract public class ScopePanel extends Table { + public static String WORLD_SCOPE = "World"; + public static String SCENE_SCOPE = "Scene"; + public static String ACTOR_SCOPE = "Actor"; + + private ButtonGroup buttonGroup; + private HorizontalGroup hPanel; + private Skin skin; + + public ScopePanel(Skin skin) { + super(skin); + this.skin = skin; + buttonGroup = new ButtonGroup(); + hPanel = new HorizontalGroup(); + hPanel.wrap(true); + hPanel.rowAlign(Align.left); + + buttonGroup.setMaxCheckCount(1); + buttonGroup.setMinCheckCount(1); + buttonGroup.setUncheckLast(true); + + hPanel.addActor(new Label("Scope: ", skin)); + + addButton(WORLD_SCOPE); + addButton(SCENE_SCOPE); + addButton(ACTOR_SCOPE); + + add(hPanel).expandX().fillX().center(); + + buttonGroup.getButtons().get(2).setChecked(true); + } + + private void addButton(String name) { + TextButton button = new TextButton(name, skin); + buttonGroup.add(button); + hPanel.addActor(button); + + button.addListener(new ClickListener() { + + @Override + public void clicked (InputEvent event, float x, float y) { + changeScope((TextButton)event.getListenerActor()); + } + }); + } + + public int getSelectedIndex() { + for(int i=0; i < buttonGroup.getButtons().size; i++) { + if(buttonGroup.getButtons().get(i) == buttonGroup.getChecked()) + return i; + } + + return -1; + } + + public void changeScope(TextButton b) { + b.setChecked(true); + + scopeChanged(b.getText().toString()); + } + + abstract public void scopeChanged(String scope); + + public String getScope() { + return buttonGroup.getChecked().getText().toString(); + } + + public void clear() { + Array buttons = buttonGroup.getButtons(); + + buttons.clear(); + hPanel.clear(); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/SoundInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/SoundInputPanel.java new file mode 100644 index 000000000..a45f62497 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/SoundInputPanel.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import java.util.Arrays; +import java.util.Map; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.bladecoder.engine.model.SoundDesc; +import com.bladecoder.engineeditor.Ctx; + +public class SoundInputPanel extends StringOptionsInputPanel { + SoundInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue) { + super(skin, title, desc, mandatory, defaultValue, getValues(mandatory)); + } + + private static String[] getValues(boolean mandatory) { + Map sounds = Ctx.project.getWorld().getSounds(); + + String[] result = new String[sounds.size()]; + + SoundDesc[] v = sounds.values().toArray(new SoundDesc[sounds.size()]); + + for(int i = 0; i < sounds.size(); i++) { + result[i] = v[i].getId(); + } + + Arrays.sort(result); + + return result; + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/StringInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/StringInputPanel.java new file mode 100644 index 000000000..2f7c6d887 --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/StringInputPanel.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextField; + +public class StringInputPanel extends InputPanel { + TextField input; + + StringInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue) { + input = new TextField("", skin); + init(skin, title, desc, input, mandatory, defaultValue); + } + + public String getText() { + String text = ((TextField)field).getText(); + return text.isEmpty()?null:text; + } + + public void setText(String s) { + ((TextField)field).setText(s); + } +} diff --git a/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/StringOptionsInputPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/StringOptionsInputPanel.java new file mode 100644 index 000000000..68aee808c --- /dev/null +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/StringOptionsInputPanel.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright 2014 Rafael Garcia Moreno. + * + * 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 com.bladecoder.engineeditor.ui.panels; + +import com.badlogic.gdx.scenes.scene2d.ui.Skin; + +public class StringOptionsInputPanel extends InputPanel implements OptionsInputPanel { + private final FilteredSelectBox input; + + StringOptionsInputPanel(Skin skin, String title, String desc, boolean mandatory, String defaultValue, String[] options) { + input = new FilteredSelectBox(skin); + + int l = options.length; + if(!mandatory) l++; + String values[] = new String[l]; + + if(!mandatory) { + values[0] = ""; + } + + System.arraycopy(options, 0, values, mandatory ? 0 : 1, options.length); + + input.setItems(values); + + init(skin, title, desc, input, mandatory, defaultValue); + } + + @Override + public String getText() { + if(input.getSelected()==null) + return null; + + return input.getSelected().isEmpty()?null:input.getSelected(); + } + + @Override + public void setText(String s) { + if(s == null) + return; + + int idx = input.getItems().indexOf(s, false); + if(idx != -1) + input.setSelectedIndex(idx); + } + + @Override + public int getSelectedIndex() { + return input.getSelectedIndex(); + } +} diff --git a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/TabPanel.java b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/TabPanel.java similarity index 89% rename from adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/TabPanel.java rename to adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/TabPanel.java index 4b5e73e8e..f915aff25 100644 --- a/adventure-composer/src/main/java/com/bladecoder/engineeditor/ui/components/TabPanel.java +++ b/adventure-editor/src/main/java/com/bladecoder/engineeditor/ui/panels/TabPanel.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ -package com.bladecoder.engineeditor.ui.components; +package com.bladecoder.engineeditor.ui.panels; import java.util.ArrayList; import java.util.List; @@ -28,11 +28,11 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; -import com.badlogic.gdx.scenes.scene2d.utils.Layout; +import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Array; public class TabPanel extends Table { - private ButtonGroup buttonGroup; + private ButtonGroup