| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617 |
- /*
- ** Command & Conquer Generals Zero Hour(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** 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 3 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, see <http://www.gnu.org/licenses/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // FILE: GUIEditWindowManager.cpp /////////////////////////////////////////////////////////////////
- // Created: Colin Day, July 2001
- // Desc: Window manager for the GUI edit tool, we want this up
- // fast and to look like what we use in the game so we're going
- // to use the WW3D window manager, and just override the
- // drawing functions to draw lines and images to the
- // display. We will also be adding our own functionality
- // here for editing and interacting with the GUI windows.
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- #include <stdlib.h>
- #include <stdio.h>
- #include "Common/Debug.h"
- #include "GameClient/GadgetSlider.h"
- #include "GUIEditWindowManager.h"
- #include "EditWindow.h"
- #include "GUIEdit.h"
- #include "HierarchyView.h"
- // PUBLIC DATA ////////////////////////////////////////////////////////////////////////////////////
- GUIEditWindowManager *TheGUIEditWindowManager = NULL; ///< editor use only
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- //-------------------------------------------------------------------------------------------------
- /** Is the given widnow in the clipboard at the top level. NOTE that
- * children are NOT included in this search */
- //-------------------------------------------------------------------------------------------------
- Bool GUIEditWindowManager::isWindowInClipboard( GameWindow *window,
- GameWindow **list )
- {
- GameWindow *other;
- // sanity
- if( list == NULL || window == NULL )
- return FALSE;
- // just run through the window list in the clipboard to check
- for( other = *list; other; other = other->winGetNext() )
- {
- if( window == other )
- return TRUE; // found
- } // end for window
- return FALSE; // not found
- } // end isWindowInClipboard
- //-------------------------------------------------------------------------------------------------
- /** Add the window to clipboard list */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::linkToClipboard( GameWindow *window,
- GameWindow **list )
- {
- // sanity
- if( window == NULL || list == NULL )
- return;
- // debug sanity checking, can't add if already in it
- if( isWindowInClipboard( window, list ) )
- return;
- window->winSetPrev( NULL );
- window->winSetNext( *list );
- if( *list )
- (*list)->winSetPrev( window );
- *list = window;
- } // end linkToClipboard
- //-------------------------------------------------------------------------------------------------
- /** Unlink window from the clipboard list */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::unlinkFromClipboard( GameWindow *window,
- GameWindow **list )
- {
- GameWindow *next, *prev;
- // sanity
- if( window == NULL || list == NULL )
- return;
- // debug sanity checking, can't remove if not in
- if( isWindowInClipboard( window, list ) == FALSE )
- return;
- prev = window->winGetPrev();
- next = window->winGetNext();
- if( next )
- next->winSetPrev( prev );
- if( prev )
- prev->winSetNext( next );
- else
- *list = next;
- } // end unlinkFromClipboard
- //-------------------------------------------------------------------------------------------------
- /** Remove selection entries for child windows that also have ANY of
- * their parents in the selection list. */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::removeSupervisedChildSelections( void )
- {
- WindowSelectionEntry *select, *next;
- GameWindow *window, *parent;
- // iterate selections
- for( select = TheEditor->getSelectList(); select; select = next )
- {
- Bool parentSelected;
- // get next entry
- next = select->next;
- // get window data
- window = select->window;
- parent = window->winGetParent();
- // check to see if any parent is selected
- parentSelected = FALSE;
- while( parent )
- {
- if( TheEditor->isWindowSelected( parent ) )
- parentSelected = TRUE;
- parent = parent->winGetParent();
- } // end while
- //
- // if there is a parent selected then we can remove this
- // selection
- //
- if( parentSelected == TRUE )
- TheEditor->unSelectWindow( window );
- } // end for select
- } // end removeSupervisedChildSelections
- //-------------------------------------------------------------------------------------------------
- /** Traverse the selected window list, any child windows we encounter
- * are removed from their parent and placed in the window list at
- * the top level. Window position adjustments are made to compensate
- * for the transition from "parent space" to "screen space" */
- //-------------------------------------------------------------------------------------------------
- /*
- void GUIEditWindowManager::orphanSelectedChildren( void )
- {
- WindowSelectionEntry *select;
- GameWindow *window, *parent;
- for( select = TheEditor->getSelectList(); select; select = select->next )
- {
-
- // get window information
- window = select->window;
- parent = window->winGetParent();
- // we have a parent we're a candidate
- if( parent )
- {
- ICoord2D pos;
- // get the screen position of the window BEFORE we remove the parent
- window->winGetScreenPosition( &pos.x, &pos.y );
- // remove the child from the parent and add to top level of window system
- window->winSetParent( NULL );
- //
- // adjust the position, which previously was relative to the parent
- // but now is relative to the screen
- //
- window->winSetPosition( pos.x, pos.y );
- } // end if, we had a parent
- } // end for select
- } // end orphanSelectedChildren
- */
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- // PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- GUIEditWindowManager::GUIEditWindowManager( void )
- {
- m_clipboard = NULL;
- m_clipboardDup = NULL;
- m_copySpacing = 8;
- m_numCopiesPasted = 0;
- } // end GUIEditWindowManager
- //-------------------------------------------------------------------------------------------------
- //-------------------------------------------------------------------------------------------------
- GUIEditWindowManager::~GUIEditWindowManager( void )
- {
- // the duplicate list is only used in the actual act of pasting
- assert( m_clipboardDup == NULL );
- // free all data on the clipboard
- resetClipboard();
- } // end ~GUIEditWindowManager
- //-------------------------------------------------------------------------------------------------
- /** initialize the system */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::init( void )
- {
- // extending functionality
- W3DGameWindowManager::init();
- } // end init
- //-------------------------------------------------------------------------------------------------
- /** Destroy a game window */
- //-------------------------------------------------------------------------------------------------
- Int GUIEditWindowManager::winDestroy( GameWindow *window )
- {
- //
- // delete the edit data from window if present, the editor is the
- // ONLY place where this edit data is allocated anyway, it is
- // NOT present in the game
- //
- GameWindowEditData *editData = window->winGetEditData();
- if( editData )
- {
- // delete it
- delete editData;
- // set the edit data to NULL in the window
- window->winSetEditData( NULL );
- } // end if
- // call our base class functionality
- return W3DGameWindowManager::winDestroy( window );
- } // end winDestroy
- //-------------------------------------------------------------------------------------------------
- /** Create a new window by setting up its parameters and callbacks. */
- //-------------------------------------------------------------------------------------------------
- GameWindow *GUIEditWindowManager::winCreate( GameWindow *parent,
- UnsignedInt status,
- Int x, Int y,
- Int width, Int height,
- GameWinSystemFunc system,
- WinInstanceData *instData )
- {
- GameWindow *window;
- // call base class create
- window = W3DGameWindowManager::winCreate( parent, status, x, y,
- width, height, system,
- instData );
- // allocate edit data for the window
- if( window )
- {
- GameWindowEditData *editData = new GameWindowEditData;
- // set edit data to nothing
- memset( editData, 0, sizeof( GameWindowEditData ) );
- // attach edit data to window
- window->winSetEditData( editData );
- } // end if
- return window;
- } // end winCreate
- //-------------------------------------------------------------------------------------------------
- /** Destroy all windows in the clipboard */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::resetClipboard( void )
- {
- GameWindow *window, *next;
- // iterate through all windows
- for( window = m_clipboard; window; window = next )
- {
- // get next window
- next = window->winGetNext();
- //
- // in order for the destroy to really work correctly, the system
- // assumes that the window is actually part of the system, so take it
- // away from the clipboard and add it back to the regular system
- //
- unlinkFromClipboard( window, &m_clipboard );
- linkWindow( window );
- //
- // delete the window, note that these aren't part of the active editor,
- // the live only in the clipboard land so we don't need to notify
- // the edit window or the editor that this is going away ... they can't
- // possible be selected or anything
- //
- winDestroy( window );
- } // end for window
- // immediately process the destroyed windows just to be clean here
- processDestroyList();
- // nothing in the buffer now
- m_clipboard = NULL;
- m_numCopiesPasted = 0;
- } // end resetClipboard
- //-------------------------------------------------------------------------------------------------
- /** Is the clipboard empty */
- //-------------------------------------------------------------------------------------------------
- Bool GUIEditWindowManager::isClipboardEmpty( void )
- {
- if( m_clipboard )
- return TRUE;
- return FALSE;
- } // end isClipboardEmtpy
- //-------------------------------------------------------------------------------------------------
- /** Remove the selected windows from the current layout and put them into
- * the clipboard. If the parent of a window is not being cut with the
- * child the child will have no parent and will be adjusted to absolute
- * screen coordinates with no parent */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::cutSelectedToClipboard( void )
- {
- //
- // reset the clipboard just to be safe, this is done in the copy but
- // it's nice cause we depend on it here for deleting
- //
- resetClipboard();
- // first copy the selected windows to the clipboard
- copySelectedToClipboard();
- //
- // now delete the selected windows from the scene if we actually
- // copied them to the clipboard
- //
- if( m_clipboard )
- TheEditor->deleteSelected();
- } // end cutSelectedToClipboard
- //-------------------------------------------------------------------------------------------------
- /** Given the current window in a list pointed to by 'root', if that
- * window is selected, duplicate it and place it on the clipboard. If
- * it's not selected check it's children to see if any of them are
- * selected and should be duplicated. Then just move on down the list
- * and check the other sibling windows as well */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::duplicateSelected( GameWindow *root )
- {
- // end of recursion
- if( root == NULL )
- return;
- // if widow is selected duplicate and continue on
- if( TheEditor->isWindowSelected( root ) )
- {
- GameWindow *duplicate;
- // perform the duplication of window and all children
- duplicate = duplicateWindow( root, NULL );
- if( duplicate )
- {
- //
- // if our source window had a parent, that means that the child
- // was selected, but the parent wasn't. Therefore the new
- // duplicate has no parent, but needs to have its position
- // adjusted to be relative to the screen instead of the now
- // missing parent
- //
- GameWindow *parent = root->winGetParent();
- if( parent )
- {
- ICoord2D parentPos;
- ICoord2D pos;
- parent->winGetScreenPosition( &parentPos.x, &parentPos.y );
- duplicate->winGetScreenPosition( &pos.x, &pos.y );
- pos.x += parentPos.x;
- pos.y += parentPos.y;
- duplicate->winSetPosition( pos.x, pos.y );
-
- } // end if
- // add window to the clipboard
- linkToClipboard( duplicate, &m_clipboard );
- } // end if
- } // end if
- else
- {
- //
- // the window itself is not selected, but some of it's children
- // may be so check them
- //
- duplicateSelected( root->winGetChild() );
- } // end else
- // move on to the next window
- duplicateSelected( root->winGetNext() );
- } // end duplicateSelected
- //-------------------------------------------------------------------------------------------------
- /** Copy the selected windows to the clipboard */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::copySelectedToClipboard( void )
- {
- // reset the contents of the clipboard
- resetClipboard();
- //
- // to simplify things, child windows that ALSO have their
- // parent window selected will become unselected, anything that
- // happens to the parent will automatically include the child
- //
- removeSupervisedChildSelections();
- //
- // go through the window list and duplicate anything selected, note
- // that the clipboard will contain the list of windows in reverse
- // order from the original order in the layout
- //
- duplicateSelected( m_windowList );
- } // end copySelectedToClipboard
- //-------------------------------------------------------------------------------------------------
- /** Take the string representation of the name of the window passed in,
- * and add a number to it at the end. If there is already a number
- * on it at the end, that number will be incremented */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::incrementName( GameWindow *window )
- {
- WinInstanceData *instData = window->winGetInstanceData();
- // bleah, this is ugly and hokey, but if I rewrite
- // this I will botch it (cuz I'm currently not sure
- // how to test it)
- char name[MAX_WINDOW_NAME_LEN];
- strcpy(name, instData->m_decoratedNameString.str());
- Int len = strlen( name );
- char numberBuffer[ MAX_WINDOW_NAME_LEN ];
- Int i, j;
- char c;
- Bool hasNumberSuffix = FALSE;
- Int numberStartIndex = 0;
- // trivial case, just append a number to the end and get outta here
- if( len == 0 )
- {
-
- strcat( name, "1" );
- goto cleanup;
- } // end if
- //
- // start from the end of the string and back up to the start picking
- // off each character, checking if it's a number, and adding that number
- // to a string buffer. After all numbers are read from the name
- // the string is turned real number, incremented, and replaces the
- // existing number string
- //
- for( i = 0; i < MAX_WINDOW_NAME_LEN; i++ )
- numberBuffer[ i ] = ' ';
- numberBuffer[ MAX_WINDOW_NAME_LEN - 1 ] = '\0';
- for( i = len - 1, j = MAX_WINDOW_NAME_LEN - 2; i >= 0; i-- )
- {
- c = name[ i ];
- if( isdigit( c ) )
- {
- hasNumberSuffix = TRUE;
- numberBuffer[ j-- ] = c;
- } // end if
- else
- {
-
- numberStartIndex = i + 1;
- break; // exit for i
- } // end else
- } // end for i
- //
- // if we have a number suffix change it to a number, increment it, and
- // paste it over the old number
- //
- if( hasNumberSuffix == TRUE )
- {
- Int number = atoi( numberBuffer );
- Int charsAdded;
- // increment the number
- number++;
- // turn number back into string
- itoa( number, numberBuffer, 10 );
- // put number string OVER the original number string in the name
- len = strlen( numberBuffer );
- charsAdded = 0;
- for( i = 0; i < len; i++ )
- {
- if( i + numberStartIndex <= MAX_WINDOW_NAME_LEN - 2 )
- {
- name[ i + numberStartIndex ] = numberBuffer[ i ];
- charsAdded++;
- } // end if
- }
- name[ numberStartIndex + charsAdded ] = 0; // terminate at end of new string
- } // end if
- else
- {
- // no number at end, easy ... just append a number '1'
- strcat( name, "1" );
- } // end else
- cleanup:
- instData->m_decoratedNameString = name;
- } // end incrementName
- //-------------------------------------------------------------------------------------------------
- /** Validate the names for all the windows and child windows in the copy
- * buffer that they are unique and don't collide with any windows in
- * the real system. This is in preparation for a paste of the copy
- * buffer into the real working layout */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::validateClipboardNames( GameWindow *root )
- {
- Bool nameOK = FALSE;
- WinInstanceData *instData;
- Int sanityLoop = 0;
- // end of recursion
- if( root == NULL )
- return;
- // get our inst data
- instData = root->winGetInstanceData();
- //
- // we will check our name against all names in the active layout AND
- // in the clipboard, if it's a dupe we will pick a new name and
- // try it over and over until it's OK
- //
- while( nameOK == FALSE )
- {
- // if we're not a dupe with anything anywhere we're ok
- if( !TheEditor->isNameDuplicate( m_windowList, root, instData->m_decoratedNameString ) &&
- !TheEditor->isNameDuplicate( m_clipboardDup, root, instData->m_decoratedNameString ) )
- nameOK = TRUE;
- else
- incrementName( root ); // have to change our name, so sorry :(
- //
- // and just because I don't want the possibility of a infinite loop
- // EVER to occur here this is just a sanity check that will probably
- // never get run
- //
- if( ++sanityLoop > 99999999 )
- {
- char buffer[ 1024 ];
- sprintf( buffer, "Unable to make unique name for '%s', please manually edit the name before saving.",
- instData->m_decoratedNameString.str() );
- MessageBox( TheEditor->getWindowHandle(), buffer, "Error Mapping Names", MB_OK );
- nameOK = TRUE;
- } // end if
- } // end if
- // validate our children names
- GameWindow *child;
- for( child = root->winGetChild(); child; child = child->winGetNext() )
- validateClipboardNames( child );
- // validate the next window in the list
- validateClipboardNames( root->winGetNext() );
- } // end validateClipboardNames
- //-------------------------------------------------------------------------------------------------
- /** Paste the contents of the clipboard into the window world */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::pasteClipboard( void )
- {
- GameWindow *window, *next;
- GameWindow *firstWindow = NULL;
- // check for empty clipboard
- if( m_clipboard == NULL )
- {
- MessageBox( TheEditor->getWindowHandle(),
- "Cannot perform paste, the clipboard is empty.",
- "Clipboard Empty",
- MB_OK );
- return;
- } // end if
- // create a duplicate of everything in the clipboard
- assert( m_clipboardDup == NULL );
- createClipboardDuplicate();
- //
- // we are about to paste the contents of the clipboard dupe into the world,
- // scan through the clipboard dupe and adjust any names that will cause
- // collisions in the current layout
- //
- validateClipboardNames( m_clipboardDup );
- // keep a pointer to the first window we will add
- firstWindow = m_clipboardDup;
- // move everything from the duplicate list into the real world
- for( window = m_clipboardDup; window; window = next )
- {
- // get next window
- next = window->winGetNext();
- // remove from clipboard
- unlinkFromClipboard( window, &m_clipboardDup );
- // place in real layout
- linkWindow( window );
- //
- // since we just pasted in a new window, offset it a little bit
- // from the original location based on how many times we're pasted
- // this set of copies. This way they won't all stack on top of
- // each other
- //
- ICoord2D pos, safePos;
- window->winGetPosition( &pos.x, &pos.y );
- pos.x += m_copySpacing * (m_numCopiesPasted + 1);
- pos.y += m_copySpacing * (m_numCopiesPasted + 1);
- // kee the location legal
- TheEditor->computeSafeLocation( window, pos.x, pos.y,
- &safePos.x, &safePos.y );
- // set the new location
- TheEditor->moveWindowTo( window, safePos.x, safePos.y );
- // notify the hierarchy of the new window added
- TheHierarchyView->addWindow( window, HIERARCHY_ADD_AT_TOP );
- } // end for window
- // the clipboard duplicate list is only for the act of pasting
- assert( m_clipboardDup == NULL );
- // we've now completed another successful copy pasted in
- m_numCopiesPasted++;
- //
- // now that all windows were added to the layout, and we have
- // the first window that we added ... since we know they were added
- // at the head of the window list we can traverse from the first
- // window added to the head of the window list to access each new
- // window we just pasted. As a convenience we will unselct anything
- // selected and select all the windows we added
- //
- TheEditor->clearSelections();
- window = firstWindow;
- while( window )
- {
- TheEditor->selectWindow( window );
- window = window->winGetPrev();
- // notify the editor that each of the windows was created
- TheEditor->notifyNewWindow( window );
- } // end while
- // if we did in fact paste a window then our file contents have changed
- if( firstWindow )
- TheEditor->setUnsaved( TRUE );
- } // end pasteClipboard
- //-------------------------------------------------------------------------------------------------
- /** Convinience funtion to copy the Draw state info for a given instance */
- //-------------------------------------------------------------------------------------------------
- void InstDrawCopy ( WinInstanceData *instData, WinInstanceData *sourceInstData)
- {
- // do the copy of the colors for each state
- memcpy( &instData->m_enabledDrawData,
- &sourceInstData->m_enabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_disabledDrawData,
- &sourceInstData->m_disabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_hiliteDrawData,
- &sourceInstData->m_hiliteDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- }
- //-------------------------------------------------------------------------------------------------
- /** Duplciate a window and all its children */
- //-------------------------------------------------------------------------------------------------
- GameWindow *GUIEditWindowManager::duplicateWindow( GameWindow *source,
- GameWindow *parent )
- {
- GameWindow *duplicate = NULL;
- UnsignedInt style, status;
- WinInstanceData *instData;
- WinInstanceData instDataCopy;
- ICoord2D pos, size;
- // sanity
- if( source == NULL )
- return NULL;
- // get the window instance data and make a copy of it for creating new stuff
- instData = source->winGetInstanceData();
- instDataCopy = *instData;
- // memcpy( &instDataCopy, instData, sizeof( instDataCopy ) );
- //
- // do NOT copy the display string instances, these MUST be allocated when
- // needed in real windows
- //
- instDataCopy.m_text = NULL;
- instDataCopy.m_tooltip = NULL;
- // get a few properties we're going to need
- style = source->winGetStyle();
- status = source->winGetStatus();
- source->winGetPosition( &pos.x, &pos.y );
- source->winGetSize( &size.x, &size.y );
- // create a new window or gadget of the appropriate type
- if( BitTest( style, GWS_PUSH_BUTTON ) )
- {
- duplicate =
- TheWindowManager->gogoGadgetPushButton( parent,
- status,
- pos.x,
- pos.y,
- size.x,
- size.y,
- &instDataCopy,
- source->winGetFont(),
- FALSE );
- } // end if
- else if( BitTest( style, GWS_RADIO_BUTTON ) )
- {
- RadioButtonData *radioData = (RadioButtonData *)source->winGetUserData();
- RadioButtonData radioDataCopy;
- radioDataCopy = *radioData;
- // memcpy( &radioDataCopy, radioData, sizeof( RadioButtonData ) );
- duplicate =
- TheWindowManager->gogoGadgetRadioButton( parent,
- status,
- pos.x,
- pos.y,
- size.x,
- size.y,
- &instDataCopy,
- &radioDataCopy,
- source->winGetFont(),
- FALSE );
- } // end else if
- else if( BitTest( style, GWS_CHECK_BOX ) )
- {
- duplicate =
- TheWindowManager->gogoGadgetCheckbox( parent,
- status,
- pos.x,
- pos.y,
- size.x,
- size.y,
- &instDataCopy,
- source->winGetFont(),
- FALSE );
- } // end else if
- else if( BitTest( style, GWS_HORZ_SLIDER | GWS_VERT_SLIDER ) )
- {
- SliderData *sliderData = (SliderData *)source->winGetUserData();
- SliderData sliderDataCopy;
- sliderDataCopy = *sliderData;
- // memcpy( &sliderDataCopy, sliderData, sizeof( SliderData ) );
- duplicate = TheWindowManager->gogoGadgetSlider( parent,
- status,
- pos.x,
- pos.y,
- size.x,
- size.y,
- &instDataCopy,
- &sliderDataCopy,
- source->winGetFont(),
- FALSE );
- //
- // copy the color and image schemes of the sub controls that make
- // up a slider
- //
- if( duplicate )
- {
- WinInstanceData *instData;
- WinInstanceData *sourceInstData;
- // do the slider thumb
- GameWindow *thumb = GadgetSliderGetThumb( duplicate );
- GameWindow *sourceThumb = GadgetSliderGetThumb( source );
- if( thumb && sourceThumb )
- {
- instData = thumb->winGetInstanceData();
- sourceInstData = sourceThumb->winGetInstanceData();
-
- // do the copy of the colors for each state
- memcpy( &instData->m_enabledDrawData,
- &sourceInstData->m_enabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_disabledDrawData,
- &sourceInstData->m_disabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_hiliteDrawData,
- &sourceInstData->m_hiliteDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- } // end if
- } // end if
- } // end else if
- else if( BitTest( style, GWS_COMBO_BOX ) )
- {
- ComboBoxData *comboData = (ComboBoxData *)source->winGetUserData();
- ComboBoxData comboDataCopy;
- memset( &comboDataCopy, 0, sizeof( ComboBoxData ) );
-
- comboDataCopy.entryData = new EntryData;
- memset ( comboDataCopy.entryData, 0, sizeof(EntryData));
- comboDataCopy.listboxData = new ListboxData;
- memset ( comboDataCopy.listboxData, 0, sizeof(ListboxData));
-
-
- comboDataCopy.entryCount = comboData->entryCount;
- comboDataCopy.isEditable = comboData->isEditable;
- comboDataCopy.maxChars = comboData->maxChars;
- comboDataCopy.maxDisplay = comboData->maxDisplay;
- comboDataCopy.lettersAndNumbersOnly = comboData->lettersAndNumbersOnly;
- comboDataCopy.asciiOnly = comboData->asciiOnly;
- comboDataCopy.listboxData->autoPurge = comboData->listboxData->autoPurge;
- comboDataCopy.listboxData->autoScroll = comboData->listboxData->autoScroll;
- comboDataCopy.listboxData->scrollIfAtEnd = comboData->listboxData->scrollIfAtEnd;
- comboDataCopy.listboxData->forceSelect = comboData->listboxData->forceSelect;
- comboDataCopy.listboxData->listLength = comboData->listboxData->listLength;
- comboDataCopy.listboxData->multiSelect = comboData->listboxData->multiSelect;
- comboDataCopy.listboxData->scrollBar = comboData->listboxData->scrollBar;
- comboDataCopy.listboxData->columns = comboData->listboxData->columns;
- comboDataCopy.listboxData->columnWidth = comboData->listboxData->columnWidth;
- comboDataCopy.listboxData->columnWidthPercentage = comboData->listboxData->columnWidthPercentage;
- comboDataCopy.entryData->alphaNumericalOnly = comboData->entryData->alphaNumericalOnly;
- comboDataCopy.entryData->aSCIIOnly = comboData->entryData->aSCIIOnly;
- comboDataCopy.entryData->maxTextLen = comboData->entryData->maxTextLen;
- comboDataCopy.entryData->numericalOnly = comboData->entryData->numericalOnly;
-
-
- duplicate =
- TheWindowManager->gogoGadgetComboBox( parent,
- status,
- pos.x,
- pos.y,
- size.x,
- size.y,
- &instDataCopy,
- &comboDataCopy,
- source->winGetFont(),
- FALSE );
- //
- // copy the color and image schemes of the sub controls that make
- // up a listbox
- //
- if( duplicate )
- {
- ComboBoxData *comboData = (ComboBoxData *)duplicate->winGetUserData();
- ComboBoxData *sourceComboData = (ComboBoxData *)source->winGetUserData();
- WinInstanceData *instData;
- WinInstanceData *sourceInstData;
-
- // drop down button
- GameWindow *dropDownButton = comboData->dropDownButton;
- GameWindow *sourceDropDownButton = sourceComboData->dropDownButton;
- if(dropDownButton && sourceDropDownButton)
- {
- instData = dropDownButton->winGetInstanceData();
- sourceInstData = sourceDropDownButton->winGetInstanceData();
- InstDrawCopy(instData,sourceInstData);
- }
- // edit box
- GameWindow *editBox = comboData->editBox;
- GameWindow *sourceEditBox = sourceComboData->editBox;
- if(editBox && sourceEditBox)
- {
- instData = editBox->winGetInstanceData();
- sourceInstData = sourceEditBox->winGetInstanceData();
- InstDrawCopy(instData,sourceInstData);
- }
-
- // ListBox
- GameWindow *listBox = comboData->listBox;
- GameWindow *sourceListBox = sourceComboData->listBox;
- if(listBox && sourceListBox)
- {
- instData = listBox->winGetInstanceData();
- sourceInstData = sourceListBox->winGetInstanceData();
- InstDrawCopy(instData,sourceInstData);
-
- // up button
- GameWindow *upButton = comboData->listboxData->upButton;
- GameWindow *sourceUpButton = sourceComboData->listboxData->upButton;
- if( upButton && sourceUpButton )
- {
-
- instData = upButton->winGetInstanceData();
- sourceInstData = sourceUpButton->winGetInstanceData();
-
- // do the copy of the colors for each state
- memcpy( &instData->m_enabledDrawData,
- &sourceInstData->m_enabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_disabledDrawData,
- &sourceInstData->m_disabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_hiliteDrawData,
- &sourceInstData->m_hiliteDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- } // if
- // down button
- GameWindow *downButton = comboData->listboxData->downButton;
- GameWindow *sourceDownButton = sourceComboData->listboxData->downButton;
- if( downButton && sourceDownButton )
- {
-
- instData = downButton->winGetInstanceData();
- sourceInstData = sourceDownButton->winGetInstanceData();
-
- // do the copy of the colors for each state
- memcpy( &instData->m_enabledDrawData,
- &sourceInstData->m_enabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_disabledDrawData,
- &sourceInstData->m_disabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_hiliteDrawData,
- &sourceInstData->m_hiliteDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- } // if
- // slider
- GameWindow *slider = comboData->listboxData->slider;
- GameWindow *sourceSlider = sourceComboData->listboxData->slider;
- if( slider && sourceSlider )
- {
-
- instData = slider->winGetInstanceData();
- sourceInstData = sourceSlider->winGetInstanceData();
-
- // do the copy of the colors for each state
- memcpy( &instData->m_enabledDrawData,
- &sourceInstData->m_enabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_disabledDrawData,
- &sourceInstData->m_disabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_hiliteDrawData,
- &sourceInstData->m_hiliteDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- // do the slider thumb
- GameWindow *thumb = GadgetSliderGetThumb( slider );
- GameWindow *sourceThumb = GadgetSliderGetThumb( sourceSlider );
- if( thumb && sourceThumb )
- {
- instData = thumb->winGetInstanceData();
- sourceInstData = sourceThumb->winGetInstanceData();
-
- // do the copy of the colors for each state
- memcpy( &instData->m_enabledDrawData,
- &sourceInstData->m_enabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_disabledDrawData,
- &sourceInstData->m_disabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_hiliteDrawData,
- &sourceInstData->m_hiliteDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- } // end if
- } // if
- } // if
- } // end if
- } // end else if
- else if( BitTest( style, GWS_SCROLL_LISTBOX ) )
- {
- ListboxData *listData = (ListboxData *)source->winGetUserData();
- ListboxData listDataCopy;
- memset( &listDataCopy, 0, sizeof( listDataCopy ) );
- listDataCopy.autoPurge = listData->autoPurge;
- listDataCopy.autoScroll = listData->autoScroll;
- listDataCopy.scrollIfAtEnd = listData->scrollIfAtEnd;
- listDataCopy.forceSelect = listData->forceSelect;
- listDataCopy.listLength = listData->listLength;
- listDataCopy.multiSelect = listData->multiSelect;
- listDataCopy.scrollBar = listData->scrollBar;
- listDataCopy.columns = listData->columns;
- if(listData->columnWidth)
- {
- listDataCopy.columnWidth = new Int[listData->columns];
- for(Int i = 0; i < listData->columns; i ++)
- {
- listDataCopy.columnWidth[i] = listData->columnWidth[i];
- }
- }
- else
- listDataCopy.columnWidth = NULL;
- if(listData->columnWidthPercentage)
- {
- listDataCopy.columnWidthPercentage = new Int[listData->columns];
- for(Int i = 0; i < listData->columns; i ++)
- {
- listDataCopy.columnWidthPercentage[i] = listData->columnWidthPercentage[i];
- }
- }
- else
- listDataCopy.columnWidthPercentage = NULL;
- duplicate =
- TheWindowManager->gogoGadgetListBox( parent,
- status,
- pos.x,
- pos.y,
- size.x,
- size.y,
- &instDataCopy,
- &listDataCopy,
- source->winGetFont(),
- FALSE );
- //
- // copy the color and image schemes of the sub controls that make
- // up a listbox
- //
- if( duplicate )
- {
- ListboxData *listData = (ListboxData *)duplicate->winGetUserData();
- ListboxData *sourceListData = (ListboxData *)source->winGetUserData();
- WinInstanceData *instData;
- WinInstanceData *sourceInstData;
- // up button
- GameWindow *upButton = listData->upButton;
- GameWindow *sourceUpButton = sourceListData->upButton;
- if( upButton && sourceUpButton )
- {
-
- instData = upButton->winGetInstanceData();
- sourceInstData = sourceUpButton->winGetInstanceData();
-
- // do the copy of the colors for each state
- memcpy( &instData->m_enabledDrawData,
- &sourceInstData->m_enabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_disabledDrawData,
- &sourceInstData->m_disabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_hiliteDrawData,
- &sourceInstData->m_hiliteDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- } // if
- // down button
- GameWindow *downButton = listData->downButton;
- GameWindow *sourceDownButton = sourceListData->downButton;
- if( downButton && sourceDownButton )
- {
-
- instData = downButton->winGetInstanceData();
- sourceInstData = sourceDownButton->winGetInstanceData();
-
- // do the copy of the colors for each state
- memcpy( &instData->m_enabledDrawData,
- &sourceInstData->m_enabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_disabledDrawData,
- &sourceInstData->m_disabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_hiliteDrawData,
- &sourceInstData->m_hiliteDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- } // if
- // slider
- GameWindow *slider = listData->slider;
- GameWindow *sourceSlider = sourceListData->slider;
- if( slider && sourceSlider )
- {
-
- instData = slider->winGetInstanceData();
- sourceInstData = sourceSlider->winGetInstanceData();
-
- // do the copy of the colors for each state
- memcpy( &instData->m_enabledDrawData,
- &sourceInstData->m_enabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_disabledDrawData,
- &sourceInstData->m_disabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_hiliteDrawData,
- &sourceInstData->m_hiliteDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- // do the slider thumb
- GameWindow *thumb = GadgetSliderGetThumb( slider );
- GameWindow *sourceThumb = GadgetSliderGetThumb( sourceSlider );
- if( thumb && sourceThumb )
- {
- instData = thumb->winGetInstanceData();
- sourceInstData = sourceThumb->winGetInstanceData();
-
- // do the copy of the colors for each state
- memcpy( &instData->m_enabledDrawData,
- &sourceInstData->m_enabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_disabledDrawData,
- &sourceInstData->m_disabledDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- memcpy( &instData->m_hiliteDrawData,
- &sourceInstData->m_hiliteDrawData,
- sizeof( WinDrawData ) * MAX_DRAW_DATA );
- } // end if
- } // if
- } // end if
- } // end else if
- else if( BitTest( style, GWS_ENTRY_FIELD ) )
- {
- EntryData *entryData = (EntryData *)source->winGetUserData();
- EntryData entryDataCopy;
- memset( &entryDataCopy, 0, sizeof( entryDataCopy ) );
- entryDataCopy.alphaNumericalOnly = entryData->alphaNumericalOnly;
- entryDataCopy.aSCIIOnly = entryData->aSCIIOnly;
- entryDataCopy.maxTextLen = entryData->maxTextLen;
- entryDataCopy.numericalOnly = entryData->numericalOnly;
- entryDataCopy.secretText = entryData->secretText;
- duplicate =
- TheWindowManager->gogoGadgetTextEntry( parent,
- status,
- pos.x,
- pos.y,
- size.x,
- size.y,
- &instDataCopy,
- &entryDataCopy,
- source->winGetFont(),
- FALSE );
- } // end else if
- else if( BitTest( style, GWS_STATIC_TEXT ) )
- {
- TextData *textData = (TextData *)source->winGetUserData();
- TextData textDataCopy;
- textDataCopy.centered = textData->centered;
- duplicate =
- TheWindowManager->gogoGadgetStaticText( parent,
- status,
- pos.x,
- pos.y,
- size.x,
- size.y,
- &instDataCopy,
- &textDataCopy,
- source->winGetFont(),
- FALSE );
- } // end else if
- else if( BitTest( style, GWS_PROGRESS_BAR ) )
- {
-
- duplicate =
- TheWindowManager->gogoGadgetProgressBar( parent,
- status,
- pos.x,
- pos.y,
- size.x,
- size.y,
- &instDataCopy,
- source->winGetFont(),
- FALSE );
- } // end else if
- else if( BitTest( style, GWS_USER_WINDOW ) )
- {
- // create plain ol generic window
- duplicate = TheWindowManager->winCreate( parent,
- status,
- pos.x,
- pos.y,
- size.x,
- size.y,
- NULL,
- &instDataCopy );
- } // end else if
- else
- {
- MessageBox( TheEditor->getWindowHandle(),
- "Cannot duplicate window, undefined style.",
- "Internal Error", MB_OK );
- assert( 0 );
- memset( &instDataCopy, 0, sizeof( instDataCopy ) ); // see comment below
- return NULL;
- } // end else
- // sanity
- if( duplicate == NULL )
- {
- MessageBox( TheEditor->getWindowHandle(), "Unable to duplicate window",
- "Internal Error", MB_OK );
- assert( 0 );
- memset( &instDataCopy, 0, sizeof( instDataCopy ) ); // see comment below
- return NULL;
- } // end if
- //
- // since we're using the real window system here to create things, we
- // want to immediately remove it from the real system list cause we're
- // not adding windows to the layout, only duplicating windows in
- // isolation. Note that child windows are linked to their parents
- // but that is totally isolated in the parent so that's OK and
- // necessary.
- //
- if( parent == NULL )
- unlinkWindow( duplicate );
- // copy edit data, only for the editor
- if( duplicate )
- {
- GameWindowEditData *editData = duplicate->winGetEditData();
- GameWindowEditData *sourceEditData = source->winGetEditData();
- // set edit data to zero or copy from source
- if( sourceEditData && editData )
- *editData = *sourceEditData;
- // memcpy( editData, sourceEditData, sizeof( GameWindowEditData ) );
- } // end if
- //
- // duplicate all the children for the window, except if this window
- // is a gadget, those windows may have children but all of that
- // is already taken care of in the creation above ... a gadget should
- // be considered a single atomic unit
- //
- if( TheEditor->windowIsGadget( duplicate ) == FALSE )
- {
- GameWindow *child;
- for( child = source->winGetChild(); child; child = child->winGetNext() )
- duplicateWindow( child, duplicate );
- } // end if
- //
- // the inst data copy was literally a copy, now it's going to go out of
- // scope and we DONT want any data to be freed that points back to the
- // original window e got it from. So therefore we'll just blow it away
- //
- memset( &instDataCopy, 0, sizeof( instDataCopy ) );
- // return the duped window
- return duplicate;
- } // end duplicateWindow
- //-------------------------------------------------------------------------------------------------
- /** Create a duplicate everything on the clipboard list and put it
- * on the m_clipboardDup list for pasting */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::createClipboardDuplicate( void )
- {
- GameWindow *duplicate;
- GameWindow *window;
- GameWindow *lastWindow;
- // find last window in clipboard
- lastWindow = m_clipboard;
- while( lastWindow && lastWindow->winGetNext() != NULL )
- lastWindow = lastWindow->winGetNext();
- //
- // go through each window in the clipboard, note we're starting from
- // the bottom and going to the front to preserve the same order
- // as the clipboard
- //
- for( window = lastWindow; window; window = window->winGetPrev() )
- {
- // duplicate the window and all its children
- duplicate = duplicateWindow( window, NULL );
- // add duplicate to list
- if( duplicate )
- linkToClipboard( duplicate, &m_clipboardDup );
- } // end for
- } // end createClipboardDuplicate
- //-------------------------------------------------------------------------------------------------
- /** Make the 'target' a child of the 'parent' */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::makeChildOf( GameWindow *target,
- GameWindow *parent )
- {
- // sanity
- if( target == NULL )
- return;
- // get target parent
- GameWindow *prevParent = target->winGetParent();
- // check for no parent
- if( parent == NULL )
- {
- // if target already has no parent nothing to do
- if( prevParent == NULL )
- return;
- //
- // we are removing a parent from the target and placing target
- // at the top of the window list. Be sure to preserve the
- // screen position as the new coords so it's in the same place
- //
- ICoord2D screenPos;
- target->winGetScreenPosition( &screenPos.x, &screenPos.y );
- unlinkChildWindow( target );
- linkWindow( target );
- target->winSetPosition( screenPos.x, screenPos.y );
- return;
- } // end if
- // check to see if this is already out parent, nothing to do
- if( prevParent == parent )
- return;
- // you cannot make a window a child of a gadget control
- if( TheEditor->windowIsGadget( parent ) )
- {
- MessageBox( TheEditor->getWindowHandle(),
- "You cannot give a gadget control a child.",
- "Child Not Allowed",
- MB_OK );
- return;
- } // end if
- // get the target screen position before the move to child
- ICoord2D screenPosBeforeMove;
- target->winGetScreenPosition( &screenPosBeforeMove.x,
- &screenPosBeforeMove.y );
- // remove the target from the window or any child list
- if( prevParent )
- unlinkChildWindow( target );
- else
- unlinkWindow( target );
- // add as child of 'parent'
- addWindowToParent( target, parent );
- // adjust the position so it's relative to the new parent
- ICoord2D parentPos;
- parent->winGetScreenPosition( &parentPos.x, &parentPos.y );
- target->winSetPosition( screenPosBeforeMove.x - parentPos.x,
- screenPosBeforeMove.y - parentPos.y );
- // notify the hierarchy of the change
- TheHierarchyView->moveWindowChildOf( target, parent );
- //
- // run through the move code to keep the child in a legal position
- // inside the parent client area
- //
- ICoord2D origin, safeLoc;
- target->winGetScreenPosition( &origin.x, &origin.y );
- // kee the location legal
- TheEditor->computeSafeLocation( target, origin.x, origin.y,
- &safeLoc.x, &safeLoc.y );
-
- // move the target
- TheEditor->moveWindowTo( target, safeLoc.x, safeLoc.y );
-
- } // end makeChildOf
- //-------------------------------------------------------------------------------------------------
- /** Move the 'windowToMove' to be just in front of the 'aheadOf' window
- * in either the master window list or in the child list */
- //-------------------------------------------------------------------------------------------------
- void GUIEditWindowManager::moveAheadOf( GameWindow *windowToMove,
- GameWindow *aheadOf )
- {
- // sanity
- if( windowToMove == NULL || aheadOf == NULL || windowToMove == aheadOf )
- return;
- //
- // get our screen position before the move ... we want to appear in the
- // same place after we're moved
- //
- ICoord2D beforeMoveScreenPos;
- windowToMove->winGetScreenPosition( &beforeMoveScreenPos.x,
- &beforeMoveScreenPos.y );
- // get the parent of that which we are moving
- GameWindow *prevParent = windowToMove->winGetParent();
- // take the window to move off the chain
- if( prevParent )
- {
- ICoord2D pos;
- // get he screen position of the window BEFORE we unlink it
- windowToMove->winGetScreenPosition( &pos.x, &pos.y );
- // take off the child list, this will remove our parent pointer as well
- unlinkChildWindow( windowToMove );
- //
- // now that we're unlinked, set the position to be accurate with
- // the screen position and no parent
- //
- windowToMove->winSetPosition( pos.x, pos.y );
- } // end if
- else
- {
- // just take off the main list
- unlinkWindow( windowToMove );
-
- } // end else
- // insert the window at the specified location
- insertWindowAheadOf( windowToMove, aheadOf );
- //
- // adjust our position to be in the same place in our new location
- // in the chain ... if we gained a parent we have to offset by
- // the difference between our parent screen and our screen positions.
- // if we lost a parent our position must be set to the absolute
- // screen position
- //
- GameWindow *newParent = windowToMove->winGetParent();
- ICoord2D parentPos = { 0 }; // init to top left of screen
- if( newParent )
- newParent->winGetScreenPosition( &parentPos.x, &parentPos.y );
- windowToMove->winSetPosition( beforeMoveScreenPos.x - parentPos.x,
- beforeMoveScreenPos.y - parentPos.y );
- // move the window hierarchy representation of this window
- TheHierarchyView->moveWindowAheadOf( windowToMove, aheadOf );
- //
- // run through the move code to keep the child in a legal position
- // inside the parent client area
- //
- ICoord2D origin, safeLoc;
- windowToMove->winGetScreenPosition( &origin.x, &origin.y );
- // kee the location legal
- TheEditor->computeSafeLocation( windowToMove, origin.x, origin.y,
- &safeLoc.x, &safeLoc.y );
-
- // move the target
- TheEditor->moveWindowTo( windowToMove, safeLoc.x, safeLoc.y );
- } // end moveAheadOf
|