From d220657d8525ccfa246e0f49904e18cc36458b28 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 25 Feb 2014 21:54:09 -0800 Subject: ACME-1327 : WIP : Added big preview to the Flickr photo panel, uses the thumbnail for the moment --- indra/newview/llfloaterbigpreview.cpp | 109 ++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 indra/newview/llfloaterbigpreview.cpp (limited to 'indra/newview/llfloaterbigpreview.cpp') diff --git a/indra/newview/llfloaterbigpreview.cpp b/indra/newview/llfloaterbigpreview.cpp new file mode 100644 index 0000000000..84a1523e7c --- /dev/null +++ b/indra/newview/llfloaterbigpreview.cpp @@ -0,0 +1,109 @@ +/** +* @file llfloaterbigpreview.cpp +* @brief Display of extended (big) preview for snapshots and SL Share +* @author merov@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* 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 "llviewerprecompiledheaders.h" + +#include "llfloaterbigpreview.h" + +#include "llfloaterreg.h" +#include "llsnapshotlivepreview.h" + +/////////////////////// +//LLFloaterBigPreview// +/////////////////////// + +LLFloaterBigPreview::LLFloaterBigPreview(const LLSD& key) : LLFloater(key), + mPreviewPlaceholder(NULL), + mFloaterOwner(NULL) +{ +} + +LLFloaterBigPreview::~LLFloaterBigPreview() +{ + if (mPreviewHandle.get()) + { + mPreviewHandle.get()->die(); + } +} + +void LLFloaterBigPreview::onCancel() +{ + closeFloater(); +} + +void LLFloaterBigPreview::closeOnFloaterOwnerClosing(LLFloater* floaterp) +{ + if (floaterp == mFloaterOwner) + { + closeFloater(); + } +} + +BOOL LLFloaterBigPreview::postBuild() +{ + mPreviewPlaceholder = getChild("big_preview_placeholder"); + return LLFloater::postBuild(); +} + +void LLFloaterBigPreview::draw() +{ + LLFloater::draw(); + + LLSnapshotLivePreview * previewp = static_cast(mPreviewHandle.get()); + + // Display the preview if one is available + // HACK!!! We use the puny thumbnail image for the moment + // *TODO : Use the real large preview + if (previewp && previewp->getThumbnailImage()) + { + const LLRect& preview_rect = mPreviewPlaceholder->getRect(); +// const S32 thumbnail_w = previewp->getThumbnailWidth(); +// const S32 thumbnail_h = previewp->getThumbnailHeight(); + + // calc preview offset within the preview rect +// const S32 local_offset_x = (preview_rect.getWidth() - thumbnail_w) / 2 ; +// const S32 local_offset_y = (preview_rect.getHeight() - thumbnail_h) / 2 ; + const S32 local_offset_x = 0 ; + const S32 local_offset_y = 0 ; + + // calc preview offset within the floater rect + S32 offset_x = preview_rect.mLeft + local_offset_x; + S32 offset_y = preview_rect.mBottom + local_offset_y; + + //llinfos << "Merov : draw, offset x = " << offset_x << ", y = " << offset_y << ", thumbnail w = " << thumbnail_w << ", h = " << thumbnail_h << ", rect w = " << preview_rect.getWidth() << ", h = " << preview_rect.getHeight() << llendl; + + gGL.matrixMode(LLRender::MM_MODELVIEW); + // Apply floater transparency to the texture unless the floater is focused. + F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); + LLColor4 color = LLColor4::white; + gl_draw_scaled_image(offset_x, offset_y, + //thumbnail_w, thumbnail_h, + preview_rect.getWidth(), preview_rect.getHeight(), + previewp->getThumbnailImage(), color % alpha); + } +} + -- cgit v1.3 From 6dfcd7fc2bd0f502673c43f1a54cda2a8d74e391 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Tue, 25 Feb 2014 23:01:52 -0800 Subject: ACME-1327 : WIP : Added computation of the big preview, allow big preview to be resizable --- indra/newview/llfloaterbigpreview.cpp | 8 ++-- indra/newview/llsnapshotlivepreview.cpp | 54 +++++++++++++++++++++- indra/newview/llsnapshotlivepreview.h | 10 +++- .../skins/default/xui/en/floater_big_preview.xml | 2 +- 4 files changed, 66 insertions(+), 8 deletions(-) (limited to 'indra/newview/llfloaterbigpreview.cpp') diff --git a/indra/newview/llfloaterbigpreview.cpp b/indra/newview/llfloaterbigpreview.cpp index 84a1523e7c..d5f25d5f95 100644 --- a/indra/newview/llfloaterbigpreview.cpp +++ b/indra/newview/llfloaterbigpreview.cpp @@ -78,7 +78,7 @@ void LLFloaterBigPreview::draw() // Display the preview if one is available // HACK!!! We use the puny thumbnail image for the moment // *TODO : Use the real large preview - if (previewp && previewp->getThumbnailImage()) + if (previewp && previewp->getBigThumbnailImage()) { const LLRect& preview_rect = mPreviewPlaceholder->getRect(); // const S32 thumbnail_w = previewp->getThumbnailWidth(); @@ -93,9 +93,7 @@ void LLFloaterBigPreview::draw() // calc preview offset within the floater rect S32 offset_x = preview_rect.mLeft + local_offset_x; S32 offset_y = preview_rect.mBottom + local_offset_y; - - //llinfos << "Merov : draw, offset x = " << offset_x << ", y = " << offset_y << ", thumbnail w = " << thumbnail_w << ", h = " << thumbnail_h << ", rect w = " << preview_rect.getWidth() << ", h = " << preview_rect.getHeight() << llendl; - + gGL.matrixMode(LLRender::MM_MODELVIEW); // Apply floater transparency to the texture unless the floater is focused. F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); @@ -103,7 +101,7 @@ void LLFloaterBigPreview::draw() gl_draw_scaled_image(offset_x, offset_y, //thumbnail_w, thumbnail_h, preview_rect.getWidth(), preview_rect.getHeight(), - previewp->getThumbnailImage(), color % alpha); + previewp->getBigThumbnailImage(), color % alpha); } } diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index eef4ed78c8..2ab00419f9 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -75,7 +75,8 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Param mColor(1.f, 0.f, 0.f, 0.5f), mCurImageIndex(0), mPreviewImage(NULL), - mThumbnailImage(NULL) , + mThumbnailImage(NULL) , + mBigThumbnailImage(NULL) , mThumbnailWidth(0), mThumbnailHeight(0), mThumbnailSubsampled(FALSE), @@ -115,6 +116,7 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Param mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ; mThumbnailUpdateLock = FALSE ; mThumbnailUpToDate = FALSE ; + mBigThumbnailUpToDate = FALSE ; } LLSnapshotLivePreview::~LLSnapshotLivePreview() @@ -205,6 +207,7 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail if (new_thumbnail) { mThumbnailUpToDate = FALSE ; + mBigThumbnailUpToDate = FALSE; } } @@ -602,6 +605,55 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update) mThumbnailUpdateLock = FALSE ; } +LLViewerTexture* LLSnapshotLivePreview::getBigThumbnailImage() +{ + if (mThumbnailUpdateLock) //in the process of updating + { + return NULL; + } + if (mBigThumbnailUpToDate && mBigThumbnailImage)//already updated + { + return mBigThumbnailImage; + } + + LLPointer raw = new LLImageRaw; + + // The big thumbnail is be a subsampled version of the preview (used in SL Share previews, i.e. Flickr, Twitter, Facebook) + raw->resize( mPreviewImage->getWidth(), + mPreviewImage->getHeight(), + mPreviewImage->getComponents()); + raw->copy(mPreviewImage); + // Scale to the big thumbnail size + if (!raw->scale(getBigThumbnailWidth(), getBigThumbnailHeight())) + { + raw = NULL ; + } + + if (raw) + { + // Filter + // Note: filtering needs to be done *before* the scaling to power of 2 or the effect is distorted + if (getFilter() != "") + { + std::string filter_path = LLImageFiltersManager::getInstance()->getFilterPath(getFilter()); + if (filter_path != "") + { + LLImageFilter filter(filter_path); + filter.executeFilter(raw); + } + else + { + llwarns << "Couldn't find a path to the following filter : " << getFilter() << llendl; + } + } + // Scale to a power of 2 so it can be mapped to a texture + raw->expandToPowerOfTwo(); + mBigThumbnailImage = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); + mBigThumbnailUpToDate = TRUE ; + } + + return mBigThumbnailImage ; +} // Called often. Checks whether it's time to grab a new snapshot and if so, does it. // Returns TRUE if new snapshot generated, FALSE otherwise. diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h index 1b7b5290f8..baf3531e69 100644 --- a/indra/newview/llsnapshotlivepreview.h +++ b/indra/newview/llsnapshotlivepreview.h @@ -120,6 +120,11 @@ public: void resetThumbnailImage() { mThumbnailImage = NULL ; } void drawPreviewRect(S32 offset_x, S32 offset_y) ; + + LLViewerTexture* getBigThumbnailImage(); + S32 getBigThumbnailWidth() const { return 3*mThumbnailWidth ; } + S32 getBigThumbnailHeight() const { return 3*mThumbnailHeight ; } + // Returns TRUE when snapshot generated, FALSE otherwise. static BOOL onIdle( void* snapshot_preview ); @@ -145,7 +150,10 @@ private: BOOL mThumbnailUpdateLock ; BOOL mThumbnailUpToDate ; LLRect mThumbnailPlaceholderRect; - BOOL mThumbnailSubsampled; // TRUE is the thumbnail is a subsampled version of the mPreviewImage + BOOL mThumbnailSubsampled; // TRUE if the thumbnail is a subsampled version of the mPreviewImage + + LLPointer mBigThumbnailImage ; + BOOL mBigThumbnailUpToDate; S32 mCurImageIndex; // The logic is mPreviewImage (raw frame) -> mFormattedImage (formatted / filtered) -> mPreviewImageEncoded (decoded back, to show artifacts) diff --git a/indra/newview/skins/default/xui/en/floater_big_preview.xml b/indra/newview/skins/default/xui/en/floater_big_preview.xml index 23698ccc40..c0bdd3d9bd 100644 --- a/indra/newview/skins/default/xui/en/floater_big_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_big_preview.xml @@ -2,7 +2,7 @@ Date: Wed, 26 Feb 2014 17:22:16 -0800 Subject: ACME-1327 : WIP : Make rescale of preview isotropic, make preview button a toggle --- indra/newview/llfloaterbigpreview.cpp | 33 ++++++++++++---------- indra/newview/llfloaterbigpreview.h | 4 +-- indra/newview/llfloaterflickr.cpp | 31 +++++++++++++++----- indra/newview/llfloaterflickr.h | 1 + indra/newview/llsnapshotlivepreview.h | 1 + .../skins/default/xui/en/panel_flickr_photo.xml | 5 ++-- 6 files changed, 48 insertions(+), 27 deletions(-) (limited to 'indra/newview/llfloaterbigpreview.cpp') diff --git a/indra/newview/llfloaterbigpreview.cpp b/indra/newview/llfloaterbigpreview.cpp index d5f25d5f95..b516e9dd01 100644 --- a/indra/newview/llfloaterbigpreview.cpp +++ b/indra/newview/llfloaterbigpreview.cpp @@ -28,8 +28,6 @@ #include "llviewerprecompiledheaders.h" #include "llfloaterbigpreview.h" - -#include "llfloaterreg.h" #include "llsnapshotlivepreview.h" /////////////////////// @@ -57,7 +55,7 @@ void LLFloaterBigPreview::onCancel() void LLFloaterBigPreview::closeOnFloaterOwnerClosing(LLFloater* floaterp) { - if (floaterp == mFloaterOwner) + if (isFloaterOwner(floaterp)) { closeFloater(); } @@ -76,21 +74,25 @@ void LLFloaterBigPreview::draw() LLSnapshotLivePreview * previewp = static_cast(mPreviewHandle.get()); // Display the preview if one is available - // HACK!!! We use the puny thumbnail image for the moment - // *TODO : Use the real large preview if (previewp && previewp->getBigThumbnailImage()) { + // Get the preview rect const LLRect& preview_rect = mPreviewPlaceholder->getRect(); -// const S32 thumbnail_w = previewp->getThumbnailWidth(); -// const S32 thumbnail_h = previewp->getThumbnailHeight(); - // calc preview offset within the preview rect -// const S32 local_offset_x = (preview_rect.getWidth() - thumbnail_w) / 2 ; -// const S32 local_offset_y = (preview_rect.getHeight() - thumbnail_h) / 2 ; - const S32 local_offset_x = 0 ; - const S32 local_offset_y = 0 ; + // Get the preview texture size + S32 thumbnail_w = previewp->getBigThumbnailWidth(); + S32 thumbnail_h = previewp->getBigThumbnailHeight(); + + // Compute the scaling ratio and the size of the final texture in the rect: we want to prevent anisotropic scaling (distorted in x and y) + F32 ratio = llmax((F32)(thumbnail_w)/(F32)(preview_rect.getWidth()), (F32)(thumbnail_h)/(F32)(preview_rect.getHeight())); + thumbnail_w = (S32)((F32)(thumbnail_w)/ratio); + thumbnail_h = (S32)((F32)(thumbnail_h)/ratio); - // calc preview offset within the floater rect + // Compute the preview offset within the preview rect: we want to center that preview in the available rect + const S32 local_offset_x = (preview_rect.getWidth() - thumbnail_w) / 2 ; + const S32 local_offset_y = (preview_rect.getHeight() - thumbnail_h) / 2 ; + + // Compute preview offset within the floater rect S32 offset_x = preview_rect.mLeft + local_offset_x; S32 offset_y = preview_rect.mBottom + local_offset_y; @@ -98,9 +100,10 @@ void LLFloaterBigPreview::draw() // Apply floater transparency to the texture unless the floater is focused. F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); LLColor4 color = LLColor4::white; + + // Draw the preview texture gl_draw_scaled_image(offset_x, offset_y, - //thumbnail_w, thumbnail_h, - preview_rect.getWidth(), preview_rect.getHeight(), + thumbnail_w, thumbnail_h, previewp->getBigThumbnailImage(), color % alpha); } } diff --git a/indra/newview/llfloaterbigpreview.h b/indra/newview/llfloaterbigpreview.h index 91b0968e88..63c6784d36 100644 --- a/indra/newview/llfloaterbigpreview.h +++ b/indra/newview/llfloaterbigpreview.h @@ -28,9 +28,6 @@ #define LL_LLFLOATERBIGPREVIEW_H #include "llfloater.h" -#include "llviewertexture.h" - -//class LLSnapshotLivePreview; class LLFloaterBigPreview : public LLFloater { @@ -44,6 +41,7 @@ public: void setPreview(LLView* previewp) { mPreviewHandle = previewp->getHandle(); } void setFloaterOwner(LLFloater* floaterp) { mFloaterOwner = floaterp; } + bool isFloaterOwner(LLFloater* floaterp) const { return (mFloaterOwner == floaterp); } void closeOnFloaterOwnerClosing(LLFloater* floaterp); private: diff --git a/indra/newview/llfloaterflickr.cpp b/indra/newview/llfloaterflickr.cpp index 21c619730c..e93adf1570 100644 --- a/indra/newview/llfloaterflickr.cpp +++ b/indra/newview/llfloaterflickr.cpp @@ -66,6 +66,7 @@ LLFlickrPhotoPanel::LLFlickrPhotoPanel() : mSnapshotPanel(NULL), mResolutionComboBox(NULL), mRefreshBtn(NULL), +mBtnPreview(NULL), mWorkingLabel(NULL), mThumbnailPlaceholder(NULL), mTitleTextBox(NULL), @@ -98,6 +99,7 @@ BOOL LLFlickrPhotoPanel::postBuild() mFilterComboBox = getChild("filters_combobox"); mFilterComboBox->setCommitCallback(boost::bind(&LLFlickrPhotoPanel::updateResolution, this, TRUE)); mRefreshBtn = getChild("new_snapshot_btn"); + mBtnPreview = getChild("big_preview_btn"); mWorkingLabel = getChild("working_lbl"); mThumbnailPlaceholder = getChild("thumbnail_placeholder"); mTitleTextBox = getChild("photo_title"); @@ -162,8 +164,14 @@ void LLFlickrPhotoPanel::draw() mResolutionComboBox->setEnabled(no_ongoing_connection); mFilterComboBox->setEnabled(no_ongoing_connection); mRefreshBtn->setEnabled(no_ongoing_connection); + mBtnPreview->setEnabled(no_ongoing_connection); mLocationCheckbox->setEnabled(no_ongoing_connection); + // Toggle the button state as appropriate + LLFloaterBigPreview* big_preview_floater = dynamic_cast(LLFloaterReg::getInstance("big_preview")); + bool preview_active = (big_preview_floater && big_preview_floater->getVisible() && big_preview_floater->isFloaterOwner(getParentByType())); + mBtnPreview->setToggleState(preview_active); + // Display the preview if one is available if (previewp && previewp->getThumbnailImage()) { @@ -256,13 +264,22 @@ void LLFlickrPhotoPanel::onClickNewSnapshot() void LLFlickrPhotoPanel::onClickBigPreview() { LLFloaterBigPreview* big_preview_floater = dynamic_cast(LLFloaterReg::getInstance("big_preview")); - if (big_preview_floater) - { - LLSnapshotLivePreview* previewp = getPreviewView(); - big_preview_floater->setPreview(previewp); - big_preview_floater->setFloaterOwner(getParentByType()); - } - LLFloaterReg::showInstance("big_preview"); + bool preview_active = (big_preview_floater && big_preview_floater->getVisible() && big_preview_floater->isFloaterOwner(getParentByType())); + // Toggle the preview + if (preview_active) + { + LLFloaterReg::hideInstance("big_preview"); + } + else + { + if (big_preview_floater) + { + LLSnapshotLivePreview* previewp = getPreviewView(); + big_preview_floater->setPreview(previewp); + big_preview_floater->setFloaterOwner(getParentByType()); + } + LLFloaterReg::showInstance("big_preview"); + } } void LLFlickrPhotoPanel::onSend() diff --git a/indra/newview/llfloaterflickr.h b/indra/newview/llfloaterflickr.h index 9fa4a258e2..8a346c3166 100644 --- a/indra/newview/llfloaterflickr.h +++ b/indra/newview/llfloaterflickr.h @@ -76,6 +76,7 @@ private: LLUICtrl * mRatingComboBox; LLUICtrl * mPostButton; LLUICtrl * mCancelButton; + LLButton * mBtnPreview; }; class LLFlickrAccountPanel : public LLPanel diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h index baf3531e69..0e918d165e 100644 --- a/indra/newview/llsnapshotlivepreview.h +++ b/indra/newview/llsnapshotlivepreview.h @@ -28,6 +28,7 @@ #define LL_LLSNAPSHOTLIVEPREVIEW_H #include "llpanelsnapshot.h" +#include "llviewertexture.h" #include "llviewerwindow.h" class LLImageJPEG; diff --git a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml index 350c385cc3..8d8ef45c0d 100644 --- a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml +++ b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml @@ -95,11 +95,12 @@