From fde724cdc4fa3d09cc7200c3305bd0e2a9b6402b Mon Sep 17 00:00:00 2001 From: ZiRee Date: Mon, 2 May 2011 18:14:44 +0200 Subject: [PATCH] Added pie menu files --- indra/newview/piemenu.cpp | 495 ++++++++++++++++++ indra/newview/piemenu.h | 110 ++++ indra/newview/pieseparator.cpp | 43 ++ indra/newview/pieseparator.h | 49 ++ indra/newview/pieslice.cpp | 121 +++++ indra/newview/pieslice.h | 93 ++++ .../xui/en/menu_pie_attachment_other.xml | 153 ++++++ .../xui/en/menu_pie_attachment_self.xml | 100 ++++ .../default/xui/en/menu_pie_avatar_other.xml | 153 ++++++ .../default/xui/en/menu_pie_avatar_self.xml | 256 +++++++++ .../skins/default/xui/en/menu_pie_land.xml | 61 +++ .../skins/default/xui/en/menu_pie_object.xml | 193 +++++++ 12 files changed, 1827 insertions(+) create mode 100644 indra/newview/piemenu.cpp create mode 100644 indra/newview/piemenu.h create mode 100644 indra/newview/pieseparator.cpp create mode 100644 indra/newview/pieseparator.h create mode 100644 indra/newview/pieslice.cpp create mode 100644 indra/newview/pieslice.h create mode 100644 indra/newview/skins/default/xui/en/menu_pie_attachment_other.xml create mode 100644 indra/newview/skins/default/xui/en/menu_pie_attachment_self.xml create mode 100644 indra/newview/skins/default/xui/en/menu_pie_avatar_other.xml create mode 100644 indra/newview/skins/default/xui/en/menu_pie_avatar_self.xml create mode 100644 indra/newview/skins/default/xui/en/menu_pie_land.xml create mode 100644 indra/newview/skins/default/xui/en/menu_pie_object.xml diff --git a/indra/newview/piemenu.cpp b/indra/newview/piemenu.cpp new file mode 100644 index 0000000000..77eb2c8a3c --- /dev/null +++ b/indra/newview/piemenu.cpp @@ -0,0 +1,495 @@ +/** + * @file piemenu.cpp + * @brief Pie menu class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2011, Zi Ree @ Second Life + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "piemenu.h" +#include "pieslice.h" +#include "pieseparator.h" +#include "llviewerwindow.h" +#include "v2math.h" + +// copied from LLMenuGL - Remove these lines over there when finished +const S32 PIE_INNER_SIZE=20; // radius of the inner pie circle +const F32 PIE_POPUP_FACTOR=1.7; // pie menu size factor on popup +const F32 PIE_POPUP_TIME=0.25; // time to shrink from popup size to regular size +const S32 PIE_OUTER_SIZE=96; // radius of the outer pie circle + +// register the pie menu globally as child widget +static LLDefaultChildRegistry::Register r1("pie_menu"); + +// register all possible child widgets a pie menu can have +static PieChildRegistry::Register pie_r1("pie_menu"); +static PieChildRegistry::Register pie_r2("pie_slice"); +static PieChildRegistry::Register pie_r3("pie_separator"); + +#define PIE_POPUP_EFFECT 1 // debug +#define PIE_DRAW_BOUNDING_BOX 0 // debug + +PieMenu::PieMenu(const LLContextMenu::Params& p) : + LLContextMenu(p) +{ + lldebugs << "PieMenu::PieMenu()" << llendl; + // radius, so we need this *2 + reshape(PIE_OUTER_SIZE*2,PIE_OUTER_SIZE*2,FALSE); + // set up the font for the menu + mFont=LLFontGL::getFont(LLFontDescriptor("SansSerif","Pie",LLFontGL::NORMAL)); + if(!mFont) + { + llwarns << "Could not find font size for Pie menu, falling back to Small font." << llendl; + mFont=LLFontGL::getFont(LLFontDescriptor("SansSerif","Small",LLFontGL::NORMAL)); + } + // set slices pointer to our own slices + mSlices=&mMySlices; + // this will be the first click on the menu + mFirstClick=TRUE; + + // clean initialisation + mSlice=0; +} + +bool PieMenu::addChild(LLView* child,S32 tab_group) +{ + // don't add invalid slices + if(!child) + return FALSE; + + // add a new slice to the menu + mSlices->push_back(child); + + // tell the view that our menu has changed and reshape it back to correct size + LLUICtrl::addChild(child); + reshape(PIE_OUTER_SIZE*2,PIE_OUTER_SIZE*2,FALSE); + return TRUE; +} + +void PieMenu::removeChild(LLView* child) +{ + // remove a slice from the menu + slice_list_t::iterator found_it=std::find(mSlices->begin(),mSlices->end(),child); + if(found_it!=mSlices->end()) + { + mSlices->erase(found_it); + } + + // tell the view that our menu has changed and reshape it back to correct size + LLUICtrl::removeChild(child); + reshape(PIE_OUTER_SIZE*2,PIE_OUTER_SIZE*2,FALSE); +} + +BOOL PieMenu::handleHover(S32 x,S32 y,MASK mask) +{ + // do nothing + return TRUE; +} + +void PieMenu::show(S32 x,S32 y) +{ + // if the menu is already there, do nothing + if(getVisible()) + return; + + // play a sound + make_ui_sound("UISndPieMenuAppear"); + + lldebugs << "PieMenu::show(): " << x << " " << y << llendl; + + // make sure the menu is always the correct size + reshape(PIE_OUTER_SIZE*2,PIE_OUTER_SIZE*2,FALSE); + + // remember our center point + mCenterX=x; + mCenterY=y; + + // get the 3D view rectangle + LLRect screen=LLMenuGL::sMenuContainer->getMenuRect(); + + // check if the pie menu is out of bounds and move it accordingly + if(x-PIE_OUTER_SIZE<0) + x=PIE_OUTER_SIZE; + else if(x+PIE_OUTER_SIZE>screen.getWidth()) + x=screen.getWidth()-PIE_OUTER_SIZE; + + if(y-PIE_OUTER_SIZEscreen.getHeight()) + y=screen.getHeight()-PIE_OUTER_SIZE+screen.mBottom; + + // move the mouse pointer into the center of the menu + LLUI::setMousePositionLocal(getParent(),x,y); + // set our drawing origin to the center of the menu + setOrigin(x-PIE_OUTER_SIZE,y-PIE_OUTER_SIZE); + // grab mouse control + gFocusMgr.setMouseCapture(this); + + // this was the first click for the menu + mFirstClick=TRUE; + // set up the slices pointer to the menu's own slices + mSlices=&mMySlices; + + // cleanup + mSlice=0; + mOldSlice=0; + + // draw the menu on screen + setVisible(TRUE); + LLView::setVisible(TRUE); +} + +void PieMenu::hide() +{ + // if the menu is already hidden, do nothing + if(!getVisible()) + return; + + // make a sound when hiding + make_ui_sound("UISndPieMenuHide"); + + llwarns << "Clearing selections" << llendl; + + mSlices=&mMySlices; +#if PIE_POPUP_EFFECT + // safety in case the timer was still running + mPopupTimer.stop(); +#endif + LLView::setVisible(FALSE); +} + +void PieMenu::setVisible(BOOL visible) +{ + // hide the menu if needed + if(!visible) + { + hide(); + // clear all menus and temporary selections + sMenuContainer->hideMenus(); + } +} + +void PieMenu::draw( void ) +{ + // save the current OpenGL drawing matrix so we can freely modify it + gGL.pushMatrix(); + + // save the widget's rectangle for later use + LLRect r=getRect(); + + // initialize pie scale factor for popup effect + F32 factor=1.0; + +#if PIE_POPUP_EFFECT + // set the popup size if this was the first click on the menu + if(mFirstClick) + { + factor=PIE_POPUP_FACTOR; + } + // otherwise check if the popup timer is still running + else if(mPopupTimer.getStarted()) + { + // if the timer ran past the popup time, stop the timer and set the size to 1.0 + F32 elapsedTime=mPopupTimer.getElapsedTimeF32(); + if(elapsedTime>PIE_POPUP_TIME) + { + factor=1.0; + mPopupTimer.stop(); + } + // otherwise calculate the size factor to make the menu shrink over time + else + { + factor=PIE_POPUP_FACTOR-(PIE_POPUP_FACTOR-1.0)*elapsedTime/PIE_POPUP_TIME; + } +// setRect(r); // obsolete? + } +#endif + +#if PIE_DRAW_BOUNDING_BOX + // draw a bounding box around the menu for debugging purposes + gl_rect_2d(0,r.getHeight(),r.getWidth(),0,LLColor4(1,1,1,1),FALSE); +#endif + + // set up pie menu colors + LLColor4 lineColor=LLUIColorTable::instance().getColor("PieMenuLineColor"); + LLColor4 selectedColor=LLUIColorTable::instance().getColor("PieMenuSelectedColor"); + LLColor4 textColor=LLUIColorTable::instance().getColor("PieMenuTextColor"); + LLColor4 bgColor=LLUIColorTable::instance().getColor("PieMenuBgColor"); + LLColor4 borderColor=bgColor % 0.3; + // on first click, make the menu fade out to indicate "borderless" operation + if(mFirstClick) + borderColor%=0.0; + + // get the current mouse pointer position + S32 mouseX=gViewerWindow->getCurrentMouseX(); + S32 mouseY=gViewerWindow->getCurrentMouseY(); + + // initially, the current segment is marked as invalid + S32 currentSegment=-1; + + // find the center of the pie menu + LLVector2 centerVector(r.getCenterX(),r.getCenterY()); + // calculate the distance of the mouse from the center + LLVector2 mouseVector(mouseX,mouseY); + LLVector2 distanceVector(mouseVector-centerVector); + S32 distance=distanceVector.length(); + // check if our mouse pointer is within the pie slice area + if(distance>PIE_INNER_SIZE && (distance<(PIE_OUTER_SIZE*factor) || mFirstClick)) + { + // get the angle of the mouse pointer from the center in radians + F32 angle=acos(distanceVector.mV[0]/distance); + // if the mouse is below the middle of the pie, reverse the angle + if(distanceVector.mV[1]<0) + angle=F_PI*2-angle; + // rotate the angle slightly so the slices' centers are aligned correctly + angle+=F_PI/8; + + // calculate slice number from the angle + currentSegment=(S32) (8.0*angle/(F_PI*2.0)) % 8; + } + + // move origin point to the center of our rectangle + gGL.translatef(r.getWidth()/2,r.getHeight()/2,0.0); + + // draw the general pie background + gl_washer_2d(PIE_OUTER_SIZE*factor,PIE_INNER_SIZE,32,bgColor,borderColor); + + // set up an item list iterator to point at the beginning of the item list + slice_list_t::iterator cur_item_iter; + cur_item_iter=mSlices->begin(); + + // clear current slice pointer + mSlice=0; + // current slice number is 0 + S32 num=0; + BOOL wasAutohide=FALSE; + do + { + // standard item text color + LLColor4 itemColor=textColor; + + // clear the label and set up the starting angle to draw in + std::string label(""); + F32 segmentStart=F_PI/4.0*(F32) num-F_PI/8.0; + + // iterate through the list of slices + if(cur_item_iter!=mSlices->end()) + { + // get current slice item + LLView* item=(*cur_item_iter); + + // check if this is a submenu or a normal click slice + PieSlice* currentSlice=dynamic_cast(item); + PieMenu* currentSubmenu=dynamic_cast(item); + // advance internally to the next slice item + cur_item_iter++; + + // in case it is regular click slice + if(currentSlice) + { + // get the slice label and tell the slice to check if it's supposed to be visible + label=currentSlice->getLabel(); + currentSlice->updateVisible(); + // skip it if it's not visible + if(!currentSlice->getVisible()) + { + lldebugs << label << " is not visible" << llendl; + continue; + } + // check if the current slice is part of an autohide chain + if(currentSlice->getAutohide()) + { + // if the previous item already won the autohide, skip this item + if(wasAutohide) + continue; + // look at the next item in the pie + LLView* lookAhead=(*cur_item_iter); + // check if this is a normal click slice + PieSlice* lookSlice=dynamic_cast(lookAhead); + if(lookSlice) + { + // if the next item is part of the autohide chain as well ... + if(lookSlice->getAutohide()) + { + // ... it's visible and it's enabled, skip the current one. + // the first visible and enabled item in autohide chains wins + // this is useful for Sit/Stand toggles + lookSlice->updateEnabled(); + lookSlice->updateVisible(); + if(lookSlice->getVisible() && lookSlice->getEnabled()) + continue; + // this item won the autohide contest + wasAutohide=TRUE; + } + } + } + else + // reset autohide chain + wasAutohide=FALSE; + // check if the slice is currently enabled + currentSlice->updateEnabled(); + if(!currentSlice->getEnabled()) + { + lldebugs << label << " is disabled" << llendl; + // fade the item color alpha to mark the item as disabled + itemColor%=0.3; + } + } + // if it's a submenu just get the label + else if(currentSubmenu) + label=currentSubmenu->getLabel(); + + // if it's a slice or submenu, the mouse pointer is over the same segment as our counter and the item is enabled + if((currentSlice || currentSubmenu) && (currentSegment==num) && item->getEnabled()) + { + // memorize the currently highlighted slice for later + mSlice=item; + // if we highlighted a different slice than before, we must play a sound + if(mOldSlice!=mSlice) + { + // get the appropriate UI sound and play it + char soundNum='0'+num; + std::string soundName="UISndPieMenuSliceHighlight"; + soundName+=soundNum; + + make_ui_sound(soundName.c_str()); + // remember which slice we highlighted last, so we only play the sound once + mOldSlice=mSlice; + } + + // draw the currently highlighted pie slice + gl_washer_segment_2d(PIE_OUTER_SIZE*factor,PIE_INNER_SIZE,segmentStart+0.02,segmentStart+F_PI/4.0-0.02,4,selectedColor,borderColor); + } + } + // draw the divider line for this slice + gl_washer_segment_2d(PIE_OUTER_SIZE*factor,PIE_INNER_SIZE,segmentStart-0.02,segmentStart+0.02,4,lineColor,borderColor); + + // draw the slice labels in a slightly elliptic shape around the center + mFont->renderUTF8(label, + 0, + (S32) (cos(segmentStart+F_PI/8.0)*PIE_OUTER_SIZE/1.5), + (S32) (sin(segmentStart+F_PI/8.0)*PIE_OUTER_SIZE/1.3), + itemColor, + LLFontGL::HCENTER, + LLFontGL::VCENTER, + LLFontGL::NORMAL); + // next slice + num++; + } + while(num<8); // do this until the menu is full + + // draw inner and outer circle, outer only if it was not the first click + if(!mFirstClick) + gl_washer_2d(PIE_OUTER_SIZE*factor,PIE_OUTER_SIZE*factor-2,32,lineColor,borderColor); + gl_washer_2d(PIE_INNER_SIZE+1,PIE_INNER_SIZE-1,16,borderColor,lineColor); + + // restore OpenGL drawing matrix + gGL.popMatrix(); + + // give control back to the UI library + LLView::draw(); +} + +BOOL PieMenu::appendContextSubMenu(PieMenu* menu) +{ + lldebugs << "PieMenu::appendContextSubMenu()" << llendl; + if(!menu) + return FALSE; + + lldebugs << "PieMenu::appendContextSubMenu() appending " << menu->getLabel() << " to " << getLabel() << llendl; + + // add the submenu to the list of items + mSlices->push_back(menu); + // tell the view that our menu has changed + LLUICtrl::addChild(menu); + return TRUE; +} + +BOOL PieMenu::handleMouseUp(S32 x,S32 y,MASK mask) +{ + // left and right mouse buttons both do the same thing currently + return handleMouseButtonUp(x,y,mask); +} + +BOOL PieMenu::handleRightMouseUp(S32 x,S32 y,MASK mask) +{ + // left and right mouse buttons both do the same thing currently + return handleMouseButtonUp(x,y,mask); +} + +// left and right mouse buttons both do the same thing currently +BOOL PieMenu::handleMouseButtonUp(S32 x,S32 y,MASK mask) +{ + // if this was the first click and no slice is highlighted (no borderless click), start the popup timer + if(mFirstClick && !mSlice) + { + mFirstClick=FALSE; +#if PIE_POPUP_EFFECT + mPopupTimer.start(); +#endif + } + else + { + // default to invisible + BOOL visible=FALSE; + + // get the current selected slice and check if this is a regular click slice + PieSlice* currentSlice=dynamic_cast(mSlice); + if(currentSlice) + { + // if so, click it and make a sound + make_ui_sound("UISndClickRelease"); + currentSlice->onCommit(); + } + else + { + // check if this was a submenu + PieMenu* currentSubmenu=dynamic_cast(mSlice); + if(currentSubmenu) + { + // if so, remember we clicked the menu already at least once + mFirstClick=FALSE; + // swap out the list of items for the ones in the submenu + mSlices=¤tSubmenu->mMySlices; + // the menu stays visible + visible=TRUE; +#if PIE_POPUP_EFFECT + // restart the popup timer + mPopupTimer.reset(); + mPopupTimer.start(); +#endif + // make a sound + make_ui_sound("UISndPieMenuAppear"); + } + } + // show or hide the menu, as needed + setVisible(visible); + } + // release mouse capture after the first click if we still have it grabbed + if(hasMouseCapture()) + gFocusMgr.setMouseCapture(NULL); + + // give control back to the system + return LLView::handleMouseUp(x,y,mask); +} diff --git a/indra/newview/piemenu.h b/indra/newview/piemenu.h new file mode 100644 index 0000000000..c480c9be9d --- /dev/null +++ b/indra/newview/piemenu.h @@ -0,0 +1,110 @@ +/** + * @file piemenu.h + * @brief Pie menu class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2011, Zi Ree @ Second Life + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef PIEMENU_H +#define PIEMENU_H + +#include "llmenugl.h" +#include "llframetimer.h" + +// PieChildRegistry contains a list of allowed child types for the XUI definition +struct PieChildRegistry : public LLChildRegistry +{}; + +class PieMenu : public LLContextMenu +{ + public: + // parameter block for the XUI factory + struct Params : public LLInitParam::Block + { + Optional name; + + Params() + { + visible=false; + } + }; + + // PieChildRegistry contains a list of allowed child types for the XUI definition + typedef PieChildRegistry child_registry_t; + + PieMenu(const LLContextMenu::Params& p); + + /*virtual*/ void setVisible(BOOL visible); + + // adding and removing "child" slices to the pie + /*virtual*/ bool addChild(LLView* child,S32 tab_group=0); + /*virtual*/ void removeChild(LLView* child); + + /*virtual*/ BOOL handleHover(S32 x,S32 y,MASK mask); + /*virtual*/ BOOL handleMouseUp(S32 x,S32 y,MASK mask); + /*virtual*/ BOOL handleRightMouseUp(S32 x,S32 y,MASK mask); + + // does all the hard work of bringing the menu on the screen + void draw(); + + // showing/hiding the menu + void show(S32 x,S32 y); + void hide(); + + // our item list type definition + typedef std::list slice_list_t; + // the actual item list + slice_list_t mMySlices; + // pointer to the currently used list + slice_list_t* mSlices; + + // appends a sub pie menu to the current pie + BOOL appendContextSubMenu(PieMenu* menu); + + // we never rearrange our menu + void needsArrange() {}; + // arranging does nothing + virtual void arrange( void ) {}; + // arranging does nothing + void arrangeAndClear( void ) {}; + + protected: + // general mouse button handling + BOOL handleMouseButtonUp(S32 x,S32 y,MASK mask); + // font used for the menu + const LLFontGL* mFont; + // currently highlighted item, must be tested if it's a slice or submenu + LLView* mSlice; + // used to play UI sounds only once on hover slice change, do not dereference! + LLView* mOldSlice; + + // timer for visual popup effect + LLFrameTimer mPopupTimer; + // center position, used for popup effect + S32 mCenterX; + S32 mCenterY; + // this is TRUE when the first mouseclick came to display the menu, used for borderless menu + BOOL mFirstClick; +}; + +#endif // PIEMENU_H diff --git a/indra/newview/pieseparator.cpp b/indra/newview/pieseparator.cpp new file mode 100644 index 0000000000..22a6d9d554 --- /dev/null +++ b/indra/newview/pieseparator.cpp @@ -0,0 +1,43 @@ +/** + * @file pieseparator.cpp + * @brief Pie menu separator slice class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2011, Zi Ree @ Second Life + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "pieseparator.h" + +// simple separator item, does nothing +PieSeparator::PieSeparator(const PieSeparator::Params& p) : + LLUICtrl(p) +{ + lldebugs << "PieSeparator::PieSeparator()" << llendl; +} + +// pick up parameters from the XUI definition +PieSeparator::Params::Params() +: name("name","") +{ +} diff --git a/indra/newview/pieseparator.h b/indra/newview/pieseparator.h new file mode 100644 index 0000000000..16e9237e4a --- /dev/null +++ b/indra/newview/pieseparator.h @@ -0,0 +1,49 @@ +/** + * @file pieseparator.h + * @brief Pie menu separator slice class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2011, Zi Ree @ Second Life + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef PIESEPARATOR_H +#define PIESEPARATOR_H + +#include "llinitparam.h" +#include "lluictrl.h" + +// a pie slice that does nothing and is not highlighting by mouse hover +class PieSeparator : public LLUICtrl +{ + public: + // parameter block for the XUI factory + struct Params : public LLInitParam::Block + { + Optional name; + + Params(); + }; + + PieSeparator(const Params& p); +}; + +#endif // PIESEPARATOR_H diff --git a/indra/newview/pieslice.cpp b/indra/newview/pieslice.cpp new file mode 100644 index 0000000000..0e1478381e --- /dev/null +++ b/indra/newview/pieslice.cpp @@ -0,0 +1,121 @@ +/** + * @file pieslice.cpp + * @brief Pie menu slice class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2011, Zi Ree @ Second Life + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "pieslice.h" + +// create a new slice and memorize the XUI parameters +PieSlice::PieSlice(const PieSlice::Params& p) : + LLUICtrl(p), + mLabel(p.label), + mAutohide(p.autohide) +{ + + lldebugs << "PieSlice::PieSlice(): " << mLabel << " " << mAutohide << llendl; +} + +// pick up parameters from the XUI definition +PieSlice::Params::Params() : + on_click("on_click"), + on_visible("on_visible"), + on_enable("on_enable"), + autohide("autohide",FALSE) +{ +} + +// initialize parameters +void PieSlice::initFromParams(const Params& p) +{ + // add a callback if on_click is provided + if(p.on_click.isProvided()) + { + setCommitCallback(initCommitCallback(p.on_click)); + } + // add a callback if on_visible is provided + if (p.on_visible.isProvided()) + { + mVisibleSignal.connect(initEnableCallback(p.on_visible)); + } + // add a callback if on_enable is provided + if (p.on_enable.isProvided()) + { + setEnableCallback(initEnableCallback(p.on_enable)); + // Set the enabled control variable (for backwards compatability) + if (p.on_enable.control_name.isProvided() && !p.on_enable.control_name().empty()) + { + LLControlVariable* control = findControl(p.on_enable.control_name()); + if (control) + { + setEnabledControlVariable(control); + } + } + } + + LLUICtrl::initFromParams(p); +} + +// call this to make the menu update its "enabled" status +void PieSlice::updateEnabled() +{ + if(mEnableSignal.num_slots()>0) + { + bool enabled=mEnableSignal(this,LLSD()); + if(mEnabledControlVariable) + { + if(!enabled) + { + // callback overrides control variable; this will call setEnabled() + mEnabledControlVariable->set(false); + } + } + else + { + setEnabled(enabled); + } + } +} + +// call this to make the menu update its "visible" status +void PieSlice::updateVisible() +{ + if(mVisibleSignal.num_slots()>0) + { + bool visible=mVisibleSignal(this,LLSD()); + setVisible(visible); + } +} + +// accessor +std::string PieSlice::getLabel() +{ + return mLabel; +} + +// accessor +BOOL PieSlice::getAutohide() +{ + return mAutohide; +} diff --git a/indra/newview/pieslice.h b/indra/newview/pieslice.h new file mode 100644 index 0000000000..72fb8e8bd4 --- /dev/null +++ b/indra/newview/pieslice.h @@ -0,0 +1,93 @@ +/** + * @file pieslice.h + * @brief Pie menu slice class + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2011, Zi Ree @ Second Life + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef PIESLICE_H +#define PIESLICE_H + +#include + +#include "llinitparam.h" +#include "lluictrl.h" + +// A slice in the pie. Does nothing by itself, just stores the function and +// parameter to be execued when the user clicks on this item +class PieSlice : public LLUICtrl +{ + public: + // parameter block for the XUI factory + struct Params : public LLInitParam::Block + { + // register an on_click callback we can use in the XML definition + Optional on_click; + // register an on_enable callback we can use in the XML definition + Optional on_enable; + // register an on_visible callback which does the same as on_enable + Optional on_visible; + + // autohide feature to hide a disabled pie slice (NOTE: is not ) + Optional autohide; + // parameter "constructor" function to pick up the parameters from the XUI system + Params(); + }; + + PieSlice(const Params& p); + + // call these before checking on enabled/visible status + void updateEnabled(); + void updateVisible(); + + // initialisation, taking care of optional parameters and setting up the callback + void initFromParams(const Params& p); + + // accessor to expose the label to the outside + std::string getLabel(); + // accessor to expose the autohide feature + BOOL getAutohide(); + + // callback connection for the onCommit method to launch the specified function + boost::signals2::connection setClickCallback(const commit_signal_t::slot_type& cb) + { + return setCommitCallback(cb); + } + + // callback connection for the onEnable method to enable/disable menu items + boost::signals2::connection setEnableCallback( const enable_signal_t::slot_type& cb ) + { + return mEnableSignal.connect(cb); + } + + protected: + // accessor store + std::string mLabel; + BOOL mAutohide; + + private: + enable_signal_t mEnableSignal; + enable_signal_t mVisibleSignal; +}; + +#endif // PIESLICE_H diff --git a/indra/newview/skins/default/xui/en/menu_pie_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_pie_attachment_other.xml new file mode 100644 index 0000000000..500202384c --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_pie_attachment_other.xml @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_pie_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_pie_attachment_self.xml new file mode 100644 index 0000000000..4ddeef58fb --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_pie_attachment_self.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_pie_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_pie_avatar_other.xml new file mode 100644 index 0000000000..e4032bd546 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_pie_avatar_other.xml @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_pie_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_pie_avatar_self.xml new file mode 100644 index 0000000000..fc2ecfcbca --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_pie_avatar_self.xml @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_pie_land.xml b/indra/newview/skins/default/xui/en/menu_pie_land.xml new file mode 100644 index 0000000000..3ea967c02a --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_pie_land.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_pie_object.xml b/indra/newview/skins/default/xui/en/menu_pie_object.xml new file mode 100644 index 0000000000..7c44aa0a5e --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_pie_object.xml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +