Files
SingularityViewer/indra/llui/llfloater.h
Inusaito Sayori e5f2d5f76e Fix Save Preview As... for textures, now save as any type we can encode to!
Removes the previous method and condenses the menu entries back into one.
 - Translations have been updated except for German, German will need to update the translation for "Save Preview As..." since the name hasn't changed.
Adds FFSAVE_IMAGE to the filepicker enums
Crossplatformity:
 - The Windows version works nicely
 - The Linux version may not work or even compile but it should..
 - The Mac version hasn't been added, instead it will default to accept any(all filter), should the provided file extension be invalid a notification will display.
2013-09-14 21:21:36 -04:00

434 lines
14 KiB
C++

/**
* @file llfloater.h
* @brief LLFloater base class
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-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$
*/
// Floating "windows" within the GL display, like the inventory floater,
// mini-map floater, etc.
#ifndef LL_FLOATER_H
#define LL_FLOATER_H
#include "llpanel.h"
#include "lluuid.h"
#include "lltabcontainer.h"
#include "llnotificationcontext.h"
#include "llnotificationptr.h"
#include <set>
class LLDragHandle;
class LLResizeHandle;
class LLResizeBar;
class LLButton;
class LLMultiFloater;
class LLFloater;
const S32 LLFLOATER_VPAD = 6;
const S32 LLFLOATER_HPAD = 6;
const S32 LLFLOATER_CLOSE_BOX_SIZE = 16;
const S32 LLFLOATER_HEADER_SIZE = 18;
const BOOL RESIZE_YES = TRUE;
const BOOL RESIZE_NO = FALSE;
const S32 DEFAULT_MIN_WIDTH = 100;
const S32 DEFAULT_MIN_HEIGHT = 100;
const BOOL DRAG_ON_TOP = FALSE;
const BOOL DRAG_ON_LEFT = TRUE;
const BOOL MINIMIZE_YES = TRUE;
const BOOL MINIMIZE_NO = FALSE;
const BOOL CLOSE_YES = TRUE;
const BOOL CLOSE_NO = FALSE;
const BOOL ADJUST_VERTICAL_YES = TRUE;
const BOOL ADJUST_VERTICAL_NO = FALSE;
// associates a given notification instance with a particular floater
class LLFloaterNotificationContext :
public LLNotificationContext
{
public:
LLFloaterNotificationContext(LLHandle<LLFloater> floater_handle) :
mFloaterHandle(floater_handle)
{}
LLFloater* getFloater() { return mFloaterHandle.get(); }
private:
LLHandle<LLFloater> mFloaterHandle;
};
class LLFloater : public LLPanel
{
friend class LLFloaterView;
friend class LLMultiFloater;
public:
enum EFloaterButtons
{
BUTTON_CLOSE,
BUTTON_RESTORE,
BUTTON_MINIMIZE,
BUTTON_TEAR_OFF,
BUTTON_EDIT,
BUTTON_COUNT
};
LLFloater();
LLFloater(const std::string& name); //simple constructor for data-driven initialization
LLFloater( const std::string& name, const LLRect& rect, const std::string& title,
BOOL resizable = FALSE,
S32 min_width = DEFAULT_MIN_WIDTH,
S32 min_height = DEFAULT_MIN_HEIGHT,
BOOL drag_on_left = FALSE,
BOOL minimizable = TRUE,
BOOL close_btn = TRUE,
BOOL bordered = BORDER_NO);
LLFloater( const std::string& name, const std::string& rect_control, const std::string& title,
BOOL resizable = FALSE,
S32 min_width = DEFAULT_MIN_WIDTH,
S32 min_height = DEFAULT_MIN_HEIGHT,
BOOL drag_on_left = FALSE,
BOOL minimizable = TRUE,
BOOL close_btn = TRUE,
BOOL bordered = BORDER_NO);
virtual ~LLFloater();
virtual LLXMLNodePtr getXML(bool save_children = true) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
void initFloaterXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory, BOOL open = TRUE);
/*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
/*virtual*/ BOOL canSnapTo(const LLView* other_view);
/*virtual*/ void setSnappedTo(const LLView* snap_view);
/*virtual*/ void setFocus( BOOL b );
/*virtual*/ void setIsChrome(BOOL is_chrome);
// Can be called multiple times to reset floater parameters.
// Deletes all children of the floater.
virtual void initFloater(const std::string& title, BOOL resizable,
S32 min_width, S32 min_height, BOOL drag_on_left,
BOOL minimizable, BOOL close_btn);
virtual void open(); /* Flawfinder: ignore */
// If allowed, close the floater cleanly, releasing focus.
// app_quitting is passed to onClose() below.
virtual void close(bool app_quitting = false);
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
// Release keyboard and mouse focus
void releaseFocus();
// moves to center of gFloaterView
void center();
// applies rectangle stored in mRectControl, if any
void applyRectControl();
LLMultiFloater* getHost() { return (LLMultiFloater*)mHostHandle.get(); }
void applyTitle();
const std::string& getCurrentTitle() const;
void setTitle( const std::string& title);
std::string getTitle();
void setShortTitle( const std::string& short_title );
std::string getShortTitle();
void setTitleVisible(bool visible);
virtual void setMinimized(BOOL b);
void moveResizeHandlesToFront();
void addDependentFloater(LLFloater* dependent, BOOL reposition = TRUE);
void addDependentFloater(LLHandle<LLFloater> dependent_handle, BOOL reposition = TRUE);
LLFloater* getDependee() { return (LLFloater*)mDependeeHandle.get(); }
void removeDependentFloater(LLFloater* dependent);
BOOL isMinimized() { return mMinimized; }
BOOL isFrontmost();
BOOL isDependent() { return !mDependeeHandle.isDead(); }
void setCanMinimize(BOOL can_minimize);
void setCanClose(BOOL can_close);
void setCanTearOff(BOOL can_tear_off);
virtual void setCanResize(BOOL can_resize);
void setCanDrag(BOOL can_drag);
void setHost(LLMultiFloater* host);
BOOL isResizable() const { return mResizable; }
void setResizeLimits( S32 min_width, S32 min_height );
void getResizeLimits( S32* min_width, S32* min_height ) { *min_width = mMinWidth; *min_height = mMinHeight; }
bool isMinimizeable() const{ return mButtonsEnabled[BUTTON_MINIMIZE]; }
// Does this window have a close button, NOT can we close it right now.
bool isCloseable() const{ return (mButtonsEnabled[BUTTON_CLOSE]); }
bool isDragOnLeft() const{ return mDragOnLeft; }
S32 getMinWidth() const{ return mMinWidth; }
S32 getMinHeight() const{ return mMinHeight; }
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
virtual void draw();
virtual void onOpen() {}
// Call destroy() to free memory, or setVisible(FALSE) to keep it
// If app_quitting, you might not want to save your visibility.
// Defaults to destroy().
virtual void onClose(bool app_quitting) { destroy(); }
// This cannot be "const" until all derived floater canClose()
// methods are const as well. JC
virtual BOOL canClose() { return TRUE; }
virtual void setVisible(BOOL visible);
void setFrontmost(BOOL take_focus = TRUE);
// Defaults to false.
virtual BOOL canSaveAs() const { return FALSE; }
virtual void saveAs() {}
void setSnapTarget(LLHandle<LLFloater> handle) { mSnappedTo = handle; }
void clearSnapTarget() { mSnappedTo.markDead(); }
LLHandle<LLFloater> getSnapTarget() const { return mSnappedTo; }
LLHandle<LLFloater> getHandle() const { return getDerivedHandle<LLFloater>(); }
// Return a closeable floater, if any, given the current focus.
static LLFloater* getClosableFloaterFromFocus();
// Close the floater returned by getClosableFloaterFromFocus() and
// handle refocusing.
static void closeFocusedFloater();
LLNotificationPtr addContextualNotification(const std::string& name, const LLSD& substitutions = LLSD());
void onClickClose();
void onClickMinimize();
void onClickTearOff();
void onClickEdit();
static void setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; }
static void setEditModeEnabled(BOOL enable);
static BOOL getEditModeEnabled() { return sEditModeEnabled; }
static LLMultiFloater* getFloaterHost() {return sHostp; }
void enableResizeCtrls(bool enable, bool width = true, bool height = true);
protected:
virtual void bringToFront(S32 x, S32 y);
virtual void setVisibleAndFrontmost(BOOL take_focus=TRUE);
void setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized
const LLRect& getExpandedRect() const { return mExpandedRect; }
void setAutoFocus(BOOL focus) { mAutoFocus = focus; } // whether to automatically take focus when opened
LLDragHandle* getDragHandle() const { return mDragHandle; }
void destroy() { die(); } // Don't call this directly. You probably want to call close(). JC
private:
void setForeground(BOOL b); // called only by floaterview
void cleanupHandles(); // remove handles to dead floaters
void createMinimizeButton();
void updateButtons();
void buildButtons();
BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index);
void addResizeCtrls();
void layoutResizeCtrls();
LLRect mExpandedRect;
LLDragHandle* mDragHandle;
LLResizeBar* mResizeBar[4];
LLResizeHandle* mResizeHandle[4];
LLButton *mMinimizeButton;
BOOL mCanTearOff;
BOOL mMinimized;
BOOL mForeground;
LLHandle<LLFloater> mDependeeHandle;
std::string mTitle;
std::string mShortTitle;
BOOL mFirstLook; // TRUE if the _next_ time this floater is visible will be the first time in the session that it is visible.
BOOL mResizable;
S32 mMinWidth;
S32 mMinHeight;
BOOL mEditing;
typedef std::set<LLHandle<LLFloater> > handle_set_t;
typedef std::set<LLHandle<LLFloater> >::iterator handle_set_iter_t;
handle_set_t mDependents;
bool mDragOnLeft;
BOOL mButtonsEnabled[BUTTON_COUNT];
protected:
LLButton* mButtons[BUTTON_COUNT];
private:
F32 mButtonScale;
BOOL mAutoFocus;
LLHandle<LLFloater> mSnappedTo;
LLHandle<LLFloater> mHostHandle;
LLHandle<LLFloater> mLastHostHandle;
static LLMultiFloater* sHostp;
static BOOL sEditModeEnabled;
static std::string sButtonActiveImageNames[BUTTON_COUNT];
static std::string sButtonInactiveImageNames[BUTTON_COUNT];
static std::string sButtonPressedImageNames[BUTTON_COUNT];
static std::string sButtonNames[BUTTON_COUNT];
static std::string sButtonToolTips[BUTTON_COUNT];
typedef void (LLFloater::*button_callback)();
static button_callback sButtonCallbacks[BUTTON_COUNT];
typedef std::map<LLHandle<LLFloater>, LLFloater*> handle_map_t;
typedef std::map<LLHandle<LLFloater>, LLFloater*>::iterator handle_map_iter_t;
static handle_map_t sFloaterMap;
std::vector<LLHandle<LLView> > mMinimizedHiddenChildren;
BOOL mHasBeenDraggedWhileMinimized;
S32 mPreviousMinimizedBottom;
S32 mPreviousMinimizedLeft;
LLFloaterNotificationContext* mNotificationContext;
};
/////////////////////////////////////////////////////////////
// LLFloaterView
// Parent of all floating panels
class LLFloaterView : public LLUICtrl
{
public:
LLFloaterView( const std::string& name, const LLRect& rect );
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
void reshapeFloater(S32 width, S32 height, BOOL called_from_parent, BOOL adjust_vertical);
/*virtual*/ void draw();
/*virtual*/ LLRect getSnapRect() const;
void refresh();
void getNewFloaterPosition( S32* left, S32* top );
void resetStartingFloaterPosition();
LLRect findNeighboringPosition( LLFloater* reference_floater, LLFloater* neighbor );
// Given a child of gFloaterView, make sure this view can fit entirely onscreen.
void adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside);
void getMinimizePosition( S32 *left, S32 *bottom);
void restoreAll(); // un-minimize all floaters
typedef std::set<LLView*> skip_list_t;
void pushVisibleAll(BOOL visible, const skip_list_t& skip_list = skip_list_t());
void popVisibleAll(const skip_list_t& skip_list = skip_list_t());
void setCycleMode(BOOL mode) { mFocusCycleMode = mode; }
BOOL getCycleMode() const { return mFocusCycleMode; }
void bringToFront( LLFloater* child, BOOL give_focus = TRUE );
void highlightFocusedFloater();
void unhighlightFocusedFloater();
void focusFrontFloater();
void destroyAllChildren();
// attempt to close all floaters
void closeAllChildren(bool app_quitting);
BOOL allChildrenClosed();
// <edit>
void minimizeAllChildren();
// </edit>
LLFloater* getFrontmost();
LLFloater* getBackmost();
LLFloater* getParentFloater(LLView* viewp);
LLFloater* getFocusedFloater();
void syncFloaterTabOrder();
// Returns z order of child provided. 0 is closest, larger numbers
// are deeper in the screen. If there is no such child, the return
// value is not defined.
S32 getZOrder(LLFloater* child);
void setSnapOffsetBottom(S32 offset) { mSnapOffsetBottom = offset; }
private:
S32 mColumn;
S32 mNextLeft;
S32 mNextTop;
BOOL mFocusCycleMode;
S32 mSnapOffsetBottom;
};
// visibility policy specialized for floaters
template<>
class VisibilityPolicy<LLFloater>
{
public:
// visibility methods
static bool visible(LLFloater* instance, const LLSD& key)
{
if (instance)
{
return !instance->isMinimized() && instance->isInVisibleChain();
}
return FALSE;
}
static void show(LLFloater* instance, const LLSD& key);
static void hide(LLFloater* instance, const LLSD& key)
{
if (instance) instance->close();
}
};
// singleton implementation for floaters (provides visibility policy)
// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=164990
template <class T> class LLFloaterSingleton : public LLUISingleton<T, VisibilityPolicy<LLFloater> >
{
};
extern LLFloaterView* gFloaterView;
#endif // LL_FLOATER_H