123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- /* GCSx
- ** ANIMGROUPEDIT.CPP
- **
- ** Animation group support
- ** Expands basic AnimGroup to include editor functionality
- */
- /*****************************************************************************
- ** Copyright (C) 2003-2006 Janson
- **
- ** This program is free software; you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation; either version 2 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program; if not, write to the Free Software
- ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
- #include "all.h"
- AnimGroupEdit::AnimGroupEdit(WorldEdit* myWorld, int myId) : AnimGroup(myWorld, myId) { start_func
- assert(myWorld);
- // Find an unused "Untitled" name
- if (myId) {
- string findName("animations");
- int pos = 1;
- while (myWorld->findAnimGroup(findName)) {
- findName = "animations ";
- findName += intToStr(++pos);
- }
-
- findName[0] = toupper(findName[0]);
- name = findName;
- headerModified = contentModified = 1;
- }
- else headerModified = contentModified = 0;
- nameL = name;
- toLower(nameL);
- browserNode = NULL;
- disassociated = 0;
- desktop->broadcastObjChange(OBJ_ANIMGROUP | OBJMOD_CREATE, this, 0, 0);
- }
- AnimGroupEdit::~AnimGroupEdit() { start_func
- // @TODO: doesn't appear to be needed; no way to delete accidentally
- // if (!disassociated) desktop->broadcastObjChange(OBJ_ANIMGROUP | OBJMOD_DELETE, this, 0, 0);
- // World should be the one deleting us, which will delete our node also
- }
- void AnimGroupEdit::disassociate() throw_File { start_func
- // Ensure not cached- our exception point
- cacheLoad();
-
- // Drop browser node
- dropBrowser();
-
- // Notify objects
- desktop->broadcastObjChange(OBJ_ANIMGROUP | OBJMOD_DELETE, this, 0, 0);
-
- disassociated = 1;
- }
- void AnimGroupEdit::reassociate(TreeView* node) { start_func
- assert(disassociated);
-
- // Notify objects
- desktop->broadcastObjChange(OBJ_ANIMGROUP | OBJMOD_CREATE, this, 0, 0);
-
- // Browser node
- addToBrowser(node, 0);
- // Ensure written to file
- headerModified = contentModified = 1;
- disassociated = 0;
- }
- void AnimGroupEdit::setHeaderModified() { start_func
- if (!headerModified) headerModified = 1;
- }
- void AnimGroupEdit::setContentModified() { start_func
- if (!contentModified) {
- contentModified = 1;
- // No possibility of returning to cache
- delete cacheFile;
- cacheFile = NULL;
- }
- }
- void AnimGroupEdit::dropBrowser() { start_func
- browserNode = NULL;
- }
- void AnimGroupEdit::addToBrowser(TreeView* node, int makeCurrent) { start_func
- browserNode = new TreeView(name, this, 0, treeviewEventWrap);
- browserNode->setIcon(7);
- node->insert(browserNode, makeCurrent);
- }
- int AnimGroupEdit::treeviewEvent(int code, int command, int check) { start_func
- if (check) {
- if (command == EDIT_DELETE) return Window::COMMAND_ENABLE;
- return Window::COMMAND_HIDE;
- }
- switch (command) {
- case LV_SELECT:
- openBrowseWindow();
- return 1;
-
- case LV_RCLICK:
- // @TODO: Should actually be a popup with this as an item
- propertiesDialog(desktop->findPreviousFocusWindow());
- return 1;
-
- case EDIT_DELETE:
- case LV_DELETE:
- // Handles any error conditions/cancellation for us
- getWorldEdit()->deleteAnimGroup(this, desktop->findPreviousFocusWindow());
- return 1;
- }
-
- return 0;
- }
- int AnimGroupEdit::treeviewEventWrap(void* ptr, int code, int command, int check) { start_func
- return ((AnimGroupEdit*)ptr)->treeviewEvent(code, command, check);
- }
- void AnimGroupEdit::setSize(int newCount, Window* srcWin, Window* exWin) throw_Undo { start_func
- // @TODO: Undo (already in throw def), update events
- if (newCount != numAnim) {
- setHeaderModified();
- setContentModified();
- AnimSequence* newAnims = NULL;
- if (newCount) {
- newAnims = new AnimSequence[newCount];
- // Copy existing
- for (int pos = min(numAnim, newCount) - 1; pos >= 0; --pos) {
- newAnims[pos] = anims[pos];
- }
- // (any empty spaces initialized already)
- }
- delete[] anims;
- anims = newAnims;
- numAnim = newCount;
- }
- }
- void AnimGroupEdit::setName(const string& newName, Window* srcWin, Window* exWin) throw_Undo { start_func
- if (name != newName) {
- setHeaderModified();
- if (world) {
- getWorldEdit()->undo.storeUndoName(UndoBuffer::UNDO_ANIMGROUPNAME, id, name, newName, srcWin);
- world->deindexAnimGroup(this);
- }
- name = newName;
- nameL = newName;
- toLower(nameL);
- if (world) world->indexAnimGroup(this);
- if (browserNode) browserNode->changeName(newName);
-
- desktop->broadcastObjChange(OBJ_TILESET | OBJMOD_NAME, this, 0, 0, exWin);
- }
- }
- void AnimGroupEdit::openEditWindow(int subid) { start_func
- try {
- if (!numAnim) return;
- if (subid < 1) subid = 1;
- else if (subid > numAnim) subid = numAnim;
- new AnimGroupPaint(this, subid); // Exception point
- }
- catch (FileException& e) {
- guiErrorBox(string(e.details), errorTitleFile);
- }
- }
- void AnimGroupEdit::openBrowseWindow() { start_func
- try {
- //@TODO: new window
- //@TODO: add anim requires at least one tileset
- }
- catch (FileException& e) {
- guiErrorBox(string(e.details), errorTitleFile);
- }
- }
- void AnimGroupEdit::loadAnim(int id, AnimSequence* copyAnim) { start_func
- assert(id > 0);
- assert(id <= numAnim);
-
- *copyAnim = anims[id - 1];
- }
- void AnimGroupEdit::saveAnim(int id, const AnimSequence* newAnim, Window* exWin) { start_func
- assert(id > 0);
- assert(id <= numAnim);
-
- anims[id - 1] = *newAnim;
- desktop->broadcastObjChange(OBJ_ANIMGROUP | OBJMOD_ANIM, this, id, 0, exWin);
- }
- void AnimGroupEdit::loadAnimName(int id, string* copyName) { start_func
- assert(id > 0);
- assert(id <= numAnim);
-
- *copyName = anims[id - 1].name;
- }
- void AnimGroupEdit::saveAnimName(int id, const string* newName, Window* exWin) { start_func
- assert(id > 0);
- assert(id <= numAnim);
- if (anims[id - 1].name != *newName) {
- anims[id - 1].name = *newName;
- desktop->broadcastObjChange(OBJ_ANIMGROUP | OBJMOD_NAME, this, id - 1, 0, exWin);
- }
- }
- int AnimGroupEdit::propertiesDialog(Window* srcWin, Window* exWin) { start_func
- string newName = name;
- if (AnimGroupPropertiesDialog::create()->run(&newName, this)) {
- try {
- markLock();
- }
- catch (FileException& e) {
- guiErrorBox(string(e.details), errorTitleFile);
- return 0;
- }
- try {
- getWorldEdit()->undo.preUndoBlock();
- setName(newName, srcWin, exWin);
- getWorldEdit()->undo.postUndoBlock();
- }
- catch (UndoException& e) {
- markUnlock();
- return 0;
- }
- markUnlock();
- return 1;
- }
-
- return 0;
- }
- int AnimGroupEdit::isHeaderModified() const { start_func
- return headerModified;
- }
- int AnimGroupEdit::isContentModified() const { start_func
- return contentModified;
- }
- Uint32 AnimGroupEdit::saveHeader(FileWrite* file) throw_File { start_func
- file->writeStr(name);
- file->writeInt(id);
- file->writeInt(defWidth);
- file->writeInt(defHeight);
- file->writeInt(numAnim);
-
- return 1;
- }
- void AnimGroupEdit::saveContent(FileWrite* file) throw_File { start_func
- // (our data shouldn't be empty unless we have none
- assert(anims || !numAnim);
- if (numAnim) {
- for (int pos = 0; pos < numAnim; ++pos) {
- file->writeStr(anims[pos].name);
- file->writeInt(anims[pos].count);
- file->writeInt(anims[pos].width);
- file->writeInt(anims[pos].height);
- file->writeInt8(anims[pos].loopType);
-
- // Frames
- for (int subpos = 0; subpos < anims[pos].count; ++subpos) {
- file->writeInt(anims[pos].frames[subpos].count);
- file->writeInt16(anims[pos].frames[subpos].xOrigin);
- file->writeInt16(anims[pos].frames[subpos].yOrigin);
- file->writeInt16(anims[pos].frames[subpos].xOffs);
- file->writeInt16(anims[pos].frames[subpos].yOffs);
- file->writeInt8(anims[pos].frames[subpos].delay);
-
- // Components
- for (int subsubpos = 0; subsubpos < anims[pos].frames[subpos].count; ++subsubpos) {
- file->writeInt(anims[pos].frames[subpos].comps[subsubpos].tileset->getId());
- file->writeInt16(anims[pos].frames[subpos].comps[subsubpos].index);
- file->writeInt16(anims[pos].frames[subpos].comps[subsubpos].x);
- file->writeInt16(anims[pos].frames[subpos].comps[subsubpos].y);
- file->writeInt8(anims[pos].frames[subpos].comps[subsubpos].r);
- file->writeInt8(anims[pos].frames[subpos].comps[subsubpos].g);
- file->writeInt8(anims[pos].frames[subpos].comps[subsubpos].b);
- file->writeInt8(anims[pos].frames[subpos].comps[subsubpos].alpha);
- file->writeInt8(anims[pos].frames[subpos].comps[subsubpos].effects);
- }
- }
- }
- }
- }
- void AnimGroupEdit::saveSuccess() { start_func
- headerModified = 0;
- contentModified = 0;
- }
- void AnimGroupEdit::cachedContent(FileRead* file, int oldData) { start_func
- // If already cached..
- if (cached) {
- delete cacheFile;
- cacheFile = file;
- }
- else if (oldData) {
- delete file;
- }
- else {
- // Cache ourselves?
- if (!lockCount) {
- delete cacheFile;
- cacheFile = file;
- delete[] anims;
- anims = NULL;
- cached = 1;
- }
- else {
- delete file;
- }
- }
- }
|