llfloaterreg.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:12k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llfloaterreg.cpp
  3.  * @brief LLFloaterReg Floater Registration Class
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "linden_common.h"
  33. #include "llfloaterreg.h"
  34. //#include "llagent.h" 
  35. #include "llfloater.h"
  36. #include "llmultifloater.h"
  37. #include "llfloaterreglistener.h"
  38. //*******************************************************
  39. //static
  40. LLFloaterReg::instance_list_t LLFloaterReg::sNullInstanceList;
  41. LLFloaterReg::instance_map_t LLFloaterReg::sInstanceMap;
  42. LLFloaterReg::build_map_t LLFloaterReg::sBuildMap;
  43. std::map<std::string,std::string> LLFloaterReg::sGroupMap;
  44. bool LLFloaterReg::sBlockShowFloaters = false;
  45. static LLFloaterRegListener sFloaterRegListener;
  46. //*******************************************************
  47. //static
  48. void LLFloaterReg::add(const std::string& name, const std::string& filename, const LLFloaterBuildFunc& func, const std::string& groupname)
  49. {
  50. sBuildMap[name].mFunc = func;
  51. sBuildMap[name].mFile = filename;
  52. sGroupMap[name] = groupname.empty() ? name : groupname;
  53. sGroupMap[groupname] = groupname; // for referencing directly by group name
  54. }
  55. //static
  56. LLRect LLFloaterReg::getFloaterRect(const std::string& name)
  57. {
  58. LLRect rect;
  59. const std::string& groupname = sGroupMap[name];
  60. if (!groupname.empty())
  61. {
  62. instance_list_t& list = sInstanceMap[groupname];
  63. if (!list.empty())
  64. {
  65. static LLUICachedControl<S32> floater_offset ("UIFloaterOffset", 16);
  66. LLFloater* last_floater = list.back();
  67. if (last_floater->getHost())
  68. {
  69. rect = last_floater->getHost()->getRect();
  70. }
  71. else
  72. {
  73. rect = last_floater->getRect();
  74. }
  75. rect.translate(floater_offset, -floater_offset);
  76. }
  77. }
  78. return rect;
  79. }
  80. //static
  81. LLFloater* LLFloaterReg::findInstance(const std::string& name, const LLSD& key)
  82. {
  83. LLFloater* res = NULL;
  84. const std::string& groupname = sGroupMap[name];
  85. if (!groupname.empty())
  86. {
  87. instance_list_t& list = sInstanceMap[groupname];
  88. for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
  89. {
  90. LLFloater* inst = *iter;
  91. if (inst->matchesKey(key))
  92. {
  93. res = inst;
  94. break;
  95. }
  96. }
  97. }
  98. return res;
  99. }
  100. //static
  101. LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key) 
  102. {
  103. LLFloater* res = findInstance(name, key);
  104. if (!res)
  105. {
  106. const LLFloaterBuildFunc& build_func = sBuildMap[name].mFunc;
  107. const std::string& xui_file = sBuildMap[name].mFile;
  108. if (build_func)
  109. {
  110. const std::string& groupname = sGroupMap[name];
  111. if (!groupname.empty())
  112. {
  113. instance_list_t& list = sInstanceMap[groupname];
  114. int index = list.size();
  115. res = build_func(key);
  116. bool success = LLUICtrlFactory::getInstance()->buildFloater(res, xui_file, NULL);
  117. if (!success)
  118. {
  119. llwarns << "Failed to build floater type: '" << name << "'." << llendl;
  120. return NULL;
  121. }
  122. // Note: key should eventually be a non optional LLFloater arg; for now, set mKey to be safe
  123. res->mKey = key;
  124. res->setInstanceName(name);
  125. res->applySavedVariables(); // Can't apply rect and dock state until setting instance name
  126. if (res->mAutoTile && !res->getHost() && index > 0)
  127. {
  128. const LLRect& cur_rect = res->getRect();
  129. LLRect next_rect = getFloaterRect(groupname);
  130. next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, cur_rect.getWidth(), cur_rect.getHeight());
  131. res->setRect(next_rect);
  132. res->setRectControl(LLStringUtil::null); // don't save rect of tiled floaters
  133. gFloaterView->adjustToFitScreen(res, true);
  134. }
  135. else
  136. {
  137. gFloaterView->adjustToFitScreen(res, false);
  138. }
  139. list.push_back(res);
  140. }
  141. }
  142. if (!res)
  143. {
  144. llwarns << "Floater type: '" << name << "' not registered." << llendl;
  145. }
  146. }
  147. return res;
  148. }
  149. //static
  150. LLFloater* LLFloaterReg::removeInstance(const std::string& name, const LLSD& key)
  151. {
  152. LLFloater* res = NULL;
  153. const std::string& groupname = sGroupMap[name];
  154. if (!groupname.empty())
  155. {
  156. instance_list_t& list = sInstanceMap[groupname];
  157. for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
  158. {
  159. LLFloater* inst = *iter;
  160. if (inst->matchesKey(key))
  161. {
  162. res = inst;
  163. list.erase(iter);
  164. break;
  165. }
  166. }
  167. }
  168. return res;
  169. }
  170. //static
  171. // returns true if the instance existed
  172. bool LLFloaterReg::destroyInstance(const std::string& name, const LLSD& key)
  173. {
  174. LLFloater* inst = removeInstance(name, key);
  175. if (inst)
  176. {
  177. delete inst;
  178. return true;
  179. }
  180. else
  181. {
  182. return false;
  183. }
  184. }
  185. // Iterators
  186. //static
  187. LLFloaterReg::const_instance_list_t& LLFloaterReg::getFloaterList(const std::string& name)
  188. {
  189. instance_map_t::iterator iter = sInstanceMap.find(name);
  190. if (iter != sInstanceMap.end())
  191. {
  192. return iter->second;
  193. }
  194. else
  195. {
  196. return sNullInstanceList;
  197. }
  198. }
  199. // Visibility Management
  200. //static
  201. LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, BOOL focus) 
  202. {
  203. if( sBlockShowFloaters )
  204. return 0;//
  205. LLFloater* instance = getInstance(name, key); 
  206. if (instance) 
  207. {
  208. instance->openFloater(key);
  209. if (focus)
  210. instance->setFocus(TRUE);
  211. }
  212. return instance;
  213. }
  214. //static
  215. // returns true if the instance exists
  216. bool LLFloaterReg::hideInstance(const std::string& name, const LLSD& key) 
  217. LLFloater* instance = findInstance(name, key); 
  218. if (instance)
  219. {
  220. // When toggling *visibility*, close the host instead of the floater when hosted
  221. if (instance->getHost())
  222. instance->getHost()->closeFloater();
  223. else
  224. instance->closeFloater();
  225. return true;
  226. }
  227. else
  228. {
  229. return false;
  230. }
  231. }
  232. //static
  233. // returns true if the instance is visible when completed
  234. bool LLFloaterReg::toggleInstance(const std::string& name, const LLSD& key)
  235. {
  236. LLFloater* instance = findInstance(name, key); 
  237. if (LLFloater::isShown(instance))
  238. {
  239. // When toggling *visibility*, close the host instead of the floater when hosted
  240. if (instance->getHost())
  241. instance->getHost()->closeFloater();
  242. else
  243. instance->closeFloater();
  244. return false;
  245. }
  246. else
  247. {
  248. return showInstance(name, key, TRUE) ? true : false;
  249. }
  250. }
  251. //static
  252. // returns true if the instance exists and is visible
  253. bool LLFloaterReg::instanceVisible(const std::string& name, const LLSD& key)
  254. {
  255. LLFloater* instance = findInstance(name, key); 
  256. return LLFloater::isShown(instance);
  257. }
  258. //static
  259. void LLFloaterReg::showInitialVisibleInstances() 
  260. {
  261. // Iterate through alll registered instance names and show any with a save visible state
  262. for (build_map_t::iterator iter = sBuildMap.begin(); iter != sBuildMap.end(); ++iter)
  263. {
  264. const std::string& name = iter->first;
  265. std::string controlname = getVisibilityControlName(name);
  266. if (LLUI::sSettingGroups["floater"]->controlExists(controlname))
  267. {
  268. BOOL isvis = LLUI::sSettingGroups["floater"]->getBOOL(controlname);
  269. if (isvis)
  270. {
  271. showInstance(name, LLSD()); // keyed floaters shouldn't set save_vis to true
  272. }
  273. }
  274. }
  275. }
  276. //static
  277. void LLFloaterReg::hideVisibleInstances(const std::set<std::string>& exceptions)
  278. {
  279. // Iterate through alll active instances and hide them
  280. for (instance_map_t::iterator iter = sInstanceMap.begin(); iter != sInstanceMap.end(); ++iter)
  281. {
  282. const std::string& name = iter->first;
  283. if (exceptions.find(name) != exceptions.end())
  284. continue;
  285. instance_list_t& list = iter->second;
  286. for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
  287. {
  288. LLFloater* floater = *iter;
  289. floater->pushVisible(FALSE);
  290. }
  291. }
  292. }
  293. //static
  294. void LLFloaterReg::restoreVisibleInstances()
  295. {
  296. // Iterate through all active instances and restore visibility
  297. for (instance_map_t::iterator iter = sInstanceMap.begin(); iter != sInstanceMap.end(); ++iter)
  298. {
  299. instance_list_t& list = iter->second;
  300. for (instance_list_t::iterator iter = list.begin(); iter != list.end(); ++iter)
  301. {
  302. LLFloater* floater = *iter;
  303. floater->popVisible();
  304. }
  305. }
  306. }
  307. //static
  308. std::string LLFloaterReg::getRectControlName(const std::string& name)
  309. {
  310. std::string res = std::string("floater_rect_") + name;
  311. LLStringUtil::replaceChar( res, ' ', '_' );
  312. return res;
  313. }
  314. //static
  315. std::string LLFloaterReg::declareRectControl(const std::string& name)
  316. {
  317. std::string controlname = getRectControlName(name);
  318. LLUI::sSettingGroups["floater"]->declareRect(controlname, LLRect(),
  319.  llformat("Window Position and Size for %s", name.c_str()),
  320.  TRUE);
  321. return controlname;
  322. }
  323. //static
  324. std::string LLFloaterReg::getVisibilityControlName(const std::string& name)
  325. {
  326. std::string res = std::string("floater_vis_") + name;
  327. LLStringUtil::replaceChar( res, ' ', '_' );
  328. return res;
  329. }
  330. //static
  331. std::string LLFloaterReg::declareVisibilityControl(const std::string& name)
  332. {
  333. std::string controlname = getVisibilityControlName(name);
  334. LLUI::sSettingGroups["floater"]->declareBOOL(controlname, FALSE,
  335.  llformat("Window Visibility for %s", name.c_str()),
  336.  TRUE);
  337. return controlname;
  338. }
  339. //static
  340. std::string LLFloaterReg::declareDockStateControl(const std::string& name)
  341. {
  342. std::string controlname = getDockStateControlName(name);
  343. LLUI::sSettingGroups["floater"]->declareBOOL(controlname, TRUE,
  344.  llformat("Window Docking state for %s", name.c_str()),
  345.  TRUE);
  346. return controlname;
  347. }
  348. //static
  349. std::string LLFloaterReg::getDockStateControlName(const std::string& name)
  350. {
  351. std::string res = std::string("floater_dock_") + name;
  352. LLStringUtil::replaceChar( res, ' ', '_' );
  353. return res;
  354. }
  355. //static
  356. void LLFloaterReg::registerControlVariables()
  357. {
  358. // Iterate through alll registered instance names and register rect and visibility control variables
  359. for (build_map_t::iterator iter = sBuildMap.begin(); iter != sBuildMap.end(); ++iter)
  360. {
  361. const std::string& name = iter->first;
  362. if (LLUI::sSettingGroups["floater"]->controlExists(getRectControlName(name)))
  363. {
  364. declareRectControl(name);
  365. }
  366. if (LLUI::sSettingGroups["floater"]->controlExists(getVisibilityControlName(name)))
  367. {
  368. declareVisibilityControl(name);
  369. }
  370. }
  371. }
  372. // Callbacks
  373. // static
  374. // Call once (i.e use for init callbacks)
  375. void LLFloaterReg::initUICtrlToFloaterVisibilityControl(LLUICtrl* ctrl, const LLSD& sdname)
  376. {
  377. // Get the visibility control name for the floater
  378. std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString());
  379. // Set the control value to the floater visibility control (Sets the value as well)
  380. ctrl->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name));
  381. }
  382. // callback args may use "floatername.key" format
  383. static void parse_name_key(std::string& name, LLSD& key)
  384. {
  385. std::string instname = name;
  386. std::size_t dotpos = instname.find(".");
  387. if (dotpos != std::string::npos)
  388. {
  389. name = instname.substr(0, dotpos);
  390. key = LLSD(instname.substr(dotpos+1, std::string::npos));
  391. }
  392. }
  393. //static
  394. void LLFloaterReg::showFloaterInstance(const LLSD& sdname)
  395. {
  396. LLSD key;
  397. std::string name = sdname.asString();
  398. parse_name_key(name, key);
  399. showInstance(name, key, TRUE);
  400. }
  401. //static
  402. void LLFloaterReg::hideFloaterInstance(const LLSD& sdname)
  403. {
  404. LLSD key;
  405. std::string name = sdname.asString();
  406. parse_name_key(name, key);
  407. hideInstance(name, key);
  408. }
  409. //static
  410. void LLFloaterReg::toggleFloaterInstance(const LLSD& sdname)
  411. {
  412. LLSD key;
  413. std::string name = sdname.asString();
  414. parse_name_key(name, key);
  415. toggleInstance(name, key);
  416. }
  417. //static
  418. bool LLFloaterReg::floaterInstanceVisible(const LLSD& sdname)
  419. {
  420. LLSD key;
  421. std::string name = sdname.asString();
  422. parse_name_key(name, key);
  423. return instanceVisible(name, key);
  424. }