llfloatereditui.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. /**
  2. * @file llfloatereditui.cpp
  3. * @author James Cook
  4. * @date May 2005
  5. * @brief In-world user interface editor
  6. *
  7. * $LicenseInfo:firstyear=2005&license=viewergpl$
  8. *
  9. * Copyright (c) 2005-2009, Linden Research, Inc.
  10. *
  11. * Second Life Viewer Source Code
  12. * The source code in this file ("Source Code") is provided by Linden Lab
  13. * to you under the terms of the GNU General Public License, version 2.0
  14. * ("GPL"), unless you have obtained a separate licensing agreement
  15. * ("Other License"), formally executed by you and Linden Lab. Terms of
  16. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18. *
  19. * There are special exceptions to the terms and conditions of the GPL as
  20. * it is applied to this Source Code. View the full text of the exception
  21. * in the file doc/FLOSS-exception.txt in this software distribution, or
  22. * online at
  23. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24. *
  25. * By copying, modifying or distributing this software, you acknowledge
  26. * that you have read and understood your obligations described above,
  27. * and agree to abide by those obligations.
  28. *
  29. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31. * COMPLETENESS OR PERFORMANCE.
  32. * $/LicenseInfo$
  33. */
  34. #include "llviewerprecompiledheaders.h"
  35. #include "llfloatereditui.h"
  36. #include "llbutton.h"
  37. #include "lllineeditor.h"
  38. #include "llspinctrl.h"
  39. #include "lltextbox.h"
  40. void LLFloaterEditUI::navigateHierarchyButtonPressed(void* data)
  41. {
  42. LLView* view = LLView::sEditingUIView;
  43. if (!view) return;
  44. LLView* parent = view->getParent();
  45. if (!parent)
  46. {
  47. return;
  48. }
  49. const LLView::child_list_t* viewChildren = view->getChildList();
  50. const LLView::child_list_t* parentChildren = parent->getChildList();
  51. std::list<LLView*>::const_iterator itor;
  52. std::list<LLView*>::size_type idx;
  53. std::list<LLView*>::size_type sidx;
  54. for (idx = 0, itor = parentChildren->begin();
  55. itor != parentChildren->end(); ++itor, ++idx)
  56. {
  57. if (*itor == view)
  58. {
  59. break;
  60. }
  61. }
  62. switch ((intptr_t)data)
  63. {
  64. case 0: // up
  65. view = view->getParent();
  66. break;
  67. case 1: // down
  68. view = viewChildren->begin() != viewChildren->end() ? *viewChildren->begin()
  69. : NULL;
  70. break;
  71. case 2: // left
  72. {
  73. if (idx == 0)
  74. {
  75. idx = parentChildren->size() - 1;
  76. }
  77. else
  78. {
  79. --idx;
  80. }
  81. if ((S32)idx < 0 || idx >= parentChildren->size())
  82. {
  83. break;
  84. }
  85. for (sidx = 0, itor = parentChildren->begin();
  86. itor != parentChildren->end(); ++itor, ++sidx)
  87. {
  88. if (sidx == idx)
  89. {
  90. view = *itor;
  91. break;
  92. }
  93. }
  94. break;
  95. }
  96. case 3: // right
  97. {
  98. if (idx == parentChildren->size() - 1)
  99. {
  100. idx = 0;
  101. }
  102. else
  103. {
  104. ++idx;
  105. }
  106. if ((S32)idx < 0 || idx >= parentChildren->size())
  107. {
  108. break;
  109. }
  110. for (sidx = 0, itor = parentChildren->begin();
  111. itor != parentChildren->end(); ++itor, ++sidx)
  112. {
  113. if (sidx == idx)
  114. {
  115. view = *itor;
  116. break;
  117. }
  118. }
  119. break;
  120. }
  121. }
  122. if (view)
  123. {
  124. sEditingUIView = view;
  125. getInstance()->refresh();
  126. }
  127. }
  128. LLFloaterEditUI::LLFloaterEditUI(const LLSD&)
  129. : LLFloater("ui editor", LLRect(0, 200, 200, 0), "Edit user interface"),
  130. mLastView(NULL),
  131. mLabelLine(NULL),
  132. mWidthSpin(NULL),
  133. mHeightSpin(NULL)
  134. {
  135. LLView::sEditingUI = true;
  136. S32 x = HPAD;
  137. S32 y = getRect().getHeight() - LINE - LINE - VPAD;
  138. constexpr S32 R1 = HPAD + 40;
  139. LLButton* button = NULL;
  140. LLLineEditor* line = NULL;
  141. LLSpinCtrl* spin = NULL;
  142. LLTextBox* text = NULL;
  143. text = new LLTextBox(std::string("Selected UI Widget:"),
  144. LLRect(x, y + 16, x + 100, y));
  145. addChild(text);
  146. y -= VPAD + 16;
  147. text = new LLTextBox(std::string("Label:"), LLRect(x, y + 16, x + 40, y));
  148. addChild(text);
  149. x = R1;
  150. line = new LLLineEditor(std::string("label_line"),
  151. LLRect(x, y + 20, x + 100, y), LLStringUtil::null,
  152. NULL, 254, onCommitLabel, NULL, NULL, this);
  153. addChild(line);
  154. mLabelLine = line;
  155. x = HPAD;
  156. y -= VPAD + 20;
  157. spin = new LLSpinCtrl(std::string("height_spin"),
  158. LLRect(x, y + 20, x + 100, y),
  159. std::string("Height:"),
  160. LLFontGL::getFontSansSerifSmall(),
  161. onCommitHeight, this, 0.f, 2.f, 1000.f, 1.f);
  162. spin->setPrecision(0);
  163. addChild(spin);
  164. mHeightSpin = spin;
  165. y -= VPAD + 20;
  166. spin = new LLSpinCtrl(std::string("width_spin"),
  167. LLRect(x, y + 20, x + 100, y),
  168. std::string("Width:"),
  169. LLFontGL::getFontSansSerifSmall(),
  170. onCommitWidth, this, 0.f, 2.f, 1000.f, 1.f);
  171. spin->setPrecision(0);
  172. addChild(spin);
  173. mWidthSpin = spin;
  174. y -= VPAD + 20;
  175. text = new LLTextBox(std::string("XML Name:"),
  176. LLRect(x, y + 16, x + 60, y));
  177. addChild(text);
  178. x+=60;
  179. text = new LLTextBox(std::string("xml_name"),
  180. LLRect(x, y + 16, x + 100, y));
  181. addChild(text);
  182. x-=50;
  183. y -= VPAD + 20;
  184. x += 40;
  185. button = new LLButton(std::string("up"), LLRect(x, y + 16, x + 32, y));
  186. addChild(button);
  187. x -= 40;
  188. y -= VPAD + 20;
  189. button = new LLButton(std::string("<<"), LLRect(x, y + 16, x + 32, y));
  190. addChild(button);
  191. x += 40;
  192. button = new LLButton(std::string("rfrsh"), LLRect(x, y + 16, x + 32, y));
  193. addChild(button);
  194. x += 40;
  195. button = new LLButton(std::string(">>"), LLRect(x, y + 16, x + 32, y));
  196. addChild(button);
  197. x -= 40;
  198. y -= VPAD + 20;
  199. button = new LLButton(std::string("dn"), LLRect(x, y + 16, x + 32, y));
  200. addChild(button);
  201. childSetAction("up", navigateHierarchyButtonPressed, (void*)0);
  202. childSetAction("dn", navigateHierarchyButtonPressed, (void*)1);
  203. childSetAction("<<", navigateHierarchyButtonPressed, (void*)2);
  204. childSetAction(">>", navigateHierarchyButtonPressed, (void*)3);
  205. childSetAction("rfrsh", navigateHierarchyButtonPressed, (void*)4);
  206. }
  207. //virtual
  208. LLFloaterEditUI::~LLFloaterEditUI()
  209. {
  210. LLView::sEditingUI = false;
  211. LLView::sEditingUIView = NULL;
  212. }
  213. //virtual
  214. void LLFloaterEditUI::draw()
  215. {
  216. refresh();
  217. LLFloater::draw();
  218. }
  219. void LLFloaterEditUI::refresh()
  220. {
  221. LLView* view = LLView::sEditingUIView;
  222. // same selection
  223. if (view == mLastView) return;
  224. // user deselected
  225. if (!view)
  226. {
  227. mLastView = NULL;
  228. mLabelLine->setText(LLStringUtil::null);
  229. mLabelLine->setEnabled(false);
  230. mWidthSpin->set(0.f);
  231. mWidthSpin->setEnabled(false);
  232. mHeightSpin->set(0.f);
  233. mHeightSpin->setEnabled(false);
  234. return;
  235. }
  236. // *HACK: don't allow widgets in this window to be selected
  237. LLView* parent = view->getParent();
  238. while (parent)
  239. {
  240. if (parent == this)
  241. {
  242. // user selected one of our children, slam them back
  243. LLView::sEditingUIView = mLastView;
  244. return;
  245. }
  246. parent = parent->getParent();
  247. }
  248. refreshCore();
  249. mLastView = view;
  250. }
  251. void LLFloaterEditUI::refreshCore()
  252. {
  253. LLView* view = LLView::sEditingUIView;
  254. if (!view) return;
  255. LLRect r = view->getRect();
  256. F32 width = (F32)r.getWidth();
  257. F32 height = (F32)r.getHeight();
  258. mWidthSpin->set(width);
  259. mHeightSpin->set(height);
  260. LLButton* buttonp = dynamic_cast<LLButton*>(view);
  261. if (buttonp)
  262. {
  263. refreshButton(view);
  264. }
  265. else
  266. {
  267. refreshView(view);
  268. }
  269. }
  270. void LLFloaterEditUI::refreshView(LLView* view)
  271. {
  272. if (view)
  273. {
  274. mLabelLine->setEnabled(false);
  275. mLabelLine->setText(LLStringUtil::null);
  276. childSetText("xml_name", view->getName());
  277. }
  278. }
  279. void LLFloaterEditUI::refreshButton(LLView* view)
  280. {
  281. if (view)
  282. {
  283. LLButton* btn = (LLButton*)view;
  284. std::string label = btn->getLabelUnselected();
  285. mLabelLine->setEnabled(true);
  286. mLabelLine->setText(label);
  287. childSetText("xml_name", view->getName());
  288. }
  289. }
  290. //static
  291. void LLFloaterEditUI::show(void*)
  292. {
  293. LLFloaterEditUI* self = getInstance();
  294. if (self)
  295. {
  296. self->center();
  297. self->open();
  298. }
  299. }
  300. //static
  301. bool LLFloaterEditUI::processKeystroke(KEY key, MASK mask)
  302. {
  303. if (!LLView::sEditingUIView) return false;
  304. S32 step = 2;
  305. bool handled = false;
  306. LLRect r = LLView::sEditingUIView->getRect();
  307. if (mask == MASK_NONE)
  308. {
  309. if (key == KEY_RIGHT)
  310. {
  311. r.translate(step, 0);
  312. handled = true;
  313. }
  314. else if (key == KEY_LEFT)
  315. {
  316. r.translate(-step, 0);
  317. handled = true;
  318. }
  319. else if (key == KEY_UP)
  320. {
  321. r.translate(0, step);
  322. handled = true;
  323. }
  324. else if (key == KEY_DOWN)
  325. {
  326. r.translate(0, -step);
  327. handled = true;
  328. }
  329. }
  330. else if (mask == MASK_SHIFT)
  331. {
  332. if (key == KEY_RIGHT)
  333. {
  334. r.mRight += step;
  335. handled = true;
  336. }
  337. else if (key == KEY_LEFT)
  338. {
  339. r.mRight -= step;
  340. handled = true;
  341. }
  342. else if (key == KEY_UP)
  343. {
  344. r.mTop += step;
  345. handled = true;
  346. }
  347. else if (key == KEY_DOWN)
  348. {
  349. r.mTop -= step;
  350. handled = true;
  351. }
  352. }
  353. if (handled)
  354. {
  355. LLView::sEditingUIView->reshape(r.getWidth(), r.getHeight());
  356. LLView::sEditingUIView->setRect(r);
  357. if (findInstance())
  358. {
  359. getInstance()->refreshCore();
  360. }
  361. }
  362. return handled;
  363. }
  364. //static
  365. void LLFloaterEditUI::onCommitLabel(LLUICtrl* ctrl, void* data)
  366. {
  367. LLView* view = LLView::sEditingUIView;
  368. if (!view && ctrl) return;
  369. LLLineEditor* line = (LLLineEditor*)ctrl;
  370. const std::string& text = line->getText();
  371. LLButton* btn = dynamic_cast<LLButton*>(view);
  372. if (btn)
  373. {
  374. btn->setLabelUnselected(text);
  375. btn->setLabelSelected(text);
  376. }
  377. }
  378. //static
  379. void LLFloaterEditUI::onCommitHeight(LLUICtrl* ctrl, void* data)
  380. {
  381. LLView* view = LLView::sEditingUIView;
  382. if (view && ctrl)
  383. {
  384. LLSpinCtrl* spin = (LLSpinCtrl*)ctrl;
  385. F32 height = spin->get();
  386. LLRect r = view->getRect();
  387. r.mTop = r.mBottom + (S32)height;
  388. view->reshape(r.getWidth(), r.getHeight());
  389. view->setRect(r);
  390. }
  391. }
  392. //static
  393. void LLFloaterEditUI::onCommitWidth(LLUICtrl* ctrl, void* data)
  394. {
  395. LLView* view = LLView::sEditingUIView;
  396. if (view && ctrl)
  397. {
  398. LLSpinCtrl* spin = (LLSpinCtrl*)ctrl;
  399. F32 width = spin->get();
  400. LLRect r = view->getRect();
  401. r.mRight = r.mLeft + (S32)width;
  402. view->reshape(r.getWidth(), r.getHeight());
  403. view->setRect(r);
  404. }
  405. }