/** * @file llfloatereditui.cpp * @author James Cook * @date May 2005 * @brief In-world user interface editor * * $LicenseInfo:firstyear=2005&license=viewergpl$ * * Copyright (c) 2005-2009, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at * http://secondlifegrid.net/programs/open_source/licensing/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, * and agree to abide by those obligations. * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" #include "llfloatereditui.h" #include "llbutton.h" #include "lllineeditor.h" #include "llspinctrl.h" #include "lltextbox.h" void LLFloaterEditUI::navigateHierarchyButtonPressed(void* data) { LLView* view = LLView::sEditingUIView; if (!view) return; LLView* parent = view->getParent(); if (!parent) { return; } const LLView::child_list_t* viewChildren = view->getChildList(); const LLView::child_list_t* parentChildren = parent->getChildList(); std::list::const_iterator itor; std::list::size_type idx; std::list::size_type sidx; for (idx = 0, itor = parentChildren->begin(); itor != parentChildren->end(); ++itor, ++idx) { if (*itor == view) { break; } } switch ((intptr_t)data) { case 0: // up view = view->getParent(); break; case 1: // down view = viewChildren->begin() != viewChildren->end() ? *viewChildren->begin() : NULL; break; case 2: // left { if (idx == 0) { idx = parentChildren->size() - 1; } else { --idx; } if ((S32)idx < 0 || idx >= parentChildren->size()) { break; } for (sidx = 0, itor = parentChildren->begin(); itor != parentChildren->end(); ++itor, ++sidx) { if (sidx == idx) { view = *itor; break; } } break; } case 3: // right { if (idx == parentChildren->size() - 1) { idx = 0; } else { ++idx; } if ((S32)idx < 0 || idx >= parentChildren->size()) { break; } for (sidx = 0, itor = parentChildren->begin(); itor != parentChildren->end(); ++itor, ++sidx) { if (sidx == idx) { view = *itor; break; } } break; } } if (view) { sEditingUIView = view; getInstance()->refresh(); } } LLFloaterEditUI::LLFloaterEditUI(const LLSD&) : LLFloater("ui editor", LLRect(0, 200, 200, 0), "Edit user interface"), mLastView(NULL), mLabelLine(NULL), mWidthSpin(NULL), mHeightSpin(NULL) { LLView::sEditingUI = true; S32 x = HPAD; S32 y = getRect().getHeight() - LINE - LINE - VPAD; constexpr S32 R1 = HPAD + 40; LLButton* button = NULL; LLLineEditor* line = NULL; LLSpinCtrl* spin = NULL; LLTextBox* text = NULL; text = new LLTextBox(std::string("Selected UI Widget:"), LLRect(x, y + 16, x + 100, y)); addChild(text); y -= VPAD + 16; text = new LLTextBox(std::string("Label:"), LLRect(x, y + 16, x + 40, y)); addChild(text); x = R1; line = new LLLineEditor(std::string("label_line"), LLRect(x, y + 20, x + 100, y), LLStringUtil::null, NULL, 254, onCommitLabel, NULL, NULL, this); addChild(line); mLabelLine = line; x = HPAD; y -= VPAD + 20; spin = new LLSpinCtrl(std::string("height_spin"), LLRect(x, y + 20, x + 100, y), std::string("Height:"), LLFontGL::getFontSansSerifSmall(), onCommitHeight, this, 0.f, 2.f, 1000.f, 1.f); spin->setPrecision(0); addChild(spin); mHeightSpin = spin; y -= VPAD + 20; spin = new LLSpinCtrl(std::string("width_spin"), LLRect(x, y + 20, x + 100, y), std::string("Width:"), LLFontGL::getFontSansSerifSmall(), onCommitWidth, this, 0.f, 2.f, 1000.f, 1.f); spin->setPrecision(0); addChild(spin); mWidthSpin = spin; y -= VPAD + 20; text = new LLTextBox(std::string("XML Name:"), LLRect(x, y + 16, x + 60, y)); addChild(text); x+=60; text = new LLTextBox(std::string("xml_name"), LLRect(x, y + 16, x + 100, y)); addChild(text); x-=50; y -= VPAD + 20; x += 40; button = new LLButton(std::string("up"), LLRect(x, y + 16, x + 32, y)); addChild(button); x -= 40; y -= VPAD + 20; button = new LLButton(std::string("<<"), LLRect(x, y + 16, x + 32, y)); addChild(button); x += 40; button = new LLButton(std::string("rfrsh"), LLRect(x, y + 16, x + 32, y)); addChild(button); x += 40; button = new LLButton(std::string(">>"), LLRect(x, y + 16, x + 32, y)); addChild(button); x -= 40; y -= VPAD + 20; button = new LLButton(std::string("dn"), LLRect(x, y + 16, x + 32, y)); addChild(button); childSetAction("up", navigateHierarchyButtonPressed, (void*)0); childSetAction("dn", navigateHierarchyButtonPressed, (void*)1); childSetAction("<<", navigateHierarchyButtonPressed, (void*)2); childSetAction(">>", navigateHierarchyButtonPressed, (void*)3); childSetAction("rfrsh", navigateHierarchyButtonPressed, (void*)4); } //virtual LLFloaterEditUI::~LLFloaterEditUI() { LLView::sEditingUI = false; LLView::sEditingUIView = NULL; } //virtual void LLFloaterEditUI::draw() { refresh(); LLFloater::draw(); } void LLFloaterEditUI::refresh() { LLView* view = LLView::sEditingUIView; // same selection if (view == mLastView) return; // user deselected if (!view) { mLastView = NULL; mLabelLine->setText(LLStringUtil::null); mLabelLine->setEnabled(false); mWidthSpin->set(0.f); mWidthSpin->setEnabled(false); mHeightSpin->set(0.f); mHeightSpin->setEnabled(false); return; } // *HACK: don't allow widgets in this window to be selected LLView* parent = view->getParent(); while (parent) { if (parent == this) { // user selected one of our children, slam them back LLView::sEditingUIView = mLastView; return; } parent = parent->getParent(); } refreshCore(); mLastView = view; } void LLFloaterEditUI::refreshCore() { LLView* view = LLView::sEditingUIView; if (!view) return; LLRect r = view->getRect(); F32 width = (F32)r.getWidth(); F32 height = (F32)r.getHeight(); mWidthSpin->set(width); mHeightSpin->set(height); LLButton* buttonp = dynamic_cast(view); if (buttonp) { refreshButton(view); } else { refreshView(view); } } void LLFloaterEditUI::refreshView(LLView* view) { if (view) { mLabelLine->setEnabled(false); mLabelLine->setText(LLStringUtil::null); childSetText("xml_name", view->getName()); } } void LLFloaterEditUI::refreshButton(LLView* view) { if (view) { LLButton* btn = (LLButton*)view; std::string label = btn->getLabelUnselected(); mLabelLine->setEnabled(true); mLabelLine->setText(label); childSetText("xml_name", view->getName()); } } //static void LLFloaterEditUI::show(void*) { LLFloaterEditUI* self = getInstance(); if (self) { self->center(); self->open(); } } //static bool LLFloaterEditUI::processKeystroke(KEY key, MASK mask) { if (!LLView::sEditingUIView) return false; S32 step = 2; bool handled = false; LLRect r = LLView::sEditingUIView->getRect(); if (mask == MASK_NONE) { if (key == KEY_RIGHT) { r.translate(step, 0); handled = true; } else if (key == KEY_LEFT) { r.translate(-step, 0); handled = true; } else if (key == KEY_UP) { r.translate(0, step); handled = true; } else if (key == KEY_DOWN) { r.translate(0, -step); handled = true; } } else if (mask == MASK_SHIFT) { if (key == KEY_RIGHT) { r.mRight += step; handled = true; } else if (key == KEY_LEFT) { r.mRight -= step; handled = true; } else if (key == KEY_UP) { r.mTop += step; handled = true; } else if (key == KEY_DOWN) { r.mTop -= step; handled = true; } } if (handled) { LLView::sEditingUIView->reshape(r.getWidth(), r.getHeight()); LLView::sEditingUIView->setRect(r); if (findInstance()) { getInstance()->refreshCore(); } } return handled; } //static void LLFloaterEditUI::onCommitLabel(LLUICtrl* ctrl, void* data) { LLView* view = LLView::sEditingUIView; if (!view && ctrl) return; LLLineEditor* line = (LLLineEditor*)ctrl; const std::string& text = line->getText(); LLButton* btn = dynamic_cast(view); if (btn) { btn->setLabelUnselected(text); btn->setLabelSelected(text); } } //static void LLFloaterEditUI::onCommitHeight(LLUICtrl* ctrl, void* data) { LLView* view = LLView::sEditingUIView; if (view && ctrl) { LLSpinCtrl* spin = (LLSpinCtrl*)ctrl; F32 height = spin->get(); LLRect r = view->getRect(); r.mTop = r.mBottom + (S32)height; view->reshape(r.getWidth(), r.getHeight()); view->setRect(r); } } //static void LLFloaterEditUI::onCommitWidth(LLUICtrl* ctrl, void* data) { LLView* view = LLView::sEditingUIView; if (view && ctrl) { LLSpinCtrl* spin = (LLSpinCtrl*)ctrl; F32 width = spin->get(); LLRect r = view->getRect(); r.mRight = r.mLeft + (S32)width; view->reshape(r.getWidth(), r.getHeight()); view->setRect(r); } }