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.
434 lines
14 KiB
C++
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
|
|
|
|
|
|
|