void CConsole::LoadHistory() { // note: we don't care if this file doesn't exist or can't be read; // just don't load anything in that case. // do this before LoadFile to avoid an error message if file not found. if (!VfsFileExists(m_sHistoryFile)) return; shared_ptr<u8> buf; size_t buflen; if (g_VFS->LoadFile(m_sHistoryFile, buf, buflen) < 0) return; CStr bytes ((char*)buf.get(), buflen); CStrW str (bytes.FromUTF8()); size_t pos = 0; while (pos != CStrW::npos) { pos = str.find('\n'); if (pos != CStrW::npos) { if (pos > 0) m_deqBufHistory.push_front(str.Left(str[pos-1] == '\r' ? pos - 1 : pos)); str = str.substr(pos + 1); } else if (str.length() > 0) m_deqBufHistory.push_front(str); } }
bool __ParseString<CRect>(const CStrW& Value, CRect& Output) { const unsigned int NUM_COORDS = 4; float coords[NUM_COORDS]; std::wstringstream stream; stream.str(Value); // Parse each coordinate for (unsigned int i = 0; i < NUM_COORDS; ++i) { if (stream.eof()) { LOGWARNING("Too few CRect parameters (min %i). Your input: '%s'", NUM_COORDS, Value.ToUTF8().c_str()); return false; } stream >> coords[i]; if ((stream.rdstate() & std::wstringstream::failbit) != 0) { LOGWARNING("Unable to parse CRect parameters. Your input: '%s'", Value.ToUTF8().c_str()); return false; } } if (!stream.eof()) { LOGWARNING("Too many CRect parameters (max %i). Your input: '%s'", NUM_COORDS, Value.ToUTF8().c_str()); return false; } // Finally the rectangle values Output = CRect(coords[0], coords[1], coords[2], coords[3]); return true; }
void CGUI::Xeromyces_ReadScript(XMBElement Element, CXeromyces* pFile, boost::unordered_set<VfsPath>& Paths) { // Check for a 'file' parameter CStrW file (Element.GetAttributes().GetNamedItem( pFile->GetAttributeID("file") ).FromUTF8()); // If there is a file specified, open and execute it if (! file.empty()) { Paths.insert(file); try { m_ScriptInterface->LoadGlobalScriptFile(file); } catch (PSERROR_Scripting& e) { LOGERROR(L"GUI: Error executing script %ls: %hs", file.c_str(), e.what()); } } // Execute inline scripts try { CStr code (Element.GetText()); if (! code.empty()) m_ScriptInterface->LoadGlobalScript(L"Some XML file", code.FromUTF8()); } catch (PSERROR_Scripting& e) { LOGERROR(L"GUI: Error executing inline script: %hs", e.what()); } }
bool __ParseString<CPos>(const CStrW& Value, CPos& Output) { const unsigned int NUM_COORDS = 2; float coords[NUM_COORDS]; std::wstringstream stream; stream.str(Value); // Parse each coordinate for (unsigned int i = 0; i < NUM_COORDS; ++i) { if (stream.eof()) { LOGWARNING("Too few CPos parameters (min %i). Your input: '%s'", NUM_COORDS, Value.ToUTF8().c_str()); return false; } stream >> coords[i]; if ((stream.rdstate() & std::wstringstream::failbit) != 0) { LOGWARNING("Unable to parse CPos parameters. Your input: '%s'", Value.ToUTF8().c_str()); return false; } } Output.x = coords[0]; Output.y = coords[1]; if (!stream.eof()) { LOGWARNING("Too many CPos parameters (max %i). Your input: '%s'", NUM_COORDS, Value.ToUTF8().c_str()); return false; } return true; }
int CSys::vPrint( oexCSTRW x_pFmt, oexVaList pArgs ) { //_STT(); CStrW s; s.vFmt( x_pFmt, pArgs ); Echo( s.Ptr() ); return s.Length(); }
void CGUIManager::LoadPage(SGUIPage& page) { // If we're hotloading then try to grab some data from the previous page CScriptValRooted hotloadData; if (page.gui) m_ScriptInterface.CallFunction(OBJECT_TO_JSVAL(page.gui->GetScriptObject()), "getHotloadData", hotloadData); page.inputs.clear(); page.gui.reset(new CGUI()); page.gui->Initialize(); VfsPath path = VfsPath("gui") / page.name; page.inputs.insert(path); CXeromyces xero; if (xero.Load(g_VFS, path) != PSRETURN_OK) // Fail silently (Xeromyces reported the error) return; int elmt_page = xero.GetElementID("page"); int elmt_include = xero.GetElementID("include"); XMBElement root = xero.GetRoot(); if (root.GetNodeName() != elmt_page) { LOGERROR(L"GUI page '%ls' must have root element <page>", page.name.c_str()); return; } XERO_ITER_EL(root, node) { if (node.GetNodeName() != elmt_include) { LOGERROR(L"GUI page '%ls' must only have <include> elements inside <page>", page.name.c_str()); continue; } CStrW name (node.GetText().FromUTF8()); TIMER(name.c_str()); VfsPath path = VfsPath("gui") / name; page.gui->LoadXmlFile(path, page.inputs); } // Remember this GUI page, in case the scripts call FindObjectByName shared_ptr<CGUI> oldGUI = m_CurrentGUI; m_CurrentGUI = page.gui; page.gui->SendEventToAll("load"); // Call the init() function if (!m_ScriptInterface.CallFunctionVoid(OBJECT_TO_JSVAL(page.gui->GetScriptObject()), "init", page.initData, hotloadData)) { LOGERROR(L"GUI page '%ls': Failed to call init() function", page.name.c_str()); } m_CurrentGUI = oldGUI; }
bool __ParseString<CColor>(const CStrW& Value, CColor& Output) { // First, check our database in g_GUI for pre-defined colors // If it fails, it won't do anything with Output if (g_GUI->GetPreDefinedColor(Value.ToUTF8(), Output)) return true; return Output.ParseString(Value.ToUTF8()); }
void Set(const CStrW& swModule, const CStrW& swName, UINT u32ID, const CStrW& swType, UINT u32Type) { sw_CurFile.Clean(); sw_Module = swModule; u32_ID = u32ID; sw_Name = swName; sw_Type = swType; if (u32Type) sw_Type.FormatResource(u32Type); }
int CSys::Print( oexCSTRW x_pFmt, ... ) { //_STT(); CStrW s; oexVaList ap; oexVaStart( ap, x_pFmt ); s.vFmt( x_pFmt, (va_list)ap ); oexVaEnd( ap ); Echo( s.Ptr() ); return s.Length(); }
bool GUI<int>::ParseColor(const CStrW& Value, CColor& Output, int DefaultAlpha) { // First, check our database in g_GUI for pre-defined colors // If we find anything, we'll ignore DefaultAlpha // If it fails, it won't do anything with Output if (g_GUI->GetPreDefinedColor(Value.ToUTF8(), Output)) return true; return Output.ParseString(Value.ToUTF8(), DefaultAlpha); }
bool GUITooltip::GetTooltip(IGUIObject* obj, CStr& style) { if (obj && obj->SettingExists("_icon_tooltip_style") && obj->MouseOverIcon()) { // Special code to handle icon tooltips in text objects if (GUI<CStr>::GetSetting(obj, "_icon_tooltip_style", style) == PSRETURN_OK) { // Check if icon tooltip text exists CStrW text; if (GUI<CStrW>::GetSetting(obj, "_icon_tooltip", text) == PSRETURN_OK) { if (text.empty()) { // No tooltip return false; } if (style.empty()) { // Text, but no style - use default style = "default"; } m_IsIconTooltip = true; return true; } } } else if (obj && obj->SettingExists("tooltip_style") && GUI<CStr>::GetSetting(obj, "tooltip_style", style) == PSRETURN_OK) { CStrW text; if (GUI<CStrW>::GetSetting(obj, "tooltip", text) == PSRETURN_OK) { if (text.empty()) { // No tooltip return false; } if (style.empty()) { // Text, but no style - use default style = "default"; } m_IsIconTooltip = false; return true; } } // Failed while retrieving tooltip_style or tooltip return false; }
jsval ScriptingHost::ExecuteScript(const CStrW& script, const CStrW& calledFrom, JSObject* contextObject ) { jsval rval; JSBool ok = JS_EvaluateUCScript(m_Context, contextObject ? contextObject : m_GlobalObject, reinterpret_cast<const jschar*>(script.utf16().c_str()), (int)script.length(), calledFrom.ToUTF8().c_str(), 1, &rval); if (!ok) return JSVAL_NULL; return rval; }
void SetSettings(const sEnvironmentSettings& s) { CmpPtr<ICmpWaterManager> cmpWaterManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY); ENSURE(cmpWaterManager); cmpWaterManager->SetWaterLevel(entity_pos_t::FromFloat(s.waterheight * (65536.f * HEIGHT_SCALE))); WaterManager* wm = g_Renderer.GetWaterManager(); wm->m_Waviness = s.waterwaviness; wm->m_Murkiness = s.watermurkiness; wm->m_WindAngle = s.windangle; if (wm->m_WaterType != *s.watertype) { wm->m_WaterType = *s.watertype; wm->ReloadWaterNormalTextures(); } #define COLOR(A, B) B = CColor(A->r/255.f, A->g/255.f, A->b/255.f, 1.f) COLOR(s.watercolor, wm->m_WaterColor); COLOR(s.watertint, wm->m_WaterTint); #undef COLOR g_LightEnv.SetRotation(s.sunrotation); g_LightEnv.SetElevation(s.sunelevation); CStrW posteffect = *s.posteffect; if (posteffect.length() == 0) posteffect = L"default"; g_Renderer.GetPostprocManager().SetPostEffect(posteffect); CStrW skySet = *s.skyset; if (skySet.length() == 0) skySet = L"default"; g_Renderer.GetSkyManager()->SetSkySet(skySet); g_LightEnv.m_FogFactor = s.fogfactor; g_LightEnv.m_FogMax = s.fogmax; g_LightEnv.m_Brightness = s.brightness; g_LightEnv.m_Contrast = s.contrast; g_LightEnv.m_Saturation = s.saturation; g_LightEnv.m_Bloom = s.bloom; #define COLOR(A, B) B = RGBColor(A->r/255.f, A->g/255.f, A->b/255.f) COLOR(s.suncolor, g_LightEnv.m_SunColor); g_LightEnv.m_SunColor *= s.sunoverbrightness; COLOR(s.terraincolor, g_LightEnv.m_TerrainAmbientColor); COLOR(s.unitcolor, g_LightEnv.m_UnitsAmbientColor); COLOR(s.fogcolor, g_LightEnv.m_FogColor); #undef COLOR cmpWaterManager->RecomputeWaterData(); }
void CPostprocManager::LoadEffect(CStrW &name) { if (!m_IsInitialised) return; if (name != L"default") { CStrW n = L"postproc/" + name; m_PostProcTech = g_Renderer.GetShaderManager().LoadEffect(CStrIntern(n.ToUTF8())); } m_PostProcEffect = name; }
void CList::SelectPrevElement() { int selected; GUI<int>::GetSetting(this, "selected", selected); if (selected > 0) { --selected; GUI<int>::SetSetting(this, "selected", selected); CStrW soundPath; if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_selected", soundPath) == PSRETURN_OK && !soundPath.empty()) g_SoundManager->PlayAsUI(soundPath.c_str(), false); } }
bool __ParseString<CSize>(const CStrW& Value, CSize &Output) { // Use the parser to parse the values CParser& parser (CParserCache::Get("_$value_$value_")); CParserLine line; line.ParseString(parser, Value.ToUTF8()); if (!line.m_ParseOK) { // Parsing failed return false; } float x, y; // x if (!line.GetArgFloat(0, x)) { // TODO Gee: Parsing failed return false; } // y if (!line.GetArgFloat(1, y)) { // TODO Gee: Parsing failed return false; } Output.cx = x; Output.cy = y; return true; }
bool __ParseString<CRect>(const CStrW& Value, CRect &Output) { // Use the parser to parse the values CParser& parser (CParserCache::Get("_$value_$value_$value_$value_")); CParserLine line; line.ParseString(parser, Value.ToUTF8()); if (!line.m_ParseOK) { // Parsing failed return false; } float values[4]; for (int i=0; i<4; ++i) { if (!line.GetArgFloat(i, values[i])) { // Parsing failed return false; } } // Finally the rectangle values Output = CRect(values[0], values[1], values[2], values[3]); return true; }
// Extract the CAB file at the given URL into the given target directory // If u16_LocalFile = "" -> a temporary file will be created // A Cabfile will be written to disk ONLY if u32_Blocksize = 0 !! // u16_TargetDir = L"" AND Blocksize = 0 --> only download any file from internet to disk BOOL ExtractUrlW(const CStrW& sw_URL, DWORD u32_Blocksize, const CStrW& sw_LocalFile, const CStrW& sw_TargetDir, void* pParam = NULL) { if (!Initialize(sw_URL, sw_LocalFile, u32_Blocksize)) return FALSE; // Just a download without CAB extraction if (!u32_Blocksize && sw_LocalFile.Len() && !sw_TargetDir.Len()) { // The caller may want to access the file immediately -> close all mi_Internet.CleanUp(); return TRUE; } // Pass it on to the base class return ExtractFileW(L"*CABINET\\*URL", sw_TargetDir, pParam); }
/** * Initializes the game world with the attributes provided. **/ void CWorld::RegisterInit(const CStrW& mapFile, const CScriptValRooted& settings, int playerID) { // Load the map, if one was specified if (mapFile.length()) { VfsPath mapfilename = VfsPath(mapFile).ChangeExtension(L".pmp"); CMapReader* reader = 0; try { reader = new CMapReader; CTriggerManager* pTriggerManager = NULL; reader->LoadMap(mapfilename, settings, m_Terrain, CRenderer::IsInitialised() ? g_Renderer.GetWaterManager() : NULL, CRenderer::IsInitialised() ? g_Renderer.GetSkyManager() : NULL, &g_LightEnv, m_pGame->GetView(), m_pGame->GetView() ? m_pGame->GetView()->GetCinema() : NULL, pTriggerManager, CRenderer::IsInitialised() ? &g_Renderer.GetPostprocManager() : NULL, m_pGame->GetSimulation2(), &m_pGame->GetSimulation2()->GetSimContext(), playerID, false); // fails immediately, or registers for delay loading } catch (PSERROR_File& err) { delete reader; LOGERROR(L"Failed to load map %ls: %hs", mapfilename.string().c_str(), err.what()); throw PSERROR_Game_World_MapLoadFailed("Failed to load map.\nCheck application log for details."); } } }
CStrW(const CStrW& s_String) { mu16_Buf = 0; mu32_Size = 0; Allocate(max(DEFAULT_BUFSIZE, s_String.Len())); // throws wcscpy(mu16_Buf, s_String); }
void CCinemaManager::AddPathToQueue(const CStrW& name) { if (!HasPath(name)) { LOGWARNING("Path with name '%s' doesn't exist", name.ToUTF8()); return; } m_CinematicSimulationData.m_PathQueue.push_back(m_CinematicSimulationData.m_Paths[name]); }
void CList::SelectNextElement() { int selected; GUI<int>::GetSetting(this, "selected", selected); CGUIList* pList; GUI<CGUIList>::GetSettingPointer(this, "list", pList); if (selected != (int)pList->m_Items.size()-1) { ++selected; GUI<int>::SetSetting(this, "selected", selected); CStrW soundPath; if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_selected", soundPath) == PSRETURN_OK && !soundPath.empty()) g_SoundManager->PlayAsUI(soundPath.c_str(), false); } }
void CCinemaManager::AddPath(const CStrW& name, const CCinemaPath& path) { if (m_CinematicSimulationData.m_Paths.find(name) != m_CinematicSimulationData.m_Paths.end()) { LOGWARNING("Path with name '%s' already exists", name.ToUTF8()); return; } m_CinematicSimulationData.m_Paths[name] = path; }
void CButton::SetupText() { if (!GetGUI()) return; ENSURE(m_GeneratedTexts.size()==1); CStrW font; if (GUI<CStrW>::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) // Use the default if none is specified // TODO Gee: (2004-08-14) Default should not be hard-coded, but be in styles! font = L"default"; CGUIString caption; GUI<CGUIString>::GetSetting(this, "caption", caption); float buffer_zone=0.f; GUI<float>::GetSetting(this, "buffer_zone", buffer_zone); *m_GeneratedTexts[0] = GetGUI()->GenerateText(caption, font, m_CachedActualSize.GetWidth(), buffer_zone, this); CalculateTextPosition(m_CachedActualSize, m_TextPos, *m_GeneratedTexts[0]); }
JSBool JSI_Console::writeConsole(JSContext* cx, uintN argc, jsval* vp) { UNUSED2(cx); CStrW output; for (uintN i = 0; i < argc; i++) { try { CStrW arg = g_ScriptingHost.ValueToUCString(JS_ARGV(cx, vp)[i]); output += arg; } catch (PSERROR_Scripting_ConversionFailed) { } } // TODO: What if the console has been destroyed already? if (g_Console) g_Console->InsertMessage(L"%ls", output.c_str()); JS_SET_RVAL(cx, vp, JSVAL_VOID); return JS_TRUE; }
// Adds a folder with all its files and all its subfolders to the CAB file // sw_Path = "C:\MyFolder\" // sw_Filter = "*.* or "*.dll" // b_Compress = FALSE --> store in CAB file without compression // Do never set or modify s32_BaseLen !! BOOL AddFolderW(/*NO const*/ CStrW sw_Path, const CStrW& sw_Filter=L"*.*", BOOL b_Compress=TRUE, int s32_BaseLen=-1) { CFile::TerminatePathW(sw_Path); int s32_Len = sw_Path.Len(); if (s32_BaseLen < 0) s32_BaseLen = s32_Len; sw_Path += sw_Filter; WIN32_FIND_DATAW k_Find; HANDLE h_File = FindFirstFileW(sw_Path, &k_Find); if (h_File == INVALID_HANDLE_VALUE) return (GetLastError() == ERROR_FILE_NOT_FOUND); do { if (k_Find.cFileName[0] == '.') // directories "." and ".." continue; CStrW sw_File = sw_Path; sw_File[s32_Len] = 0; sw_File += k_Find.cFileName; if (k_Find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (!AddFolderW(sw_File, sw_Filter, b_Compress, s32_BaseLen)) { FindClose(h_File); return FALSE; } } else { if (!AddFileW(sw_File, (WCHAR*)sw_File + s32_BaseLen, b_Compress)) { FindClose(h_File); return FALSE; } } } while (FindNextFileW(h_File, &k_Find)); FindClose(h_File); return TRUE; }
bool __ParseString<CPos>(const CStrW& Value, CPos &Output) { CParser& parser (CParserCache::Get("_[-$arg(_minus)]$value_[-$arg(_minus)]$value_")); CParserLine line; line.ParseString(parser, Value.ToUTF8()); if (!line.m_ParseOK) return false; float x, y; if (!line.GetArgFloat(0, x)) return false; if (!line.GetArgFloat(1, y)) return false; Output.x = x; Output.y = y; return true; }
CStrW CNetServerWorker::SanitisePlayerName(const CStrW& original) { const size_t MAX_LENGTH = 32; CStrW name = original; name.Replace(L"[", L"{"); // remove GUI tags name.Replace(L"]", L"}"); // remove for symmetry // Restrict the length if (name.length() > MAX_LENGTH) name = name.Left(MAX_LENGTH); // Don't allow surrounding whitespace name.Trim(PS_TRIM_BOTH); // Don't allow empty name if (name.empty()) name = L"Anonymous"; return name; }
void CDropDown::HandleMessage(SGUIMessage& Message) { // Important switch (Message.type) { case GUIM_SETTINGS_UPDATED: { // Update cached list rect if (Message.value == "size" || Message.value == "absolute" || Message.value == "dropdown_size" || Message.value == "dropdown_buffer" || Message.value == "scrollbar_style" || Message.value == "button_width") { SetupListRect(); } break; } case GUIM_MOUSE_MOTION: { if (!m_Open) break; CPos mouse = GetMousePos(); if (!GetListRect().PointInside(mouse)) break; bool scrollbar; CGUIList* pList; GUI<bool>::GetSetting(this, "scrollbar", scrollbar); GUI<CGUIList>::GetSettingPointer(this, "list", pList); float scroll = 0.f; if (scrollbar) scroll = GetScrollBar(0).GetPos(); CRect rect = GetListRect(); mouse.y += scroll; int set = -1; for (int i = 0; i < (int)pList->m_Items.size(); ++i) { if (mouse.y >= rect.top + m_ItemsYPositions[i] && mouse.y < rect.top + m_ItemsYPositions[i+1] && // mouse is not over scroll-bar !(mouse.x >= GetScrollBar(0).GetOuterRect().left && mouse.x <= GetScrollBar(0).GetOuterRect().right)) { set = i; } } if (set != -1) { m_ElementHighlight = set; //UpdateAutoScroll(); } break; } case GUIM_MOUSE_ENTER: { bool enabled; GUI<bool>::GetSetting(this, "enabled", enabled); if (!enabled) break; CStrW soundPath; if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_enter", soundPath) == PSRETURN_OK && !soundPath.empty()) g_SoundManager->PlayAsUI(soundPath.c_str(), false); break; } case GUIM_MOUSE_LEAVE: { GUI<int>::GetSetting(this, "selected", m_ElementHighlight); bool enabled; GUI<bool>::GetSetting(this, "enabled", enabled); if (!enabled) break; CStrW soundPath; if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_leave", soundPath) == PSRETURN_OK && !soundPath.empty()) g_SoundManager->PlayAsUI(soundPath.c_str(), false); break; } // We can't inherent this routine from CList, because we need to include // a mouse click to open the dropdown, also the coordinates are changed. case GUIM_MOUSE_PRESS_LEFT: { bool enabled; GUI<bool>::GetSetting(this, "enabled", enabled); if (!enabled) { CStrW soundPath; if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_disabled", soundPath) == PSRETURN_OK && !soundPath.empty()) g_SoundManager->PlayAsUI(soundPath.c_str(), false); break; } if (!m_Open) { CGUIList* pList; GUI<CGUIList>::GetSettingPointer(this, "list", pList); if (pList->m_Items.empty()) return; m_Open = true; GetScrollBar(0).SetZ(GetBufferedZ()); GUI<int>::GetSetting(this, "selected", m_ElementHighlight); // Start at the position of the selected item, if possible. GetScrollBar(0).SetPos(m_ItemsYPositions.empty() ? 0 : m_ItemsYPositions[m_ElementHighlight] - 60); CStrW soundPath; if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_opened", soundPath) == PSRETURN_OK && !soundPath.empty()) g_SoundManager->PlayAsUI(soundPath.c_str(), false); return; // overshadow } else { CPos mouse = GetMousePos(); // If the regular area is pressed, then abort, and close. if (m_CachedActualSize.PointInside(mouse)) { m_Open = false; GetScrollBar(0).SetZ(GetBufferedZ()); CStrW soundPath; if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_closed", soundPath) == PSRETURN_OK && !soundPath.empty()) g_SoundManager->PlayAsUI(soundPath.c_str(), false); return; // overshadow } if (!(mouse.x >= GetScrollBar(0).GetOuterRect().left && mouse.x <= GetScrollBar(0).GetOuterRect().right) && mouse.y >= GetListRect().top) { m_Open = false; GetScrollBar(0).SetZ(GetBufferedZ()); } } break; } case GUIM_MOUSE_WHEEL_DOWN: { bool enabled; GUI<bool>::GetSetting(this, "enabled", enabled); // Don't switch elements by scrolling when open, causes a confusing interaction between this and the scrollbar. if (m_Open || !enabled) break; GUI<int>::GetSetting(this, "selected", m_ElementHighlight); if (m_ElementHighlight + 1 >= (int)m_ItemsYPositions.size() - 1) break; ++m_ElementHighlight; GUI<int>::SetSetting(this, "selected", m_ElementHighlight); break; } case GUIM_MOUSE_WHEEL_UP: { bool enabled; GUI<bool>::GetSetting(this, "enabled", enabled); // Don't switch elements by scrolling when open, causes a confusing interaction between this and the scrollbar. if (m_Open || !enabled) break; GUI<int>::GetSetting(this, "selected", m_ElementHighlight); if (m_ElementHighlight - 1 < 0) break; m_ElementHighlight--; GUI<int>::SetSetting(this, "selected", m_ElementHighlight); break; } case GUIM_LOST_FOCUS: { if (m_Open) { CStrW soundPath; if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_closed", soundPath) == PSRETURN_OK && !soundPath.empty()) g_SoundManager->PlayAsUI(soundPath.c_str(), false); } m_Open = false; break; } case GUIM_LOAD: SetupListRect(); break; default: break; } // Important that this is after, so that overshadowed implementations aren't processed CList::HandleMessage(Message); // As HandleMessage functions return void, we need to manually verify // whether the child list's items were modified. if (CList::GetModified()) SetupText(); }
void CList::SetupText() { if (!GetGUI()) return; m_Modified = true; CGUIList* pList; GUI<CGUIList>::GetSettingPointer(this, "list", pList); //ENSURE(m_GeneratedTexts.size()>=1); m_ItemsYPositions.resize(pList->m_Items.size()+1); // Delete all generated texts. Some could probably be saved, // but this is easier, and this function will never be called // continuously, or even often, so it'll probably be okay. for (SGUIText* const& t : m_GeneratedTexts) delete t; m_GeneratedTexts.clear(); CStrW font; if (GUI<CStrW>::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) // Use the default if none is specified // TODO Gee: (2004-08-14) Don't define standard like this. Do it with the default style. font = L"default"; bool scrollbar; GUI<bool>::GetSetting(this, "scrollbar", scrollbar); float width = GetListRect().GetWidth(); // remove scrollbar if applicable if (scrollbar && GetScrollBar(0).GetStyle()) width -= GetScrollBar(0).GetStyle()->m_Width; float buffer_zone = 0.f; GUI<float>::GetSetting(this, "buffer_zone", buffer_zone); // Generate texts float buffered_y = 0.f; for (size_t i = 0; i < pList->m_Items.size(); ++i) { // Create a new SGUIText. Later on, input it using AddText() SGUIText* text = new SGUIText(); *text = GetGUI()->GenerateText(pList->m_Items[i], font, width, buffer_zone, this); m_ItemsYPositions[i] = buffered_y; buffered_y += text->m_Size.cy; AddText(text); } m_ItemsYPositions[pList->m_Items.size()] = buffered_y; // Setup scrollbar if (scrollbar) { GetScrollBar(0).SetScrollRange(m_ItemsYPositions.back()); GetScrollBar(0).SetScrollSpace(GetListRect().GetHeight()); CRect rect = GetListRect(); GetScrollBar(0).SetX(rect.right); GetScrollBar(0).SetY(rect.top); GetScrollBar(0).SetZ(GetBufferedZ()); GetScrollBar(0).SetLength(rect.bottom - rect.top); } }