/* * pspawsmanger.cpp - Author: Andrew Craig * * Copyright (C) 2003 Atomic Blue (info@planeshift.it, http://www.atomicblue.org) * * * 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 (version 2 of the License) * 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-1307, USA. * */ // PawsManager.cpp: implementation of the PawsManager class. // ////////////////////////////////////////////////////////////////////// #include //////////////////////////////////////////////////////////////////////////// // CS INCLUDES //////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include //////////////////////////////////////////////////////////////////////////// // COMMON INCLUDES //////////////////////////////////////////////////////////////////////////// #include "util/log.h" #include "util/localization.h" #include "util/psxmlparser.h" //////////////////////////////////////////////////////////////////////////// // PAWS INCLUDES //////////////////////////////////////////////////////////////////////////// #include "pawsmanager.h" #include "pawswidget.h" #include "pawsbutton.h" #include "pawscrollbar.h" #include "pawsmainwidget.h" #include "pawstextbox.h" #include "pawstextwrap.h" #include "pawskeyselectbox.h" #include "pawstexturemanager.h" #include "pawsmouse.h" //#include "pawsinfowindow.h" #include "pawsprefmanager.h" #include "pawsobjectview.h" #include "pawsgenericview.h" #include "pawstree.h" #include "pawsprogressbar.h" #include "pawsmenu.h" #include "pawsfilenavigation.h" ////////////////////////////////////////////////////////////////////// // PAWS WIDGET FACTORIES ////////////////////////////////////////////////////////////////////// #include "pawslistbox.h" #include "pawsradio.h" #include "pawsokbox.h" #include "pawscombo.h" #include "pawsselector.h" #include "pawsyesnobox.h" #include "pawscheckbox.h" #include "pawstabwindow.h" #include "pawsspinbox.h" #define TEMP_SKIN_MOUNT "/paws/temp_skin" #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// PawsManager::PawsManager(iObjectRegistry* object, const char* skin,const char* pawsConfigFile) { objectReg = object; pawsConfig = pawsConfigFile; graphics2D = CS_QUERY_REGISTRY( objectReg ,iGraphics2D ); graphics3D = CS_QUERY_REGISTRY( objectReg ,iGraphics3D ); soundloader = CS_QUERY_REGISTRY( objectReg, iSndSysLoader ); soundrenderer = CS_QUERY_REGISTRY( objectReg, iSndSysRenderer ); nameRegistry = csEventNameRegistry::GetRegistry (objectReg); // Initialize event shortcuts MouseMove = csevMouseMove (nameRegistry, 0); MouseDown = csevMouseDown (nameRegistry, 0); MouseDoubleClick = csevMouseDoubleClick (nameRegistry, 0); MouseUp = csevMouseUp (nameRegistry, 0); KeyboardDown = csevKeyboardDown (objectReg); KeyboardUp = csevKeyboardUp (objectReg); vfs = CS_QUERY_REGISTRY( objectReg, iVFS ); xml = csPtr(new csTinyDocumentSystem); csRef cfg = CS_QUERY_REGISTRY(objectReg, iConfigManager); float screenWidth = cfg->GetFloat( "Video.ScreenWidth", 800.0f ); float screenHeight = cfg->GetFloat( "Video.ScreenHeight", 600.0f ); fontFactor = min( ( screenWidth / 800.0f ) , ( screenHeight / 600.0f ) ); fontFactor *= (float)cfg->GetInt( "Font.ScalePercent", 100 ) / 100.0f; RegisterFactories(); mainWidget = new pawsMainWidget(); textureManager = new pawsTextureManager( objectReg ); prefs = new pawsPrefManager(); csString prefsFile = cfg->GetStr("Planeshift.GUI.PrefsFile", "/this/data/prefs.xml"); csString borderFile = cfg->GetStr("Planeshift.GUI.BorderFile", "/this/data/gui/borderlist.xml"); styles = new pawsStyles( objectReg ); if (!styles->LoadStyles("/this/data/gui/styles.xml")) { Error1("Failed to load PAWS styles, all style application attempts will be ignored"); delete styles; styles = NULL; } if(!LoadAdditionalSkin(skin)) Error1("Failed to load base skin!"); if ( !prefs->LoadPrefFile( prefsFile ) ) Error2("Failed to load prefsFile '%s'", prefsFile.GetData()); if ( !prefs->LoadBorderFile( borderFile ) ) Error2("Failed to load borderFile '%s'", borderFile.GetData()); mouse = new pawsMouse(); mouse->ChangeImage("Standard Mouse Pointer"); resizeImg = new pawsImage( objectReg ); resizeImg->Description( textureManager->GetImageDescription("ResizeBox") ); graphics2D->SetMouseCursor( csmcNone ); currentFocusedWidget = mainWidget; movingWidget = 0; focusOverridesControls = false; resizingWidget = 0; resizingFlags = 0; modalWidget = 0; mouseoverWidget = 0; lastfadeWidget = 0; assert(cfg); csString lang = cfg->GetStr("Planeshift.GUI.Language", ""); localization = new psLocalization(); localization->Initialize(objectReg); localization->SetLanguage(lang); tipDelay = cfg->GetInt("Planeshift.GUI.ToolTipDelay", 250); hadKeyDown = false; dragDropWidget = NULL; useSounds = true; volume = 1.0; timeOver = 0; } PawsManager::~PawsManager() { // Empty the sounds hash and remove our references to the sounds within ReleaseAllSounds(); delete mainWidget; delete textureManager; delete prefs; delete localization; delete mouse; delete resizeImg; delete styles; if (dragDropWidget != NULL) delete dragDropWidget; // Free all subscriptions PAWSSubscriptionsHash::GlobalIterator iter = subscriptions.GetIterator(); while (iter.HasNext()) { PAWSSubscription *p = iter.Next(); delete p; } subscriptions.DeleteAll(); factories.DeleteAll(); } void PawsManager::SetMainWidget(pawsMainWidget *widg) { if (mainWidget) delete mainWidget; mainWidget = widg; } pawsWidget* PawsManager::FindWidget( const char* widgetName, bool complain ) { return mainWidget->FindWidget( widgetName, complain ); } void PawsManager::MovingWidget( pawsWidget* widget ) { if ( modalWidget == NULL ) { movingWidget = widget; } } void PawsManager::ResizingWidget( pawsWidget* widget, int flags ) { if ( modalWidget == NULL ) { resizingWidget = widget; resizingFlags = flags; } } bool PawsManager::HandleEvent( iEvent &event ) { if (event.Name == MouseMove) return HandleMouseMove (event); if (event.Name == MouseDown) return HandleMouseDown (event); if (event.Name == MouseDoubleClick) return HandleDoubleClick (event); if (event.Name == MouseUp) return HandleMouseUp (event); if (event.Name == KeyboardDown || event.Name == KeyboardUp) return HandleKeyDown( event ); return false; } bool PawsManager::HandleDoubleClick( iEvent& ev ) { pawsWidget* widget = NULL; psPoint event = MouseLocation(ev); int button; int modifiers; ev.Retrieve( "mButton", button ); ev.Retrieve( "keyModifiers", modifiers ); widget = mainWidget->WidgetAt( event.x, event.y ); if ( widget != NULL ) { if ( modalWidget != NULL ) { // Check to see if the widget is a child of the modal widget. // These are the only components allowed access durning modal // mode pawsWidget* check = modalWidget->FindWidget( widget->GetName(), false ); if ( check != widget ) { widget = modalWidget->WidgetAt( event.x, event.y ); } } if ( widget != NULL ) { bool returnResult; SetCurrentFocusedWidget( widget ); if ( widget != mainWidget ) { widget->GetParent()->BringToTop( widget ); } returnResult = widget->OnDoubleClick( button, modifiers, event.x, event.y ); return returnResult; } return false; } return false; } bool PawsManager::LoadAdditionalSkin(const char* zip) { //Mount the skin printf("Mounting skin: %s\n", zip); csRef realPath = vfs->GetRealPath(zip); if (!realPath.IsValid()) { Error2( "Could not mount skin %s. GetRealPath() failed.",zip); return false; } if ( !vfs->Mount(TEMP_SKIN_MOUNT, realPath->GetData() ) ) { Error2( "Could not mount skin %s!",zip); return false; } csRef xml = ParseFile(objectReg,TEMP_SKIN_MOUNT "/skin.xml"); if(!xml) { Error2( "Could not read skin info on %s!",zip); return false; } // Get the mount path csRef root = xml->GetRoot(); if (!root) { Error2( "Could not read skin info on %s!",zip); return false; } root = root->GetNode("xml"); if(!root) { Error2( "Could not read skin info on %s!",zip); return false; } csRef mount = root->GetNode("mount_path"); if ( !mount ) { Error1("There was no mount_path found in the skin.xml file. Please check the node to make sure mount_path is defined"); return false; } csString mountPlace = mount->GetContentsValue(); mountPlace.ReplaceAll("\\","/"); // Unmount the temp location and remount real vfs->Unmount(TEMP_SKIN_MOUNT,realPath->GetData()); // See if there is another skin with that mount path csRef mounts = vfs->GetMounts(); for(size_t i = 0; i < mounts->Length();i++) { csString mount = mounts->Get(i); if(mount == mountPlace || mount == mountPlace + "/") { Error3("The mount place (%s) for skin '%s' is already taken!",mountPlace.GetData(),zip); return false; } } // mount vfs->Mount(mountPlace,realPath->GetData()); // Load additional resources csString imageFile = mountPlace + "/imagelist.xml"; textureManager->LoadImageList(imageFile); return true; } bool PawsManager::HandleKeyDown( iEvent& event ) { if ( currentFocusedWidget ) { if ( (csKeyEventHelper::GetEventType (&event) == csKeyEventTypeUp) ) { if ( hadKeyDown ) return true; } int raw = csKeyEventHelper::GetRawCode(&event); int cooked = csKeyEventHelper::GetCookedCode(&event); uint32 modifiers = csKeyEventHelper::GetModifiersBits(&event); bool result = currentFocusedWidget->OnKeyDown( raw, cooked, modifiers ); hadKeyDown = result; return result; } return false; } bool PawsManager::HandleMouseDown( iEvent &ev ) { pawsWidget* widget = 0; psPoint event = MouseLocation(ev); int button; int modifiers; ev.Retrieve("mButton", button); ev.Retrieve("keyModifiers", modifiers); widget = mainWidget->WidgetAt(event.x, event.y); if ( widget != NULL ) { if ( modalWidget != NULL ) { // Check to see if the widget is a child of the modal widget. // These are the only components allowed access durning modal // mode pawsWidget* check = modalWidget->FindWidget( widget->GetName(), false ); if ( check != widget ) { widget = modalWidget->WidgetAt(event.x, event.y); } } if ( widget != NULL ) { SetCurrentFocusedWidget( widget ); if ( widget != mainWidget ) widget->GetParent()->BringToTop(widget); bool returnResult = widget->OnMouseDown( button, modifiers, event.x, event.y ); return returnResult; } return false; } return false; } bool PawsManager::HandleMouseUp( iEvent &ev ) { psPoint event = MouseLocation(ev); int button; int modifiers; ev.Retrieve("mButton", button); ev.Retrieve("keyModifiers", modifiers); // Check to see if we are moving a widget. if ( movingWidget ) { movingWidget = NULL; return true; } if ( resizingWidget ) { resizingWidget->StopResize(); resizingWidget = NULL; return true; } if ( currentFocusedWidget ) return currentFocusedWidget->OnMouseUp( button, modifiers, event.x, event.y ); pawsWidget* widget = mainWidget->WidgetAt(event.x, event.y ); SetCurrentFocusedWidget ( widget ); if ( widget ) { if ( widget != mainWidget ) widget->GetParent()->BringToTop( widget ); return widget->OnMouseUp( button, modifiers, event.x, event.y ); } return false; } psPoint PawsManager::MouseLocation( iEvent &ev ) { csMouseEventData event; const void *_ax = 0; size_t _ax_sz = 0; csEventError ok = csEventErrNone; ok = ev.Retrieve("mAxes", _ax, _ax_sz); CS_ASSERT(ok == csEventErrNone); ok = ev.Retrieve("mNumAxes", event.numAxes); CS_ASSERT(ok == csEventErrNone); for (int iter=0 ; iterSetPosition( event.x, event.y ); PositionDragDropWidget(); timeOver = csGetTicks(); if ( movingWidget ) { movingWidget->MoveDelta( mouse->GetDeltas().x, mouse->GetDeltas().y); return true; } if ( resizingWidget ) { resizingWidget->Resize( mouse->GetDeltas().x, mouse->GetDeltas().y, resizingFlags ); return true; } if (modalWidget == NULL) { pawsWidget* widget = mainWidget->WidgetAt(event.x, event.y); if ( widget ) { if ( widget && widget != mouseoverWidget ) { widget->OnMouseEnter(); if ( mouseoverWidget ) mouseoverWidget->OnMouseExit(); } mouseoverWidget = widget; pawsWidget* widgetFade = widget; // Only fade in/out topmost parent if (widgetFade != mainWidget) { for (pawsWidget* mainParent = widgetFade->GetParent();mainParent != mainWidget;mainParent=widgetFade->GetParent()) { widgetFade = mainParent; } } if (lastfadeWidget != widgetFade && widgetFade && widgetFade->IsVisible()) { if (lastfadeWidget && lastfadeWidget != mainWidget) { lastfadeWidget->MouseOver(false); } lastfadeWidget = widgetFade; if (widgetFade != mainWidget) widgetFade->MouseOver(true); // Fade in } } } return false; } void PawsManager::Draw() { mainWidget->DrawChildren(); if ( modalWidget != NULL ) modalWidget->Draw(); graphics2D->SetClipRect( 0,0, graphics2D->GetWidth(), graphics2D->GetHeight()); // Draw the tooltip above all other windows after 250 csTicks if (timeOver < csGetTicks() - tipDelay && mouseoverWidget) mouseoverWidget->DrawToolTip(mouse->GetPosition().x, mouse->GetPosition().y); if (dragDropWidget == NULL) mouse->Draw(); else dragDropWidget->Draw(); } void PawsManager::RegisterWidgetFactory( pawsWidgetFactory* fact ) { factories.Push( fact ); } csRef PawsManager::ParseWidgetFile( const char* widgetFile ) { csRef doc; const char* error; csRef buff = vfs->ReadFile(widgetFile); if (buff == NULL) { Error2("Could not find file: %s", widgetFile); return NULL; } doc=xml->CreateDocument(); error=doc->Parse(buff); if ( error ) { Error3("Parse error in %s: %s", widgetFile, error); return NULL; } csRef root; if((root=doc->GetRoot())) { csRef widgetNode = root->GetNode("widget_description"); if (!widgetNode) Error2("File %s has no tag", widgetFile); return widgetNode; } else { Error2("Bad XML document in %s", widgetFile); return NULL; } } bool PawsManager::LoadWidget( const char* widgetFile ) { csString fullPath = localization->FindLocalizedFile(widgetFile); csRef topNode = ParseWidgetFile( fullPath ); if (!topNode) { Error2("Error parsing xml in file: %s", fullPath.GetDataSafe() ); return false; } csRef iter = topNode->GetNodes(); while ( iter->HasNext() ) { csRef node = iter->Next(); if ( node->GetType() != CS_NODE_ELEMENT ) continue; // This is a widget so read it's factory to create it. if ( strcmp( node->GetValue(), "widget" ) == 0 ) { pawsWidget * widget = LoadWidget(node); if (widget) { widget->SetFilename(widgetFile); mainWidget->AddChild(widget); } else { Error2("Could not load child widget in file %s",fullPath.GetDataSafe()); return false; } } } return true; } bool PawsManager::LoadChildWidgets( const char* widgetFile, csArray &loadedWidgets ) { bool errors=false; loadedWidgets.DeleteAll(); csString fullPath = localization->FindLocalizedFile(widgetFile); csRef topNode = ParseWidgetFile( fullPath ); if (!topNode) return false; csRef iter = topNode->GetNodes(); while ( iter->HasNext() ) { csRef node = iter->Next(); if ( node->GetType() != CS_NODE_ELEMENT ) continue; // This is a widget so read it's factory to create it. if ( strcmp( node->GetValue(), "widget" ) == 0 ) { pawsWidget * widget = LoadWidget(node); if (widget) loadedWidgets.Push(widget); else errors = true; } } return (!errors); } pawsWidget * PawsManager::LoadWidget( csRef widgetNode ) { pawsWidget * widget; csString factory = widgetNode->GetAttributeValue( "factory" ); if ( factory.Length() == 0 ) { Error1("Could not read factory from XML file. Error in XML"); return NULL; } widget = CreateWidget( factory ); if ( !widget ) { Error2( "Failed to create widget %s", factory.GetData() ); return NULL; } if ( widget->Load( widgetNode ) == false ) { Error3("Widget %s failed to load %s", widget->GetName(), factory.GetData() ); delete widget; return NULL; } return widget; } pawsWidget* PawsManager::CreateWidget( const char* factoryName ) { csString factory( factoryName ); for ( size_t x = 0; x < factories.Length(); x++ ) { if ( factory == factories[x]->GetName() ) { pawsWidget * newWidget = factories[x]->Create(); newWidget->SetFactory( factoryName ); return newWidget; } } Error2("Could not locate Factory: %s", factoryName ); return NULL; } void PawsManager::SetModalWidget( pawsWidget* widget ) { if (widget != NULL) SetCurrentFocusedWidget( widget ); modalWidget = widget; } void PawsManager::SetCurrentFocusedWidget ( pawsWidget* widget ) { if ( widget == NULL ) { SetCurrentFocusedWidget( mainWidget ); return; } if ( modalWidget == NULL ) { if ( currentFocusedWidget != widget ) { // Check if widget CAN be focused, if it can't, pass it to the parent for (;!(widget->OnGainFocus()) && widget != mainWidget;widget = widget->GetParent()) if (widget == currentFocusedWidget) // Abort break; if (currentFocusedWidget) currentFocusedWidget->OnLostFocus(); } currentFocusedWidget = widget; } else { // Allow widget to be focused if it is a child of the modal widget pawsWidget* check = modalWidget->FindWidget( widget->GetName(), false ); if (check) if ( currentFocusedWidget != widget ) { // Check if widget CAN be focused, if it can't, pass it to the parent for (;!(widget->OnGainFocus()) && widget != mainWidget;widget = widget->GetParent()) if (widget == currentFocusedWidget) // Abort break; widget->OnGainFocus(); if (currentFocusedWidget) currentFocusedWidget->OnLostFocus(); } currentFocusedWidget = widget; } // If this is an edit text box, we need the full focus of the controls now focusOverridesControls = (dynamic_cast(currentFocusedWidget)!=NULL); } void PawsManager::OnWidgetDeleted(pawsWidget * widget) { if (currentFocusedWidget == widget) currentFocusedWidget = NULL; if (mouseoverWidget == widget) mouseoverWidget = NULL; if (movingWidget == widget) movingWidget = NULL; if (modalWidget == widget) modalWidget = NULL; if (resizingWidget == widget) resizingWidget = NULL; if ( lastfadeWidget == widget ) lastfadeWidget = NULL; } void PawsManager::OnWidgetHidden(pawsWidget * widget) { // if the focused widget will be hidden, removed focus from it if (widget->Includes(currentFocusedWidget)) currentFocusedWidget = NULL; if (widget->Includes(mouseoverWidget)) mouseoverWidget = NULL; } csString PawsManager::Translate(const csString & orig) { return localization->Translate(orig); } void PawsManager::CreateWarningBox( const char* message, pawsWidget* notify, bool modal ) { pawsOkBox* ok = (pawsOkBox*)FindWidget("OkWindow"); if ( !ok ) { LoadWidget("data/gui/ok.xml"); ok = (pawsOkBox*)FindWidget("OkWindow"); if ( !ok ) { Error1("Cannot load the ok window!"); return; } } ok->SetText( message ); ok->MoveTo( (graphics2D->GetWidth() - ok->GetActualWidth(512) ) / 2, (graphics2D->GetHeight() - ok->GetActualHeight(256))/2 ); if ( notify ) ok->SetNotify( notify ); if ( modal ) SetModalWidget( ok ); } void PawsManager::CreateYesNoBox( const char* message, pawsWidget* notify, bool modal ) { pawsYesNoBox* yesNoBox = (pawsYesNoBox*)FindWidget("YesNoWindow"); if ( !yesNoBox ) { LoadWidget("data/gui/yesno.xml"); yesNoBox = (pawsYesNoBox*)FindWidget("YesNoWindow"); if ( !yesNoBox ) { Error1("Cannot Load YesNo Window"); return; } } yesNoBox->MoveTo( (graphics2D->GetWidth() - yesNoBox->GetActualWidth(512) ) / 2, (graphics2D->GetHeight() - yesNoBox->GetActualHeight(256))/2 ); yesNoBox->SetText( Translate(message) ); yesNoBox->Show(); if ( modal ) SetModalWidget(yesNoBox); if ( notify ) yesNoBox->SetNotify(notify); } pawsWidget * PawsManager::GetDragDropWidget() { return dragDropWidget; } void PawsManager::SetDragDropWidget(pawsWidget * dragDropWidget) { if (PawsManager::dragDropWidget != NULL) delete PawsManager::dragDropWidget; PawsManager::dragDropWidget = dragDropWidget; PositionDragDropWidget(); } void PawsManager::PositionDragDropWidget() { if (dragDropWidget != NULL) { csRect frame = dragDropWidget->ScreenFrame(); psPoint mousePos = mouse->GetPosition(); dragDropWidget->MoveTo(mousePos.x - frame.Width()/2, mousePos.y - frame.Height()/2); } } #define RegisterFactory(factoryclass) \ factory = new factoryclass(); void PawsManager::RegisterFactories() { pawsWidgetFactory* factory; RegisterFactory (pawsBaseWidgetFactory); RegisterFactory (pawsButtonFactory); RegisterFactory (pawsScrollBarFactory); RegisterFactory (pawsObjectViewFactory); RegisterFactory (pawsGenericViewFactory); RegisterFactory (pawsTextBoxFactory); RegisterFactory (pawsKeySelectBoxFactory); RegisterFactory (pawsMultiLineTextBoxFactory); RegisterFactory (pawsMessageTextBoxFactory); RegisterFactory (pawsEditTextBoxFactory); RegisterFactory (pawsMultilineEditTextBoxFactory); // RegisterFactory (pawsInfoWindowFactory); RegisterFactory (pawsYesNoBoxFactory); RegisterFactory (pawsListBoxFactory); RegisterFactory (pawsComboBoxFactory); RegisterFactory (pawsRadioButtonGroupFactory); RegisterFactory (pawsRadioButtonFactory); RegisterFactory (pawsProgressBarFactory); RegisterFactory (pawsOkBoxFactory); RegisterFactory (pawsSelectorBoxFactory); RegisterFactory (pawsSpinBoxFactory); /* RegisterFactory (pawsSplashWindowFactory); RegisterFactory (pawsLoadWindowFactory); RegisterFactory (pawsChatWindowFactory); RegisterFactory (pawsInventoryWindowFactory); RegisterFactory (pawsItemDescriptionWindowFactory); RegisterFactory (pawsContainerDescWindowFactory); RegisterFactory (pawsInteractWindowFactory); RegisterFactory (pawsControlWindowFactory); RegisterFactory (pawsGroupWindowFactory); RegisterFactory (pawsExchangeWindowFactory); RegisterFactory (pawsSpellBookWindowFactory); RegisterFactory (pawsGlyphWindowFactory); RegisterFactory (pawsMerchantWindowFactory); */ RegisterFactory (pawsTreeFactory); RegisterFactory (pawsSimpleTreeFactory); RegisterFactory (pawsSimpleTreeNodeFactory); RegisterFactory (pawsSeqTreeNodeFactory); RegisterFactory (pawsWidgetTreeNodeFactory); /* RegisterFactory (pawsConfigWindowFactory); RegisterFactory (pawsConfigKeysFactory); RegisterFactory (pawsFingeringWindowFactory); RegisterFactory (pawsConfigDetailsFactory); RegisterFactory (pawsConfigMouseFactory); RegisterFactory (pawsConfigEntityLabelsFactory); RegisterFactory (pawsPetitionWindowFactory); RegisterFactory (pawsPetitionGMWindowFactory); RegisterFactory (pawsPetitionViewWindowFactory); RegisterFactory (pawsShortcutWindowFactory); RegisterFactory (pawsLoginWindowFactory); RegisterFactory (pawsCharacterPickerWindowFactory); RegisterFactory (pawsGuildWindowFactory); RegisterFactory (pawsGuildJoinWindowFactory); RegisterFactory (pawsLootWindowFactory); RegisterFactory (pawsCreationMainFactory); RegisterFactory (pawsCharParentsFactory); RegisterFactory (pawsChildhoodWindowFactory); RegisterFactory (pawsLifeEventWindowFactory); RegisterFactory (pawsPathWindowFactory); RegisterFactory (pawsSummaryWindowFactory); */ RegisterFactory (pawsMenuFactory); RegisterFactory (pawsMenuItemFactory); RegisterFactory (pawsMenuSeparatorFactory); /* RegisterFactory (pawsChatMenuItemFactory); RegisterFactory (pawsSkillWindowFactory); RegisterFactory (pawsQuestListWindowFactory); RegisterFactory (pawsSpellCancelWindowFactory); */ RegisterFactory (pawsCheckBoxFactory); RegisterFactory (pawsTabWindowFactory); RegisterFactory (pawsFileNavigationFactory); RegisterFactory (pawsFadingTextBoxFactory); } bool PawsManager::RegisterSound(const char *name,csRef sounddata) { PawsSoundHandle *pawssndhandle; int name_hash=csHashCompute(name); // Note that a sound loader, vfs instance and renderer are not required at this point. // A renderer is required during playback. // Name collision check { csHash::Iterator sounditerator = sounds.GetIterator(name_hash); while (sounditerator.HasNext()) { pawssndhandle = sounditerator.Next(); if (pawssndhandle->name.Compare(name)) return false; } } // Create a paws handle to relate the name to the iSndSysHandle and add it to our paws managed list pawssndhandle = new PawsSoundHandle(name,sounddata); if (pawssndhandle) sounds.Put(name_hash,pawssndhandle); return true; } csRef PawsManager::LoadSound(const char *filename,const char *registeredname) { PawsSoundHandle *pawssndhandle; // If a registered name is not provided, the filename is used as the registered name if (registeredname==NULL) registeredname=filename; // Filename must always be specified if (filename==NULL) return NULL; // Search for the same sound already loaded int name_hash=csHashCompute(registeredname); { csHash::Iterator sounditerator = sounds.GetIterator(name_hash); while (sounditerator.HasNext()) { pawssndhandle = sounditerator.Next(); if (pawssndhandle->name.Compare(registeredname)) return pawssndhandle->snddata; } } // If there is no sound loader or vfs, sound loading cannot not be performed // This is checked after the registered name check since RegisterSound could add sounds created // by some other method. if (!vfs.IsValid() || !soundloader.IsValid()) return NULL; // Load the file data csRef soundbuf = vfs->ReadFile(filename); if (!soundbuf) { Error2("Error while reading file '%s'", filename); return NULL; } // Read it into a sound buffer csRef sounddata = soundloader->LoadSound (soundbuf); if (!sounddata) { Error2("Cannot create sound data from file '%s'", filename); return NULL; } // Create a paws handle to relate the name to the iSndData and add it to our paws managed list pawssndhandle = new PawsSoundHandle(registeredname,sounddata); if (pawssndhandle) sounds.Put(name_hash,pawssndhandle); // Return the iSndSysHandle return csPtr( sounddata ); } void PawsManager::ToggleSounds(bool value) { useSounds = value; // No need to stop sounds since PAWS generaly use short sounds } bool PawsManager::PlaySound(csRef sounddata) { if(!useSounds) return true; // If there is no sound loader or renderer, sound loading and playing will not be performed if (!sounddata.IsValid() || !soundrenderer.IsValid() ) return false; // Create a stream for this sound csRef sndstream=soundrenderer->CreateStream(sounddata,CS_SND3D_DISABLE); if (!sndstream.IsValid()) return false; // This stream should unregister (and all sources) automatically when it's done playing sndstream->SetAutoUnregister(true); // Create a source just for this sound. csRef source=soundrenderer->CreateSource(sndstream); if (!source.IsValid()) { soundrenderer->RemoveStream(sndstream); return false; } source->SetVolume(volume); sndstream->Unpause(); // Although we lose the reference, the CS sound renderer holds a reference to the source until playback is complete return true; } void PawsManager::ReleaseAllSounds() { PawsSoundHandle *pawssndhandle; { // As we iterate through the hash, the pointers become invalid, it's important that // the hash not be touched between this point and when DeleteAll() is called csHash::GlobalIterator sounditerator = sounds.GetIterator(); while (sounditerator.HasNext()) { pawssndhandle = sounditerator.Next(); delete pawssndhandle; } } // Now delete all the entries pointing to the now-invalid pointers sounds.DeleteAll(); } bool PawsManager::ApplyStyle(const char * name, iDocumentNode * target) { if (styles != NULL) styles->ApplyStyle(name, target); return true; } csString PAWSData::temp_buffer; // declare static string for returning const char* across stack const char *PAWSData::GetStr() { if (type == PAWS_DATA_STR) return str; switch (type) { case PAWS_DATA_BOOL: temp_buffer = boolval?"True":"False"; break; case PAWS_DATA_INT: temp_buffer.Format("%d",intval); break; case PAWS_DATA_FLOAT: temp_buffer.Format("%.2f",floatval); break; } return temp_buffer; } float PAWSData::GetFloat() { if (type == PAWS_DATA_FLOAT) return floatval; switch (type) { case PAWS_DATA_BOOL: return boolval?1:0; case PAWS_DATA_INT: return intval; case PAWS_DATA_STR: return atof(str); } return 0; } int PAWSData::GetInt() { if (type == PAWS_DATA_INT) return intval; switch (type) { case PAWS_DATA_BOOL: return boolval?1:0; case PAWS_DATA_FLOAT: return (int)floatval; case PAWS_DATA_STR: return atoi(str); } return 0; } bool PAWSData::GetBool() { if (type == PAWS_DATA_BOOL) return boolval; switch (type) { case PAWS_DATA_INT: return intval?true:false; case PAWS_DATA_FLOAT: return floatval?true:false; case PAWS_DATA_STR: if (!str || !strlen(str) || !strcasecmp(str,"False") || !strcasecmp(str,"No")) return false; else return true; } return false; } void PawsManager::UnSubscribe(iPAWSSubscriber *listener) { PAWSSubscriptionsHash::GlobalIterator iter = subscriptions.GetIterator(); while (iter.HasNext()) { PAWSSubscription *p = iter.Next(); if (p->subscriber == listener) p->subscriber = 0; } } void PawsManager::Subscribe(const char *dataname,iPAWSSubscriber *listener) { listener->NewSubscription(dataname); PAWSSubscriptionsHash::Iterator iter = subscriptions.GetIterator(dataname); if (!iter.HasNext()) // no one has subscribed yet, so just save subscription { // and wait for publish PAWSSubscription *p = new PAWSSubscription; p->subscriber = listener; subscriptions.Put(dataname,p); } else { PAWSData lastKnownValue; // Check for entries without sibscriber and store lastKnownValue while (iter.HasNext()) { PAWSSubscription *p = iter.Next(); if (!p->subscriber) // data is present already but no subscriber { p->subscriber = listener; p->subscriber->OnUpdateData(dataname,p->lastKnownValue); return; } lastKnownValue = p->lastKnownValue; } // Otherwise no blank slots so just subscribe and publish last Known Value PAWSSubscription *p = new PAWSSubscription; p->subscriber = listener; p->lastKnownValue = lastKnownValue; // Make sure new entries have the same value // as other entries of same dataname. subscriptions.Put(dataname,p); if (p->lastKnownValue.IsData()) p->subscriber->OnUpdateData(dataname,p->lastKnownValue); } } void PawsManager::Publish(const char *dataname,PAWSData& data) { PAWSSubscriptionsHash::Iterator iter = subscriptions.GetIterator(dataname); if (!iter.HasNext()) // no one has subscribed yet, so just save value { PAWSSubscription *p = new PAWSSubscription; p->subscriber = NULL; p->lastKnownValue = data; subscriptions.Put(dataname,p); } // Now publish to any subscribers already active while (iter.HasNext()) { PAWSSubscription *p = iter.Next(); p->lastKnownValue = data; if (p->subscriber) p->subscriber->OnUpdateData(dataname,data); } } void PawsManager::Publish(const char *dataname,const char *datavalue) { PAWSData data; data.type = PAWS_DATA_STR; data.str = datavalue; Publish(dataname,data); } void PawsManager::Publish(const char *dataname,bool datavalue) { PAWSData data; data.type = PAWS_DATA_BOOL; data.boolval = datavalue; Publish(dataname,data); } void PawsManager::Publish(const char *dataname,int datavalue) { PAWSData data; data.type = PAWS_DATA_INT; data.intval = datavalue; Publish(dataname,data); } void PawsManager::Publish(const char *dataname,float datavalue) { PAWSData data; data.type = PAWS_DATA_FLOAT; data.floatval = datavalue; Publish(dataname,data); } csArray PawsManager::ListSubscribers(const char *dataname) { csArray list; PAWSSubscriptionsHash::Iterator iter = subscriptions.GetIterator(dataname); while (iter.HasNext()) { PAWSSubscription *p = iter.Next(); if (p->subscriber) list.Push(p->subscriber); } return list; }