llcheckboxctrl.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /**
  2. * @file llcheckboxctrl.cpp
  3. * @brief LLCheckBoxCtrl base class
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, 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. // The mutants are coming!
  33. #include "linden_common.h"
  34. #include "llcheckboxctrl.h"
  35. #include "llcontrol.h"
  36. #include "llgl.h"
  37. #include "lltextbox.h"
  38. #include "lluictrlfactory.h"
  39. static const std::string LL_CHECK_BOX_CTRL_TAG = "check_box";
  40. static LLRegisterWidget<LLCheckBoxCtrl> r02(LL_CHECK_BOX_CTRL_TAG);
  41. LLCheckBoxCtrl::LLCheckBoxCtrl(const std::string& name,
  42. const LLRect& rect,
  43. const std::string& label,
  44. const LLFontGL* fontp,
  45. void (*commit_callback)(LLUICtrl*, void*),
  46. void* callback_user_data,
  47. bool initial_value,
  48. bool use_radio_style,
  49. const char* control_name)
  50. : LLUICtrl(name, rect, true, commit_callback, callback_user_data,
  51. FOLLOWS_LEFT | FOLLOWS_TOP),
  52. mTextEnabledColor(LLUI::sLabelTextColor),
  53. mTextDisabledColor(LLUI::sLabelDisabledColor),
  54. mRadioStyle(use_radio_style),
  55. mInitialValue(initial_value),
  56. mSetValue(initial_value)
  57. {
  58. if (fontp)
  59. {
  60. mFont = fontp;
  61. }
  62. else
  63. {
  64. mFont = LLFontGL::getFontSansSerifSmall();
  65. }
  66. // Must be big enough to hold all children
  67. setUseBoundingRect(true);
  68. // Label (add a little space to make sure text actually renders)
  69. constexpr S32 FUDGE = 10;
  70. S32 text_width = mFont->getWidth(label) + FUDGE;
  71. S32 text_height = ll_roundp(mFont->getLineHeight());
  72. LLRect label_rect;
  73. label_rect.setOriginAndSize(LLCHECKBOXCTRL_HPAD + LLCHECKBOXCTRL_BTN_SIZE +
  74. LLCHECKBOXCTRL_SPACING,
  75. LLCHECKBOXCTRL_VPAD + 1,
  76. text_width + LLCHECKBOXCTRL_HPAD, text_height);
  77. #if 0
  78. // *HACK Get rid of this with SL-55508...
  79. // this allows blank check boxes and radio boxes for now
  80. std::string local_label = label;
  81. if (local_label.empty())
  82. {
  83. local_label = " ";
  84. }
  85. mLabel = new LLTextBox("CheckboxCtrl Label", label_rect, local_label,
  86. mFont);
  87. #else
  88. mLabel = new LLTextBox("CheckboxCtrl Label", label_rect, label, mFont);
  89. #endif
  90. mLabel->setFollowsLeft();
  91. mLabel->setFollowsBottom();
  92. addChild(mLabel);
  93. // Button
  94. // Note: button cover the label by extending all the way to the right.
  95. LLRect btn_rect;
  96. btn_rect.setOriginAndSize(LLCHECKBOXCTRL_HPAD, LLCHECKBOXCTRL_VPAD,
  97. LLCHECKBOXCTRL_BTN_SIZE +
  98. LLCHECKBOXCTRL_SPACING + text_width +
  99. LLCHECKBOXCTRL_HPAD,
  100. llmax(text_height, LLCHECKBOXCTRL_BTN_SIZE) + LLCHECKBOXCTRL_VPAD);
  101. std::string active_true_id, active_false_id;
  102. std::string inactive_true_id, inactive_false_id;
  103. if (mRadioStyle)
  104. {
  105. active_true_id = "UIImgRadioActiveSelectedUUID";
  106. active_false_id = "UIImgRadioActiveUUID";
  107. inactive_true_id = "UIImgRadioInactiveSelectedUUID";
  108. inactive_false_id = "UIImgRadioInactiveUUID";
  109. mButton = new LLButton("Radio control button", btn_rect,
  110. active_false_id, active_true_id, control_name,
  111. &LLCheckBoxCtrl::onButtonPress, this,
  112. LLFontGL::getFontSansSerif());
  113. mButton->setDisabledImages(inactive_false_id, inactive_true_id);
  114. mButton->setHoverGlowStrength(0.35f);
  115. }
  116. else
  117. {
  118. active_false_id = "UIImgCheckboxActiveUUID";
  119. active_true_id = "UIImgCheckboxActiveSelectedUUID";
  120. inactive_true_id = "UIImgCheckboxInactiveSelectedUUID";
  121. inactive_false_id = "UIImgCheckboxInactiveUUID";
  122. mButton = new LLButton("Checkbox control button", btn_rect,
  123. active_false_id, active_true_id, control_name,
  124. &LLCheckBoxCtrl::onButtonPress, this,
  125. LLFontGL::getFontSansSerif());
  126. mButton->setDisabledImages(inactive_false_id, inactive_true_id);
  127. mButton->setHoverGlowStrength(0.35f);
  128. }
  129. mButton->setIsToggle(true);
  130. mButton->setToggleState(initial_value);
  131. mButton->setFollowsLeft();
  132. mButton->setFollowsBottom();
  133. mButton->setCommitOnReturn(false);
  134. addChild(mButton);
  135. }
  136. //static
  137. void LLCheckBoxCtrl::onButtonPress(void* userdata)
  138. {
  139. LLCheckBoxCtrl* self = (LLCheckBoxCtrl*)userdata;
  140. if (!self) return;
  141. if (self->mRadioStyle)
  142. {
  143. self->setValue(true);
  144. }
  145. self->setControlValue(self->getValue());
  146. // *HACK: because buttons do not normally commit
  147. self->onCommit();
  148. if (!self->getIsChrome())
  149. {
  150. self->setFocus(true);
  151. self->onFocusReceived();
  152. }
  153. }
  154. void LLCheckBoxCtrl::onCommit()
  155. {
  156. if (getEnabled())
  157. {
  158. setTentative(false);
  159. LLUICtrl::onCommit();
  160. }
  161. }
  162. void LLCheckBoxCtrl::setEnabled(bool b)
  163. {
  164. LLView::setEnabled(b);
  165. mButton->setEnabled(b);
  166. }
  167. void LLCheckBoxCtrl::clear()
  168. {
  169. setValue(false);
  170. }
  171. void LLCheckBoxCtrl::reshape(S32 width, S32 height, bool called_from_parent)
  172. {
  173. // Stretch or shrink bounding rectangle of label when rebuilding UI at new
  174. // scale
  175. constexpr S32 FUDGE = 10;
  176. S32 text_width = mFont->getWidth(mLabel->getText()) + FUDGE;
  177. S32 text_height = ll_roundp(mFont->getLineHeight());
  178. LLRect label_rect;
  179. label_rect.setOriginAndSize(LLCHECKBOXCTRL_HPAD + LLCHECKBOXCTRL_BTN_SIZE +
  180. LLCHECKBOXCTRL_SPACING,
  181. LLCHECKBOXCTRL_VPAD, text_width, text_height);
  182. mLabel->setRect(label_rect);
  183. LLRect btn_rect;
  184. btn_rect.setOriginAndSize(LLCHECKBOXCTRL_HPAD, LLCHECKBOXCTRL_VPAD,
  185. LLCHECKBOXCTRL_BTN_SIZE +
  186. LLCHECKBOXCTRL_SPACING + text_width,
  187. llmax(text_height, LLCHECKBOXCTRL_BTN_SIZE));
  188. mButton->setRect(btn_rect);
  189. LLUICtrl::reshape(width, height, called_from_parent);
  190. }
  191. void LLCheckBoxCtrl::draw()
  192. {
  193. if (getEnabled())
  194. {
  195. mLabel->setColor(mTextEnabledColor);
  196. }
  197. else
  198. {
  199. mLabel->setColor(mTextDisabledColor);
  200. }
  201. // Draw children
  202. LLUICtrl::draw();
  203. }
  204. //virtual
  205. void LLCheckBoxCtrl::setValue(const LLSD& value)
  206. {
  207. mButton->setValue(value);
  208. }
  209. //virtual
  210. LLSD LLCheckBoxCtrl::getValue() const
  211. {
  212. return mButton->getValue();
  213. }
  214. void LLCheckBoxCtrl::setLabel(const std::string& label)
  215. {
  216. mLabel->setText(label);
  217. reshape(getRect().getWidth(), getRect().getHeight(), false);
  218. }
  219. std::string LLCheckBoxCtrl::getLabel() const
  220. {
  221. return mLabel->getText();
  222. }
  223. bool LLCheckBoxCtrl::setLabelArg(const std::string& key,
  224. const std::string& text)
  225. {
  226. bool res = mLabel->setTextArg(key, text);
  227. reshape(getRect().getWidth(), getRect().getHeight(), false);
  228. return res;
  229. }
  230. //virtual
  231. const std::string& LLCheckBoxCtrl::getControlName() const
  232. {
  233. return mButton->getControlName();
  234. }
  235. //virtual
  236. void LLCheckBoxCtrl::setControlName(const char* control_name, LLView* context)
  237. {
  238. mButton->setControlName(control_name, context);
  239. }
  240. // Returns true if the user has modified this control.
  241. //virtual
  242. bool LLCheckBoxCtrl::isDirty() const
  243. {
  244. return mButton && mSetValue != mButton->getToggleState();
  245. }
  246. // Clear dirty state
  247. //virtual
  248. void LLCheckBoxCtrl::resetDirty()
  249. {
  250. if (mButton)
  251. {
  252. mSetValue = mButton->getToggleState();
  253. }
  254. }
  255. //virtual
  256. const std::string& LLCheckBoxCtrl::getTag() const
  257. {
  258. return LL_CHECK_BOX_CTRL_TAG;
  259. }
  260. //virtual
  261. LLXMLNodePtr LLCheckBoxCtrl::getXML(bool save_children) const
  262. {
  263. LLXMLNodePtr node = LLUICtrl::getXML();
  264. node->setName(LL_CHECK_BOX_CTRL_TAG);
  265. node->createChild("label", true)->setStringValue(mLabel->getText());
  266. node->createChild("initial_value", true)->setBoolValue(mInitialValue);
  267. node->createChild("font", true)->setStringValue(LLFontGL::nameFromFont(mFont));
  268. node->createChild("radio_style", true)->setBoolValue(mRadioStyle);
  269. return node;
  270. }
  271. //static
  272. LLView* LLCheckBoxCtrl::fromXML(LLXMLNodePtr node, LLView* parent,
  273. LLUICtrlFactory* factory)
  274. {
  275. std::string name = "checkbox";
  276. node->getAttributeString("name", name);
  277. std::string label("");
  278. node->getAttributeString("label", label);
  279. LLFontGL* fontp = LLView::selectFont(node);
  280. // if true, draw radio button style icons:
  281. bool radio_style = false;
  282. node->getAttributeBool("radio_style", radio_style);
  283. LLUICtrlCallback callback = NULL;
  284. if (label.empty())
  285. {
  286. label.assign(node->getTextContents());
  287. }
  288. LLRect rect;
  289. createRect(node, rect, parent, LLRect());
  290. LLCheckBoxCtrl* checkbox = new LLCheckBoxCtrl(name, rect, label, fontp,
  291. callback, NULL, false,
  292. radio_style);
  293. bool initial_value = checkbox->getValue().asBoolean();
  294. node->getAttributeBool("initial_value", initial_value);
  295. LLColor4 color = checkbox->mTextEnabledColor;
  296. LLUICtrlFactory::getAttributeColor(node,"text_enabled_color", color);
  297. checkbox->setEnabledColor(color);
  298. color = checkbox->mTextDisabledColor;
  299. LLUICtrlFactory::getAttributeColor(node,"text_disabled_color", color);
  300. checkbox->setDisabledColor(color);
  301. checkbox->setValue(initial_value);
  302. checkbox->initFromXML(node, parent);
  303. return checkbox;
  304. }