diff options
36 files changed, 1500 insertions, 636 deletions
diff --git a/dash/CoverflowResultView.cpp b/dash/CoverflowResultView.cpp index 2f20642d4..16297d4e0 100755 --- a/dash/CoverflowResultView.cpp +++ b/dash/CoverflowResultView.cpp @@ -303,10 +303,12 @@ void CoverflowResultView::Activate(std::string const& uri, int index, ResultView int left_results = index; int right_results = num_results ? (num_results - index) - 1 : 0; - int row_y = GetRootGeometry().y; + int row_y = GetAbsoluteY(); + int column_x = -1; int row_height = renderer_->height; + int column_width = GetWidth(); - glib::Variant data(g_variant_new("(iiii)", row_y, row_height, left_results, right_results)); + glib::Variant data(g_variant_new("(iiii)", column_x, row_y, column_width, row_height, left_results, right_results)); UriActivated.emit(uri, type, data); } diff --git a/dash/DashController.cpp b/dash/DashController.cpp index 7877610ed..1c2dcb9fd 100644 --- a/dash/DashController.cpp +++ b/dash/DashController.cpp @@ -226,11 +226,10 @@ nux::Geometry Controller::GetIdealWindowGeometry() // We want to cover as much of the screen as possible to grab any mouse events outside // of our window - panel::Style &panel_style = panel::Style::Instance(); return nux::Geometry (monitor_geo.x + launcher_width, - monitor_geo.y + panel_style.panel_height, + monitor_geo.y, monitor_geo.width - launcher_width, - monitor_geo.height - panel_style.panel_height); + monitor_geo.height); } void Controller::Relayout(bool check_monitor) diff --git a/dash/DashView.cpp b/dash/DashView.cpp index ed92f888f..1029a280a 100644 --- a/dash/DashView.cpp +++ b/dash/DashView.cpp @@ -14,6 +14,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Nick Dedekind <nick.dedekind@canonical.com> */ @@ -36,6 +37,7 @@ #include "unity-shared/UnitySettings.h" #include "unity-shared/UBusMessages.h" #include "unity-shared/PreviewStyle.h" +#include "unity-shared/PanelStyle.h" namespace unity { @@ -45,6 +47,15 @@ DECLARE_LOGGER(logger, "unity.dash.view"); namespace { previews::Style preview_style; + +const int PREVIEW_ANIMATION_LENGTH = 250; + +const int DASH_TILE_HORIZONTAL_COUNT = 6; +const int DASH_DEFAULT_CATEGORY_COUNT = 3; +const int DASH_RESULT_RIGHT_PAD = 35; +const int GROUP_HEADING_HEIGHT = 24; + +const int PREVIEW_ICON_SPLIT_OFFSCREEN_OFFSET = 10; } // This is so we can access some protected members in nux::VLayout and @@ -75,6 +86,27 @@ private: nux::Area* area_; }; +class DashContentView : public nux::View +{ +public: + DashContentView(NUX_FILE_LINE_DECL):View(NUX_FILE_LINE_PARAM) + { + SetRedirectRenderingToTexture(true); + } + ~DashContentView() {} + + void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw) + { + } + + void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw) + { + if (GetLayout()) + GetLayout()->ProcessDraw(graphics_engine, force_draw); + } + +}; + NUX_IMPLEMENT_OBJECT_TYPE(DashView); DashView::DashView() @@ -83,15 +115,17 @@ DashView::DashView() , preview_container_(nullptr) , preview_displaying_(false) , preview_navigation_mode_(previews::Navigation::NONE) - , active_lens_view_(0) , last_activated_uri_("") , search_in_progress_(false) , activate_on_finish_(false) , visible_(false) - , fade_out_value_(0.0f) - , fade_in_value_(0.0f) + , opening_column_x_(-1) , opening_row_y_(-1) + , opening_column_width_(0) , opening_row_height_(0) + , animate_split_value_(0.0) + , animate_preview_container_value_(0.0) + , animate_preview_value_(0.0) { renderer_.SetOwner(this); renderer_.need_redraw.connect([this] () { @@ -145,63 +179,6 @@ void DashView::SetMonitorOffset(int x, int y) renderer_.y_offset = y; } -void DashView::ClosePreview() -{ - if (preview_displaying_) - { - layout_->SetPresentRedirectedView(true); - animation_.Stop(); - fade_out_connection_.disconnect(); - fade_in_connection_.disconnect(); - // Set fade animation - animation_.SetDuration(250); - animation_.SetEasingCurve(na::EasingCurve(na::EasingCurve::Type::ExpoEaseIn)); - fade_in_connection_ = animation_.updated.connect(sigc::mem_fun(this, &DashView::FadeInCallBack)); - - fade_in_value_ = 1.0f; - animation_.SetStartValue(fade_in_value_); - animation_.SetFinishValue(0.0f); - animation_.Start(); - } - - preview_navigation_mode_ = previews::Navigation::NONE; - preview_displaying_ = false; - active_lens_view_->SetVisible(true); - - // re-focus dash view component. - nux::GetWindowCompositor().SetKeyFocusArea(default_focus()); - QueueDraw(); -} - -void DashView::FadeOutCallBack(float const& fade_out_value) -{ - fade_out_value_ = fade_out_value; - QueueDraw(); -} - -void DashView::FadeInCallBack(float const& fade_in_value) -{ - fade_in_value_ = fade_in_value; - QueueDraw(); - - if (fade_in_value_ == 0.0f) - { - // sanity check - if (!preview_container_) - { - return; - } - RemoveChild(preview_container_.GetPointer()); - preview_container_->UnParentObject(); - preview_container_.Release(); // free resources - preview_state_machine_.ClosePreview(); - - // Closing the preview. Set opening_row_y_ to -1; - // opening_row_y_ is updated once when the preview - opening_row_y_ = -1; - } -} - void DashView::OnUriActivated(ResultView::ActivateType type, std::string const& uri, GVariant* data, std::string const& unique_id) { last_activated_uri_ = uri; @@ -210,20 +187,20 @@ void DashView::OnUriActivated(ResultView::ActivateType type, std::string const& if (data) { // Update positioning information. - int position = -1; + int column_x = -1; + int row_y = -1; + int column_width = 0; int row_height = 0; int results_to_the_left = 0; int results_to_the_right = 0; - g_variant_get(data, "(iiii)", &position, &row_height, &results_to_the_left, &results_to_the_right); - preview_state_machine_.SetSplitPosition(SplitPosition::CONTENT_AREA, position); + g_variant_get(data, "(iiiiii)", &column_x, &row_y, &column_width, &row_height, &results_to_the_left, &results_to_the_right); + preview_state_machine_.SetSplitPosition(SplitPosition::CONTENT_AREA, row_y); preview_state_machine_.left_results = results_to_the_left; preview_state_machine_.right_results = results_to_the_right; - if (opening_row_y_ == -1) - { - // Update only when opening the previews - opening_row_y_ = position; - } + opening_column_x_ = column_x; + opening_row_y_ = row_y; + opening_column_width_ = column_width; opening_row_height_ = row_height; } @@ -234,43 +211,29 @@ void DashView::OnUriActivated(ResultView::ActivateType type, std::string const& } } - void DashView::BuildPreview(Preview::Ptr model) { if (!preview_displaying_) - { - // Make a copy of this DashView backup texture. - if (layout_->RedirectRenderingToTexture()) - { - nux::TexCoordXForm texxform; - nux::ObjectPtr<nux::IOpenGLBaseTexture> src_texture; + { + StartPreviewAnimation(); - layout_copy_ = src_texture = layout_->BackupTexture(); - - animation_.Stop(); - fade_out_connection_.disconnect(); - fade_in_connection_.disconnect(); - // Set fade animation - animation_.SetDuration(250); - animation_.SetEasingCurve(na::EasingCurve(na::EasingCurve::Type::ExpoEaseIn)); - fade_out_connection_ = animation_.updated.connect(sigc::mem_fun(this, &DashView::FadeOutCallBack)); - - fade_out_value_ = 1.0f; - animation_.SetStartValue(fade_out_value_); - animation_.SetFinishValue(0.0f); - animation_.Start(); - - layout_->SetPresentRedirectedView(false); + content_view_->SetPresentRedirectedView(false); + preview_lens_view_ = active_lens_view_; + if (preview_lens_view_) + { + preview_lens_view_->ForceCategoryExpansion(stored_activated_unique_id_, true); + preview_lens_view_->EnableResultTextures(true); + preview_lens_view_->PushFilterExpansion(false); } preview_container_ = previews::PreviewContainer::Ptr(new previews::PreviewContainer()); + preview_container_->SetRedirectRenderingToTexture(true); AddChild(preview_container_.GetPointer()); preview_container_->SetParentObject(this); preview_container_->Preview(model, previews::Navigation::NONE); // no swipe left or right - preview_container_->SetGeometry(layout_->GetGeometry()); + preview_container_->SetGeometry(lenses_layout_->GetGeometry()); preview_displaying_ = true; - active_lens_view_->SetVisible(false); // connect to nav left/right signals to request nav left/right movement. preview_container_->navigate_left.connect([&] () { @@ -309,6 +272,185 @@ void DashView::BuildPreview(Preview::Ptr model) QueueDraw(); } +void DashView::ClosePreview() +{ + if (preview_displaying_) + { + EndPreviewAnimation(); + + preview_displaying_ = false; + } + + preview_navigation_mode_ = previews::Navigation::NONE; + + // re-focus dash view component. + nux::GetWindowCompositor().SetKeyFocusArea(default_focus()); + QueueDraw(); +} + +void DashView::StartPreviewAnimation() +{ + // We use linear animations so we can easily control when the next animation in the sequence starts. + // The animation curve is caluclated separately. + + preview_animation_.reset(); + preview_container_animation_.reset(); + + // Dash Split Open Animation + split_animation_.reset(new na::AnimateValue<float>()); + split_animation_->SetDuration((1.0f - animate_split_value_) * PREVIEW_ANIMATION_LENGTH); + split_animation_->SetStartValue(animate_split_value_); + split_animation_->SetFinishValue(1.0f); + split_animation_->SetEasingCurve(na::EasingCurve(na::EasingCurve::Type::Linear)); + split_animation_->updated.connect([&](float const& linear_split_animate_value) + { + static na::EasingCurve split_animation_curve(na::EasingCurve::Type::InQuad); + + animate_split_value_ = split_animation_curve.ValueForProgress(linear_split_animate_value); + QueueDraw(); + + // time to start the preview container animation? + if (linear_split_animate_value >= 0.5f && !preview_container_animation_) + { + // Preview Container Close Animation + preview_container_animation_.reset(new na::AnimateValue<float>()); + preview_container_animation_->SetDuration((1.0f - animate_preview_container_value_) * PREVIEW_ANIMATION_LENGTH); + preview_container_animation_->SetStartValue(animate_preview_container_value_); + preview_container_animation_->SetFinishValue(1.0f); + preview_container_animation_->SetEasingCurve(na::EasingCurve(na::EasingCurve::Type::Linear)); + preview_container_animation_->updated.connect([&](float const& linear_preview_container_animate_value) + { + static na::EasingCurve preview_container_animation_curve(na::EasingCurve::Type::InQuad); + + animate_preview_container_value_ = preview_container_animation_curve.ValueForProgress(linear_preview_container_animate_value); + QueueDraw(); + + // time to start the preview animation? + if (linear_preview_container_animate_value >= 0.9f && !preview_animation_) + { + // Preview Close Animation + preview_animation_.reset(new na::AnimateValue<float>()); + preview_animation_->SetDuration((1.0f - animate_preview_value_) * PREVIEW_ANIMATION_LENGTH); + preview_animation_->SetStartValue(animate_preview_value_); + preview_animation_->SetFinishValue(1.0f); + preview_animation_->SetEasingCurve(na::EasingCurve(na::EasingCurve::Type::Linear)); + preview_animation_->updated.connect([&](float const& linear_preview_animate_value) + { + animate_preview_value_ = linear_preview_animate_value; + QueueDraw(); + }); + + preview_animation_->finished.connect(sigc::mem_fun(this, &DashView::OnPreviewAnimationFinished)); + preview_animation_->Start(); + } + }); + + preview_container_animation_->finished.connect(sigc::mem_fun(this, &DashView::OnPreviewAnimationFinished)); + preview_container_animation_->Start(); + } + + if (preview_lens_view_) + preview_lens_view_->SetResultsPreviewAnimationValue(animate_split_value_); + }); + + split_animation_->finished.connect(sigc::mem_fun(this, &DashView::OnPreviewAnimationFinished)); + split_animation_->Start(); +} + +void DashView::EndPreviewAnimation() +{ + // We use linear animations so we can easily control when the next animation in the sequence starts. + // The animation curve is caluclated separately. + + split_animation_.reset(); + preview_container_animation_.reset(); + + // Preview Close Animation + preview_animation_.reset(new na::AnimateValue<float>()); + preview_animation_->SetDuration(animate_preview_value_ * PREVIEW_ANIMATION_LENGTH); + preview_animation_->SetStartValue(1.0f - animate_preview_value_); + preview_animation_->SetFinishValue(1.0f); + preview_animation_->SetEasingCurve(na::EasingCurve(na::EasingCurve::Type::Linear)); + preview_animation_->updated.connect([&](float const& preview_value) + { + animate_preview_value_ = 1.0f - preview_value; + QueueDraw(); + + // time to stop the split? + if (preview_value >= 0.9f && !preview_container_animation_) + { + // Preview Container Close Animation + preview_container_animation_.reset(new na::AnimateValue<float>()); + preview_container_animation_->SetDuration(animate_preview_container_value_ * PREVIEW_ANIMATION_LENGTH); + preview_container_animation_->SetStartValue(1.0f - animate_preview_container_value_); + preview_container_animation_->SetFinishValue(1.0f); + preview_container_animation_->SetEasingCurve(na::EasingCurve(na::EasingCurve::Type::Linear)); + preview_container_animation_->updated.connect([&](float const& linear_preview_container_animate_value) + { + static na::EasingCurve preview_container_animation_curve(na::EasingCurve::Type::InQuad); + + animate_preview_container_value_ = 1.0f - preview_container_animation_curve.ValueForProgress(linear_preview_container_animate_value); + QueueDraw(); + + if (linear_preview_container_animate_value >= 0.5f && !split_animation_) + { + // Dash Split Close Animation + split_animation_.reset(new na::AnimateValue<float>()); + split_animation_->SetDuration(animate_split_value_ * PREVIEW_ANIMATION_LENGTH); + split_animation_->SetStartValue(1.0f - animate_split_value_); + split_animation_->SetFinishValue(1.0f); + split_animation_->SetEasingCurve(na::EasingCurve(na::EasingCurve::Type::Linear)); + split_animation_->updated.connect([&](float const& linear_split_animate_value) + { + static na::EasingCurve split_animation_curve(na::EasingCurve::Type::InQuad); + + animate_split_value_ = 1.0f - split_animation_curve.ValueForProgress(linear_split_animate_value); + QueueDraw(); + }); + split_animation_->finished.connect(sigc::mem_fun(this, &DashView::OnPreviewAnimationFinished)); + split_animation_->Start(); + + // if (preview_lens_view_) + // preview_lens_view_->PopFilterExpansion(); + } + }); + + preview_container_animation_->finished.connect(sigc::mem_fun(this, &DashView::OnPreviewAnimationFinished)); + preview_container_animation_->Start(); + } + }); + + preview_animation_->finished.connect(sigc::mem_fun(this, &DashView::OnPreviewAnimationFinished)); + preview_animation_->Start(); +} + +void DashView::OnPreviewAnimationFinished() +{ + if (animate_preview_value_ != 0.0f || animate_preview_container_value_ != 0.0f || animate_split_value_ != 0.0f) + return; + + // preview close finished. + if (preview_container_) + { + RemoveChild(preview_container_.GetPointer()); + preview_container_->UnParentObject(); + preview_container_.Release(); // free resources + preview_state_machine_.ClosePreview(); + QueueDraw(); + } + + // reset the saturation. + if (preview_lens_view_.IsValid()) + { + preview_lens_view_->SetResultsPreviewAnimationValue(0.0); + preview_lens_view_->ForceCategoryExpansion(stored_activated_unique_id_, false); + preview_lens_view_->EnableResultTextures(false); + preview_lens_view_->PopFilterExpansion(); + } + preview_lens_view_.Release(); + content_view_->SetPresentRedirectedView(true); +} + void DashView::AboutToShow() { ubus_manager_.SendMessage(UBUS_BACKGROUND_REQUEST_COLOUR_EMIT); @@ -317,26 +459,28 @@ void DashView::AboutToShow() /* Give the lenses a chance to prep data before we map them */ lens_bar_->Activate(active_lens_view_->lens()->id()); - if (active_lens_view_->lens()->id() == "home.lens") - { - for (auto lens : lenses_.GetLenses()) + if (active_lens_view_) + { + if (active_lens_view_->lens()->id() == "home.lens") { - lens->view_type = ViewType::HOME_VIEW; - LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HOME_VIEW - << " on '" << lens->id() << "'"; - } + for (auto lens : lenses_.GetLenses()) + { + lens->view_type = ViewType::HOME_VIEW; + LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HOME_VIEW + << " on '" << lens->id() << "'"; + } - home_lens_->view_type = ViewType::LENS_VIEW; - LOG_DEBUG(logger) << "Setting ViewType " << ViewType::LENS_VIEW - << " on '" << home_lens_->id() << "'"; - } - else - { - // careful here, the lens_view's view_type doesn't get reset when the dash - // hides, but lens' view_type does, so we need to update the lens directly - active_lens_view_->lens()->view_type = ViewType::LENS_VIEW; + home_lens_->view_type = ViewType::LENS_VIEW; + LOG_DEBUG(logger) << "Setting ViewType " << ViewType::LENS_VIEW + << " on '" << home_lens_->id() << "'"; + } + else + { + // careful here, the lens_view's view_type doesn't get reset when the dash + // hides, but lens' view_type does, so we need to update the lens directly + active_lens_view_->lens()->view_type = ViewType::LENS_VIEW; + } } - active_lens_view_->SetVisible(true); // this will make sure the spinner animates if the search takes a while search_bar_->ForceSearchChanged(); @@ -366,8 +510,6 @@ void DashView::AboutToHide() LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HIDDEN << " on '" << home_lens_->id() << "'"; - active_lens_view_->SetVisible(false); - // if a preview is open, close it if (preview_displaying_) { @@ -378,16 +520,20 @@ void DashView::AboutToHide() void DashView::SetupViews() { dash::Style& style = dash::Style::Instance(); + panel::Style &panel_style = panel::Style::Instance(); layout_ = new nux::VLayout(); layout_->SetLeftAndRightPadding(style.GetVSeparatorSize(), 0); layout_->SetTopAndBottomPadding(style.GetHSeparatorSize(), 0); SetLayout(layout_); - layout_->SetRedirectRenderingToTexture(true); + layout_->AddLayout(new nux::SpaceLayout(0, 0, panel_style.panel_height, panel_style.panel_height), 0); content_layout_ = new DashLayout(NUX_TRACKER_LOCATION); content_layout_->SetTopAndBottomPadding(style.GetDashViewTopPadding(), 0); - layout_->AddLayout(content_layout_, 1, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL); + + content_view_ = new DashContentView(NUX_TRACKER_LOCATION); + content_view_->SetLayout(content_layout_); + layout_->AddView(content_view_, 1, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL); search_bar_layout_ = new nux::HLayout(); search_bar_layout_->SetLeftAndRightPadding(style.GetSearchBarLeftPadding(), 0); @@ -412,15 +558,15 @@ void DashView::SetupViews() content_layout_->SetSpecialArea(search_bar_->show_filters()); lenses_layout_ = new nux::VLayout(); - content_layout_->AddView(lenses_layout_, 1, nux::MINOR_POSITION_START); + content_layout_->AddLayout(lenses_layout_, 1, nux::MINOR_POSITION_START); home_view_ = new LensView(home_lens_, nullptr); home_view_->uri_activated.connect(sigc::mem_fun(this, &DashView::OnUriActivated)); - AddChild(home_view_); + AddChild(home_view_.GetPointer()); active_lens_view_ = home_view_; lens_views_[home_lens_->id] = home_view_; - lenses_layout_->AddView(home_view_); + lenses_layout_->AddView(home_view_.GetPointer()); lens_bar_ = new LensBar(); AddChild(lens_bar_); @@ -446,19 +592,13 @@ void DashView::Relayout() content_geo_ = GetBestFitGeometry(geo); dash::Style& style = dash::Style::Instance(); - if (style.always_maximised) - { - if (geo.width >= content_geo_.width && geo.height > content_geo_.height) - content_geo_ = geo; - } - // kinda hacky, but it makes sure the content isn't so big that it throws // the bottom of the dash off the screen // not hugely happy with this, so FIXME - lenses_layout_->SetMaximumHeight (content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height - style.GetDashViewTopPadding()); - lenses_layout_->SetMinimumHeight (content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height - style.GetDashViewTopPadding()); + lenses_layout_->SetMaximumHeight (std::max(0, content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height - style.GetDashViewTopPadding())); + lenses_layout_->SetMinimumHeight (std::max(0, content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height - style.GetDashViewTopPadding())); - layout_->SetMinMaxSize(content_geo_.width, content_geo_.height); + layout_->SetMinMaxSize(content_geo_.width, content_geo_.y + content_geo_.height); // Minus the padding that gets added to the left float tile_width = style.GetTileWidth(); @@ -478,82 +618,72 @@ void DashView::Relayout() nux::Geometry DashView::GetBestFitGeometry(nux::Geometry const& for_geo) { dash::Style& style = dash::Style::Instance(); + panel::Style &panel_style = panel::Style::Instance(); int width = 0, height = 0; int tile_width = style.GetTileWidth(); int tile_height = style.GetTileHeight(); + int category_height = (style.GetPlacesGroupTopSpace() + style.GetCategoryIconSize() + style.GetPlacesGroupResultTopPadding() + tile_height); int half = for_geo.width / 2; // if default dash size is bigger than half a screens worth of items, go for that. - while ((width += tile_width) + (19 * 2) < half) + while ((width += tile_width) < half) ; - width = MAX(width, tile_width * 6); + width = std::max(width, tile_width * DASH_TILE_HORIZONTAL_COUNT); + width += style.GetVSeparatorSize(); + width += style.GetPlacesGroupResultLeftPadding() + DASH_RESULT_RIGHT_PAD; - width += 20 + 40; // add the left padding and the group plugin padding - height = search_bar_->GetGeometry().height; - height += tile_height * 3; - height += (style.GetPlacesGroupTopSpace() - 2 + 24 + 2) * 3; // adding three group headers - height += 1*2; // hseparator height + height = style.GetHSeparatorSize(); height += style.GetDashViewTopPadding(); + height += search_bar_->GetGeometry().height; + height += category_height * DASH_DEFAULT_CATEGORY_COUNT; // adding three categories height += lens_bar_->GetGeometry().height; - if (for_geo.width > 800 && for_geo.height > 550) + // width/height shouldn't be bigger than the geo available. + width = std::min(width, for_geo.width); // launcher width is taken into account in for_geo. + height = std::min(height, for_geo.height - panel_style.panel_height); // panel height is not taken into account in for_geo. + + if (style.always_maximised) { - width = MIN(width, for_geo.width-66); - height = MIN(height, for_geo.height-24); + width = std::max(0, for_geo.width); + height = std::max(0, for_geo.height - panel_style.panel_height); } - - return nux::Geometry(0, 0, width, height); + return nux::Geometry(0, panel_style.panel_height, width, height); } void DashView::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw) { - renderer_.DrawFull(graphics_engine, content_geo_, GetAbsoluteGeometry(), GetGeometry(), true); -} + panel::Style &panel_style = panel::Style::Instance(); -/** - * Parametrically interpolates a value in one of two consecutive closed intervals. - * - * @param[in] p - * @param[in] start The left (least) value of the closed interval. - * @param[in] end1 The right (greatest) value of the closed interval, - * if start <= end1 - * @param[in] end2 The right (greatest) value of the closed interval, - * if start > end1 - * - * @returns the linear interpolation at @p p of the interval [start, end] where end - * is @p end1 if start <= @p end1, otherwise end is @end2. - */ -static float Interpolate2(float p, int start, int end1, int end2) -{ - float result = end2; - if (start < end2) - { - int end = start > end1 ? end2 : end1; - result = start + p * (end - start); - } + nux::Geometry renderer_geo_abs(GetAbsoluteGeometry()); + renderer_geo_abs.y += panel_style.panel_height; + renderer_geo_abs.height -= panel_style.panel_height; - return result; + nux::Geometry renderer_geo(GetGeometry()); + renderer_geo.y += panel_style.panel_height; + renderer_geo.height += panel_style.panel_height; + + renderer_.DrawFull(graphics_engine, content_geo_, renderer_geo_abs, renderer_geo, true); } void DashView::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw) { - auto& style = dash::Style::Instance(); + panel::Style& panel_style = panel::Style::Instance(); - renderer_.DrawInner(graphics_engine, content_geo_, GetAbsoluteGeometry(), GetGeometry()); + nux::Geometry renderer_geo_abs(GetAbsoluteGeometry()); + renderer_geo_abs.y += panel_style.panel_height; + renderer_geo_abs.height -= panel_style.panel_height; - nux::Geometry clip_geo = layout_->GetGeometry(); - clip_geo.x += style.GetVSeparatorSize(); - graphics_engine.PushClippingRectangle(clip_geo); + nux::Geometry renderer_geo(GetGeometry()); + renderer_geo.y += panel_style.panel_height; + renderer_geo.height += panel_style.panel_height; - bool display_ghost = false; - bool preview_redraw = false; - if (preview_container_) - { - preview_redraw = preview_container_->IsRedrawNeeded(); - } + renderer_.DrawInner(graphics_engine, content_geo_, renderer_geo_abs, renderer_geo); + + nux::Geometry const& geo_layout(layout_->GetGeometry()); + graphics_engine.PushClippingRectangle(geo_layout); if (IsFullRedraw()) { @@ -561,249 +691,387 @@ void DashView::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw } else { - if (!preview_displaying_ && layout_->RedirectRenderingToTexture() && (fade_in_value_ == 0.0f)) - { - nux::Geometry layout_geo = layout_->GetGeometry(); - graphics_engine.PushClippingRectangle(layout_geo); - nux::GetPainter().PaintBackground(graphics_engine, layout_geo); - graphics_engine.PopClippingRectangle(); - } - - if (preview_displaying_ && (force_draw || preview_redraw) && layout_->RedirectRenderingToTexture()) - { - display_ghost = true; - nux::Geometry layout_geo = layout_->GetGeometry(); - graphics_engine.PushClippingRectangle(layout_geo); - nux::GetPainter().PaintBackground(graphics_engine, layout_geo); - graphics_engine.PopClippingRectangle(); - } + nux::GetPainter().PaintBackground(graphics_engine, geo_layout); } - if (preview_displaying_) + if (preview_container_.IsValid()) { - // Progressively reveal the preview. - nux::Geometry preview_clip_geo = preview_container_->GetGeometry(); - preview_clip_geo.y = (preview_clip_geo.y + preview_clip_geo.height)/2.0f - - (1.0f - fade_out_value_) * (preview_clip_geo.height)/2.0f; - preview_clip_geo.height = (1.0f - fade_out_value_) * (preview_clip_geo.height); + nux::Geometry geo_split_clip; + DrawDashSplit(graphics_engine, geo_split_clip); - graphics_engine.PushModelViewMatrix(nux::Matrix4::TRANSLATE(-preview_container_->GetWidth()/2.0f, -preview_container_->GetHeight()/2.0f, 0)); - graphics_engine.PushModelViewMatrix(nux::Matrix4::SCALE(1.0f - fade_out_value_, 1.0f - fade_out_value_, 1.0f)); - graphics_engine.PushModelViewMatrix(nux::Matrix4::TRANSLATE(preview_container_->GetWidth()/2.0f, preview_container_->GetHeight()/2.0f, 0)); + graphics_engine.PushClippingRectangle(geo_split_clip); - preview_container_->ProcessDraw(graphics_engine, (!force_draw) ? IsFullRedraw() : force_draw); + if (preview_lens_view_.IsValid()) + { + DrawPreviewResultTextures(graphics_engine, force_draw); + } - graphics_engine.PopModelViewMatrix(); - graphics_engine.PopModelViewMatrix(); - graphics_engine.PopModelViewMatrix(); - } - else if (fade_in_value_ > 0.0f && preview_container_ && preview_container_.IsValid()) - { - graphics_engine.PushModelViewMatrix(nux::Matrix4::TRANSLATE(-preview_container_->GetWidth()/2.0f, -preview_container_->GetHeight()/2.0f, 0)); - graphics_engine.PushModelViewMatrix(nux::Matrix4::SCALE(fade_in_value_, fade_in_value_, 1.0f)); - graphics_engine.PushModelViewMatrix(nux::Matrix4::TRANSLATE(preview_container_->GetWidth()/2.0f, preview_container_->GetHeight()/2.0f, 0)); + DrawPreviewContainer(graphics_engine); - preview_container_->ProcessDraw(graphics_engine, (!force_draw) ? IsFullRedraw() : force_draw); + // preview always on top. + DrawPreview(graphics_engine, force_draw); - graphics_engine.PopModelViewMatrix(); - graphics_engine.PopModelViewMatrix(); - graphics_engine.PopModelViewMatrix(); + graphics_engine.PopClippingRectangle(); } - else if (fade_in_value_ == 0.0f) + else { layout_->ProcessDraw(graphics_engine, force_draw); } - // Animation effect rendering - if (display_ghost || IsFullRedraw()) + if (IsFullRedraw()) { - unsigned int current_alpha_blend; - unsigned int current_src_blend_factor; - unsigned int current_dest_blend_factor; - graphics_engine.GetRenderStates().GetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); + nux::GetPainter().PopBackgroundStack(); + } + + graphics_engine.PopClippingRectangle(); + + renderer_.DrawInnerCleanup(graphics_engine, content_geo_, renderer_geo_abs, renderer_geo); +} - float ghost_opacity = 0.25f; - float tint_factor = 1.2f; - float saturation_ref = 0.4f; - nux::Color bg_color = background_color_; +void DashView::DrawDashSplit(nux::GraphicsEngine& graphics_engine, nux::Geometry& split_clip) +{ + nux::Geometry const& geo_layout(layout_->GetGeometry()); + split_clip = geo_layout; - int position_offset = 40; + if (animate_split_value_ == 1.0) + return; - if (preview_displaying_ && layout_ && layout_->RedirectRenderingToTexture()) + // if we're not presenting, then we must be manually rendering it's backup texture. + if (!content_view_->PresentRedirectedView() && content_view_->BackupTexture().IsValid()) + { + unsigned int alpha, src, dest = 0; + graphics_engine.GetRenderStates().GetBlend(alpha, src, dest); + graphics_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + nux::TexCoordXForm texxform; + texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); + texxform.FlipVCoord(true); + + // Lens Bar + texxform.uoffset = (lens_bar_->GetX() - content_view_->GetX())/(float)content_view_->GetWidth(); + texxform.voffset = (lens_bar_->GetY() - content_view_->GetY())/(float)content_view_->GetHeight(); + + int start_y = lens_bar_->GetY(); + int final_y = geo_layout.y + geo_layout.height + PREVIEW_ICON_SPLIT_OFFSCREEN_OFFSET; + + int lens_y = (1.0f - animate_split_value_) * start_y + (animate_split_value_ * final_y); + + graphics_engine.QRP_1Tex + ( + lens_bar_->GetX(), + lens_y, + lens_bar_->GetWidth(), + lens_bar_->GetHeight(), + content_view_->BackupTexture(), + texxform, + nux::Color((1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_)) + ); + + split_clip.height = std::min(lens_y, geo_layout.height); + + if (active_lens_view_ && active_lens_view_->GetPushedFilterExpansion()) { - if (layout_copy_.IsValid()) - { - graphics_engine.PushClippingRectangle(layout_->GetGeometry()); - graphics_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - nux::TexCoordXForm texxform; + // Search Bar + texxform.uoffset = (search_bar_->GetX() - content_view_->GetX())/(float)content_view_->GetWidth(); + texxform.voffset = (search_bar_->GetY() - content_view_->GetY())/(float)content_view_->GetHeight(); + + start_y = search_bar_->GetY(); + final_y = geo_layout.y - search_bar_->GetHeight() - PREVIEW_ICON_SPLIT_OFFSCREEN_OFFSET; + + graphics_engine.QRP_1Tex + ( + search_bar_->GetX(), + (1.0f - animate_split_value_) * start_y + (animate_split_value_ * final_y), + search_bar_->GetWidth() - active_lens_view_->filter_bar()->GetWidth(), + search_bar_->GetHeight(), + content_view_->BackupTexture(), + texxform, + nux::Color((1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_)) + ); + + // Filter Bar + texxform.uoffset = (active_lens_view_->filter_bar()->GetX() -content_view_->GetX())/(float)content_view_->GetWidth(); + texxform.voffset = (search_bar_->GetY() - content_view_->GetY())/(float)content_view_->GetHeight(); + + int start_x = active_lens_view_->filter_bar()->GetX(); + int final_x = content_view_->GetX() + content_view_->GetWidth() + PREVIEW_ICON_SPLIT_OFFSCREEN_OFFSET; + + int filter_x = (1.0f - animate_split_value_) * start_x + (animate_split_value_ * final_x); + + graphics_engine.QRP_1Tex + ( + filter_x, + search_bar_->GetY(), + active_lens_view_->filter_bar()->GetWidth(), + active_lens_view_->filter_bar()->GetY() + active_lens_view_->filter_bar()->GetHeight(), + content_view_->BackupTexture(), + texxform, + nux::Color((1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_)) + ); + + split_clip.width = filter_x; + } + else + { + // Search Bar + texxform.uoffset = (search_bar_->GetX() - content_view_->GetX())/(float)content_view_->GetWidth(); + texxform.voffset = (search_bar_->GetY() - content_view_->GetY())/(float)content_view_->GetHeight(); + + int start_y = search_bar_->GetY(); + int final_y = geo_layout.y - search_bar_->GetHeight() - PREVIEW_ICON_SPLIT_OFFSCREEN_OFFSET; + + graphics_engine.QRP_1Tex + ( + search_bar_->GetX(), + (1.0f - animate_split_value_) * start_y + (animate_split_value_ * final_y), + search_bar_->GetWidth(), + search_bar_->GetHeight(), + content_view_->BackupTexture(), + texxform, + nux::Color((1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_)) + ); + } - texxform.FlipVCoord(true); + graphics_engine.GetRenderStates().SetBlend(alpha, src, dest); + } +} - int filter_width = 10; - if (active_lens_view_ && active_lens_view_->filters_expanded) - { - texxform.uoffset = (active_lens_view_->filter_bar()->GetX() -layout_->GetX())/(float)layout_->GetWidth(); - texxform.voffset = (active_lens_view_->filter_bar()->GetY() -layout_->GetY())/(float)layout_->GetHeight(); - - texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); - - graphics_engine.QRP_1Tex( - active_lens_view_->filter_bar()->GetX() + (1.0f - fade_out_value_)*(active_lens_view_->filter_bar()->GetWidth() + 10), - active_lens_view_->filter_bar()->GetY(), - active_lens_view_->filter_bar()->GetWidth(), - active_lens_view_->filter_bar()->GetHeight(), - layout_copy_, texxform, - nux::Color(fade_out_value_, fade_out_value_, fade_out_value_, fade_out_value_) - ); - filter_width += active_lens_view_->filter_bar()->GetWidth(); - } +void DashView::DrawPreviewContainer(nux::GraphicsEngine& graphics_engine) +{ + if (animate_preview_container_value_ == 0.0f) + return; - float saturation = fade_out_value_ + (1.0f - fade_out_value_) * saturation_ref; - float opacity = fade_out_value_ < ghost_opacity ? ghost_opacity : fade_out_value_; - nux::Color tint = nux::Color( - fade_out_value_ + (1.0f - fade_out_value_) * tint_factor*bg_color.red, - fade_out_value_ + (1.0f - fade_out_value_) * tint_factor*bg_color.green, - fade_out_value_ + (1.0f - fade_out_value_) * tint_factor*bg_color.blue, - 1.0f); + nux::Geometry const& geo_content = content_view_->GetGeometry(); + nux::Geometry geo_abs = GetAbsoluteGeometry(); + nux::Geometry geo_abs_preview = preview_container_->GetLayoutGeometry(); - // Ghost row of items above the preview - { - int final_x = layout_->GetX(); - int final_y = layout_->GetY() - (opening_row_y_) - position_offset ; - - texxform.uoffset = 0.0f; - texxform.voffset = 0.0f; - texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); - - graphics_engine.QRP_TexDesaturate( - fade_out_value_ * layout_->GetX() + (1.0f - fade_out_value_) * final_x, - fade_out_value_ * layout_->GetY() + (1.0f - fade_out_value_) * final_y, - layout_->GetWidth() - filter_width, - opening_row_y_ + opening_row_height_, - layout_copy_, texxform, - nux::Color(tint.red, tint.green, tint.blue, opacity), - saturation - ); - } + unsigned int alpha, src, dest = 0; + graphics_engine.GetRenderStates().GetBlend(alpha, src, dest); + graphics_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - // Ghost row of items below the preview - { - int final_x = layout_->GetX(); - int final_y = layout_->GetY() + layout_->GetHeight() - (position_offset*1.9); - - texxform.uoffset = (layout_->GetX() - layout_->GetX())/(float)layout_->GetWidth(); - texxform.voffset = (opening_row_y_ + opening_row_height_ - layout_->GetY())/(float)layout_->GetHeight(); - texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); - - graphics_engine.QRP_TexDesaturate( - fade_out_value_ * layout_->GetX() + (1 - fade_out_value_) * final_x, - Interpolate2(1.0f - fade_out_value_, opening_row_y_ + opening_row_height_, final_y, layout_->GetHeight()), - layout_->GetWidth() - filter_width, - layout_->GetHeight() - opening_row_y_ - opening_row_height_, - layout_copy_, texxform, - nux::Color(tint.red, tint.green, tint.blue, opacity), - saturation - ); - } + // Triangle pointed at preview item + if (opening_column_x_ != -1) + { + int final_width = 14; + int final_height = 12; - graphics_engine.GetRenderStates().SetBlend(false); - graphics_engine.PopClippingRectangle(); - } + int x_center = geo_content.x + (opening_column_x_ - geo_abs.x) + opening_column_width_ / 2; + int start_y = geo_abs_preview.y - geo_abs.y; + int x1 = x_center - final_width/2; + int final_y1 = start_y; - } - else if (layout_ && layout_->RedirectRenderingToTexture() && fade_in_value_ != 0.0f) - { - if (layout_copy_.IsValid()) - { - graphics_engine.PushClippingRectangle(layout_->GetGeometry()); - graphics_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - nux::TexCoordXForm texxform; + int x2 = x_center + final_width/2; + int final_y2 = start_y; - texxform.FlipVCoord(true); + int x3 = x_center; + int final_y3 = start_y - final_height; - int filter_width = 10; - if (active_lens_view_ && active_lens_view_->filters_expanded) - { - texxform.uoffset = (active_lens_view_->filter_bar()->GetX() -layout_->GetX())/(float)layout_->GetWidth(); - texxform.voffset = (active_lens_view_->filter_bar()->GetY() -layout_->GetY())/(float)layout_->GetHeight(); - - texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); - - graphics_engine.QRP_1Tex( - active_lens_view_->filter_bar()->GetX() + (fade_in_value_)*(active_lens_view_->filter_bar()->GetWidth() + 10), - active_lens_view_->filter_bar()->GetY(), - active_lens_view_->filter_bar()->GetWidth(), - active_lens_view_->filter_bar()->GetHeight(), - layout_copy_, texxform, - nux::Color(1.0f - fade_in_value_, 1.0f - fade_in_value_, 1.0f - fade_in_value_, 1.0f - fade_in_value_) - ); - filter_width += active_lens_view_->filter_bar()->GetWidth(); - } + graphics_engine.QRP_Triangle + ( + x1, + (1.0f-animate_preview_container_value_) * start_y + (animate_preview_container_value_ * final_y1), - float saturation = fade_in_value_ * saturation_ref + (1.0f - fade_in_value_); - float opacity = (1.0f - fade_in_value_) < ghost_opacity ? ghost_opacity : (1.0f - fade_in_value_); - nux::Color tint = nux::Color( - fade_in_value_ * tint_factor*bg_color.red + (1.0f - fade_in_value_), - fade_in_value_ * tint_factor*bg_color.green + (1.0f - fade_in_value_), - fade_in_value_ * tint_factor*bg_color.blue + (1.0f - fade_in_value_), - 1.0f); + x2, + (1.0f-animate_preview_container_value_) * start_y + (animate_preview_container_value_ * final_y2), - // Ghost row of items above the preview - { - int final_x = layout_->GetX(); - int final_y = layout_->GetY() - (opening_row_y_) - position_offset; - - texxform.uoffset = 0.0f; - texxform.voffset = 0.0f; - texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); - - graphics_engine.QRP_TexDesaturate( - (1.0f - fade_in_value_) * layout_->GetX() + (fade_in_value_) * final_x, - (1.0f - fade_in_value_) * layout_->GetY() + (fade_in_value_) * final_y, - layout_->GetWidth() - filter_width, - opening_row_y_ + opening_row_height_, - layout_copy_, texxform, - nux::Color(tint.red, tint.green, tint.blue, opacity), - saturation - ); - } + x3, + (1.0f-animate_preview_container_value_) * start_y + (animate_preview_container_value_ * final_y3), - // Ghost row of items below the preview - { - int final_x = layout_->GetX(); - int final_y = layout_->GetY() + layout_->GetHeight() -(position_offset*1.9); - - texxform.uoffset = (layout_->GetX() - layout_->GetX())/(float)layout_->GetWidth(); - texxform.voffset = (opening_row_y_ + opening_row_height_ - layout_->GetY())/(float)layout_->GetHeight(); - texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); - - graphics_engine.QRP_TexDesaturate( - (1.0f - fade_in_value_) * layout_->GetX() + (fade_in_value_) * final_x, - Interpolate2(fade_in_value_, opening_row_y_ + opening_row_height_, final_y, layout_->GetHeight()), - layout_->GetWidth() - filter_width, - layout_->GetHeight() - opening_row_y_ - opening_row_height_, - layout_copy_, texxform, - nux::Color(tint.red, tint.green, tint.blue, opacity), - saturation - ); - } - graphics_engine.GetRenderStates().SetBlend(false); - graphics_engine.PopClippingRectangle(); - } + nux::Color(0.0f, 0.0f, 0.0f, 0.10f) + ); + } + + // Preview Background + int start_width = geo_content.width; + int start_x = geo_content.x; + int start_y = geo_abs_preview.y - geo_abs.y; + + int final_x = geo_content.x; + int final_y = start_y; + int final_width = geo_content.width; + int final_height = geo_abs_preview.height; + + graphics_engine.QRP_Color + ( + (1.0f-animate_preview_container_value_) * start_x + (animate_preview_container_value_ * final_x), + (1.0f-animate_preview_container_value_) * start_y + (animate_preview_container_value_ * final_y), + (1.0f-animate_preview_container_value_) * start_width + (animate_preview_container_value_ * final_width), + (animate_preview_container_value_ * final_height), + nux::Color(0.0f, 0.0f, 0.0f, 0.10f) + ); + + graphics_engine.GetRenderStates().SetBlend(alpha, src, dest); +} + +void DashView::DrawPreviewResultTextures(nux::GraphicsEngine& graphics_engine, bool /*force_draw*/) +{ + nux::Geometry const& geo_layout = layout_->GetGeometry(); + nux::Geometry geo_abs = GetAbsoluteGeometry(); + nux::Geometry geo_abs_preview = preview_container_->GetLayoutGeometry(); + + unsigned int alpha, src, dest = 0; + graphics_engine.GetRenderStates().GetBlend(alpha, src, dest); + graphics_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + nux::TexCoordXForm texxform; + texxform.FlipVCoord(true); + texxform.uoffset = 0.0f; + texxform.voffset = 0.0f; + texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); + + std::vector<ResultViewTexture::Ptr> result_textures = preview_lens_view_->GetResultTextureContainers(); + std::vector<ResultViewTexture::Ptr> top_textures; + + int height_concat_below = 0; + + // int i = 0; + for (auto it = result_textures.begin(); it != result_textures.end(); ++it) + { + ResultViewTexture::Ptr const& result_texture = *it; + if (!result_texture) + continue; + + // split above. + if (result_texture->abs_geo.y <= opening_row_y_) + { + top_textures.push_back(result_texture); + continue; } - graphics_engine.GetRenderStates().SetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); + // Bottom textures. + int start_x = result_texture->abs_geo.x - geo_abs.x; + int final_x = start_x; + + int start_y = result_texture->abs_geo.y - geo_abs.y; + int final_y = geo_abs_preview.y + geo_abs_preview.height - geo_abs.y; + final_y += std::min(60, ((geo_layout.y + geo_layout.height) - final_y)/4); + final_y += height_concat_below; + + nux::Geometry geo_tex_top((1.0f-animate_split_value_) * start_x + (animate_split_value_ * final_x), + (1.0f-animate_split_value_) * start_y + (animate_split_value_ * final_y), + result_texture->abs_geo.width, + result_texture->abs_geo.height); + + height_concat_below += geo_tex_top.height; + + // off the bottom + if (geo_tex_top.y <= geo_layout.y + geo_layout.height) + { + preview_lens_view_->RenderResultTexture(result_texture); + // If we haven't got it now, we're not going to get it + if (!result_texture->texture.IsValid()) + continue; + + graphics_engine.QRP_1Tex + ( + geo_tex_top.x, + geo_tex_top.y, + geo_tex_top.width, + geo_tex_top.height, + result_texture->texture, + texxform, + nux::Color(1.0f, 1.0f, 1.0f, 1.0f) + ); + } } - if (IsFullRedraw()) + // Top Textures (in reverse) + int height_concat_above = 0; + for (auto it = top_textures.rbegin(); it != top_textures.rend(); ++it) { - nux::GetPainter().PopBackgroundStack(); + ResultViewTexture::Ptr const& result_texture = *it; + + // each texture starts at a higher position. + height_concat_above += result_texture->abs_geo.height; + + int start_x = result_texture->abs_geo.x - geo_abs.x; + int final_x = start_x; + + int start_y = result_texture->abs_geo.y - geo_abs.y; + int final_y = -height_concat_above + (geo_abs_preview.y - geo_abs.y); + + nux::Geometry geo_tex_top((1.0f-animate_split_value_) * start_x + (animate_split_value_ * final_x), + (1.0f-animate_split_value_) * start_y + (animate_split_value_ * final_y), + result_texture->abs_geo.width, + result_texture->abs_geo.height); + + // off the top + if (geo_tex_top.y + geo_tex_top.height >= geo_layout.y) + { + preview_lens_view_->RenderResultTexture(result_texture); + // If we haven't got it now, we're not going to get it + if (!result_texture->texture.IsValid()) + continue; + + graphics_engine.QRP_1Tex + ( + geo_tex_top.x, + geo_tex_top.y, + geo_tex_top.width, + geo_tex_top.height, + result_texture->texture, + texxform, + nux::Color(1.0f, 1.0f, 1.0f, 1.0f) + ); + } } - graphics_engine.PopClippingRectangle(); + graphics_engine.GetRenderStates().SetBlend(alpha, src, dest); +} + +void DashView::DrawPreview(nux::GraphicsEngine& graphics_engine, bool force_draw) +{ + if (animate_preview_value_ > 0.0f) + { + bool animating = animate_split_value_ != 1.0f || animate_preview_value_ < 1.0f; + bool preview_force_draw = force_draw || animating || IsFullRedraw(); + + if (preview_force_draw) + nux::GetPainter().PushBackgroundStack(); + + if (animate_preview_value_ < 1.0f && preview_container_->RedirectRenderingToTexture()) + { + preview_container_->SetPresentRedirectedView(false); + preview_container_->ProcessDraw(graphics_engine, preview_force_draw); + + unsigned int alpha, src, dest = 0; + graphics_engine.GetRenderStates().GetBlend(alpha, src, dest); + graphics_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + nux::ObjectPtr<nux::IOpenGLBaseTexture> preview_texture = preview_container_->BackupTexture(); + if (preview_texture) + { + nux::TexCoordXForm texxform; + texxform.FlipVCoord(true); + texxform.uoffset = 0.0f; + texxform.voffset = 0.0f; + texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); + + nux::Geometry const& geo_preview = preview_container_->GetGeometry(); + graphics_engine.QRP_1Tex + ( + geo_preview.x, + geo_preview.y, + geo_preview.width, + geo_preview.height, + preview_texture, + texxform, + nux::Color(animate_preview_value_, animate_preview_value_, animate_preview_value_, animate_preview_value_) + ); + } + + preview_container_->SetPresentRedirectedView(true); + + graphics_engine.GetRenderStates().SetBlend(alpha, src, dest); + } + else + { + preview_container_->ProcessDraw(graphics_engine, preview_force_draw); + } - renderer_.DrawInnerCleanup(graphics_engine, content_geo_, GetAbsoluteGeometry(), GetGeometry()); + if (preview_force_draw) + nux::GetPainter().PopBackgroundStack(); + } } void DashView::OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key) @@ -943,12 +1211,12 @@ void DashView::OnLensAdded(Lens::Ptr& lens) std::string id = lens->id; lens_bar_->AddLens(lens); - LensView* view = new LensView(lens, search_bar_->show_filters()); - AddChild(view); + nux::ObjectPtr<LensView> view(new LensView(lens, search_bar_->show_filters())); + AddChild(view.GetPointer()); view->SetVisible(false); view->uri_activated.connect(sigc::mem_fun(this, &DashView::OnUriActivated)); - lenses_layout_->AddView(view, 1); + lenses_layout_->AddView(view.GetPointer(), 1); lens_views_[lens->id] = view; lens->activated.connect(sigc::mem_fun(this, &DashView::OnUriActivatedReply)); @@ -980,10 +1248,13 @@ void DashView::OnLensBarActivated(std::string const& id) return; } - lens_views_[id]->SetVisible(true); - active_lens_view_->SetVisible(false); - LensView* view = active_lens_view_ = lens_views_[id]; - view->JumpToTop(); + if (active_lens_view_.IsValid()) + active_lens_view_->SetVisible(false); + + nux::ObjectPtr<LensView> view = active_lens_view_ = lens_views_[id]; + + view->SetVisible(true); + view->AboutToShow(); for (auto it: lens_views_) { @@ -1022,7 +1293,7 @@ void DashView::OnSearchFinished(Lens::Hints const& hints, glib::Error const& err { hide_message_delay_.reset(); - if (active_lens_view_ == NULL) return; + if (!active_lens_view_.IsValid()) return; // FIXME: bind the lens_view in PerformSearch active_lens_view_->CheckNoResults(hints); @@ -1154,7 +1425,7 @@ void DashView::DisableBlur() } void DashView::OnEntryActivated() { - if (!search_in_progress_) + if (active_lens_view_.IsValid() && !search_in_progress_) { active_lens_view_->ActivateFirst(); } @@ -1223,7 +1494,7 @@ void DashView::AddProperties(GVariantBuilder* builder) dash::Style& style = dash::Style::Instance(); int num_rows = 1; // The search bar - if (active_lens_view_) + if (active_lens_view_.IsValid()) num_rows += active_lens_view_->GetNumRows(); std::string form_factor("unknown"); @@ -1250,7 +1521,7 @@ nux::Area* DashView::KeyNavIteration(nux::KeyNavDirection direction) { return preview_container_->KeyNavIteration(direction); } - else if (direction == nux::KEY_NAV_DOWN && search_bar_ && active_lens_view_) + else if (direction == nux::KEY_NAV_DOWN && search_bar_ && active_lens_view_.IsValid()) { auto show_filters = search_bar_->show_filters(); auto fscroll_view = active_lens_view_->fscroll_view(); @@ -1338,10 +1609,13 @@ nux::Area* DashView::FindKeyFocusArea(unsigned int key_symbol, if (direction != KEY_NAV_NONE && key_symbol == nux::NUX_KEYDOWN && !search_bar_->im_preedit) { std::list<nux::Area*> tabs; - for (auto category : active_lens_view_->categories()) + if (active_lens_view_.IsValid()) { - if (category->IsVisible()) - tabs.push_back(category); + for (auto category : active_lens_view_->categories()) + { + if (category->IsVisible()) + tabs.push_back(category); + } } if (search_bar_ && search_bar_->show_filters() && @@ -1350,7 +1624,8 @@ nux::Area* DashView::FindKeyFocusArea(unsigned int key_symbol, tabs.push_back(search_bar_->show_filters()); } - if (active_lens_view_->filter_bar() && active_lens_view_->fscroll_view() && + if (active_lens_view_.IsValid() && + active_lens_view_->filter_bar() && active_lens_view_->fscroll_view() && active_lens_view_->fscroll_view()->IsVisible()) { for (auto child : active_lens_view_->filter_bar()->GetLayout()->GetChildren()) diff --git a/dash/DashView.h b/dash/DashView.h index f0589b275..ee0484463 100644 --- a/dash/DashView.h +++ b/dash/DashView.h @@ -52,7 +52,7 @@ class DashLayout; class DashView : public nux::View, public unity::debug::Introspectable { NUX_DECLARE_OBJECT_TYPE(DashView, nux::View); - typedef std::map<std::string, LensView*> LensViews; + typedef std::map<std::string, nux::ObjectPtr<LensView>> LensViews; public: DashView(); @@ -65,9 +65,6 @@ public: void OnActivateRequest(GVariant* args); void SetMonitorOffset(int x, int y); - void SetPreview(Preview::Ptr preview); - void ClosePreview(); - std::string const GetIdForShortcutActivation(std::string const& shortcut) const; std::vector<char> GetAllShortcuts(); @@ -93,7 +90,17 @@ private: virtual long PostLayoutManagement (long LayoutResult); nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type); + // Dash animations + void DrawDashSplit(nux::GraphicsEngine& graphics_engine, nux::Geometry& split_clip); + void DrawPreviewContainer(nux::GraphicsEngine& graphics_engine); + void DrawPreviewResultTextures(nux::GraphicsEngine& gfx_context, bool force_draw); + void DrawPreview(nux::GraphicsEngine& gfx_context, bool force_draw); + void StartPreviewAnimation(); + void EndPreviewAnimation(); + void BuildPreview(Preview::Ptr model); + void ClosePreview(); + void OnPreviewAnimationFinished(); void OnMouseButtonDown(int x, int y, unsigned long button, unsigned long key); void OnBackgroundColorChanged(GVariant* args); void OnSearchChanged(std::string const& search_string); @@ -134,13 +141,15 @@ private: nux::VLayout* layout_; DashLayout* content_layout_; + nux::View* content_view_; nux::HLayout* search_bar_layout_; SearchBar* search_bar_; nux::VLayout* lenses_layout_; LensBar* lens_bar_; - LensView* home_view_; - LensView* active_lens_view_; + nux::ObjectPtr<LensView> home_view_; + nux::ObjectPtr<LensView> active_lens_view_; + nux::ObjectPtr<LensView> preview_lens_view_; // Drawing related nux::Geometry content_geo_; @@ -161,20 +170,21 @@ private: nux::ObjectPtr<nux::IOpenGLBaseTexture> filter_view_copy_; nux::ObjectPtr<nux::IOpenGLBaseTexture> layout_copy_; - float fade_out_value_; - float fade_in_value_; - na::AnimateValue<float> animation_; - - void FadeOutCallBack(float const& fade_out_value); - void FadeInCallBack(float const& fade_out_value); - + int opening_column_x_; int opening_row_y_; + int opening_column_width_; int opening_row_height_; - sigc::connection fade_in_connection_; - sigc::connection fade_out_connection_; - nux::Color background_color_; + + std::unique_ptr<na::AnimateValue<float>> split_animation_; + float animate_split_value_; + + std::unique_ptr<na::AnimateValue<float>> preview_container_animation_; + float animate_preview_container_value_; + + std::unique_ptr<na::AnimateValue<float>> preview_animation_; + float animate_preview_value_; }; diff --git a/dash/LensView.cpp b/dash/LensView.cpp index 17e34a08a..bdc15a257 100755 --- a/dash/LensView.cpp +++ b/dash/LensView.cpp @@ -157,6 +157,7 @@ LensView::LensView(Lens::Ptr lens, nux::Area* show_filters) , no_results_active_(false) , last_expanded_group_(nullptr) , last_good_filter_model_(-1) + , filter_expansion_pushed_(false) { SetupViews(show_filters); SetupCategories(); @@ -656,9 +657,8 @@ void LensView::OnGroupExpanded(PlacesGroup* group) { ResultViewGrid* grid = static_cast<ResultViewGrid*>(group->GetChildView()); grid->expanded = group->GetExpanded(); - ubus_manager_.SendMessage(UBUS_PLACE_VIEW_QUEUE_DRAW); - CheckScrollBarState(); + QueueRelayout(); } void LensView::CheckScrollBarState() @@ -834,6 +834,100 @@ bool LensView::AcceptKeyNavFocus() return false; } +void LensView::ForceCategoryExpansion(std::string const& view_id, bool expand) +{ + for (auto it = categories_.begin(); it != categories_.end(); ++it) + { + if ((*it)->GetChildView()->unique_id == view_id) + { if (expand) + { + (*it)->PushExpanded(); + (*it)->SetExpanded(true); + } + else + { + (*it)->PopExpanded(); + } + } + } +} + +void LensView::SetResultsPreviewAnimationValue(float preview_animation) +{ + for (auto it = categories_.begin(); it != categories_.end(); ++it) + { + (*it)->SetResultsPreviewAnimationValue(preview_animation); + } +} + +void LensView::EnableResultTextures(bool enable_result_textures) +{ + scroll_view_->EnableScrolling(!enable_result_textures); + + for (auto it = categories_.begin(); it != categories_.end(); ++it) + { + ResultView* result_view = (*it)->GetChildView(); + if (result_view) + { + result_view->enable_texture_render = enable_result_textures; + } + } +} + +std::vector<ResultViewTexture::Ptr> LensView::GetResultTextureContainers() +{ + // iterate in visual order + std::vector<ResultViewTexture::Ptr> textures; + auto category_order = lens_->GetCategoriesOrder(); + for (unsigned int i = 0; i < category_order.size(); i++) + { + unsigned category_index = category_order.at(i); + if (categories_.size() <= category_index) + continue; + + PlacesGroup* category = categories_.at(category_index); + if (!category || !category->IsVisible()) + continue; + + ResultView* result_view = category->GetChildView(); + if (result_view) + { + // concatenate textures + std::vector<ResultViewTexture::Ptr> const& category_textures = result_view->GetResultTextureContainers(); + for (auto it = category_textures.begin(); it != category_textures.end(); ++it) + { + ResultViewTexture::Ptr const& result_texture = *it; + result_texture->category_index = category_index; + textures.push_back(result_texture); + } + } + } + return textures; +} + +void LensView::RenderResultTexture(ResultViewTexture::Ptr const& result_texture) +{ + ResultView* result_view = GetResultViewForCategory(result_texture->category_index); + if (result_view) + result_view->RenderResultTexture(result_texture); +} + +void LensView::PushFilterExpansion(bool expand) +{ + filter_expansion_pushed_ = filters_expanded; + filters_expanded = expand; +} + +void LensView::PopFilterExpansion() +{ + filters_expanded = GetPushedFilterExpansion(); +} + +bool LensView::GetPushedFilterExpansion() const +{ + return filter_expansion_pushed_; +} + PlacesGroup* LensView::CreatePlacesGroup() { return new PlacesGroup(dash::Style::Instance()); diff --git a/dash/LensView.h b/dash/LensView.h index a31ffc07b..ada5b2e46 100644 --- a/dash/LensView.h +++ b/dash/LensView.h @@ -76,6 +76,17 @@ public: void CheckCategoryExpansion(); void HideResultsMessage(); + void ForceCategoryExpansion(std::string const& view_id, bool expand); + void PushFilterExpansion(bool expand); + void PopFilterExpansion(); + bool GetPushedFilterExpansion() const; + + void SetResultsPreviewAnimationValue(float preview_animation); + + void EnableResultTextures(bool enable_result_textures); + std::vector<ResultViewTexture::Ptr> GetResultTextureContainers(); + void RenderResultTexture(ResultViewTexture::Ptr const& result_texture); + private: void SetupViews(nux::Area* show_filters); void SetupCategories(); @@ -132,6 +143,8 @@ private: int last_good_filter_model_; glib::Source::UniquePtr fix_filter_models_idle_; + bool filter_expansion_pushed_; + friend class TestLensView; }; diff --git a/dash/PlacesGroup.cpp b/dash/PlacesGroup.cpp index 6499f2b03..8082d521e 100755 --- a/dash/PlacesGroup.cpp +++ b/dash/PlacesGroup.cpp @@ -55,7 +55,6 @@ namespace const nux::Color kExpandDefaultTextColor(1.0f, 1.0f, 1.0f, 0.5f); const float kExpandDefaultIconOpacity = 0.5f; -const int kCategoryIconSize = 22; // Category highlight const int kHighlightHeight = 24; const int kHighlightRightPadding = 10 - 3; // -3 because the scrollbar is not a real overlay scrollbar! @@ -116,9 +115,11 @@ NUX_IMPLEMENT_OBJECT_TYPE(PlacesGroup); PlacesGroup::PlacesGroup(dash::StyleInterface& style) : nux::View(NUX_TRACKER_LOCATION), _style(style), + _child_layout(nullptr), _child_view(nullptr), _using_filters_background(false), _is_expanded(false), + _is_expanded_pushed(false), _n_visible_items_in_unexpand_mode(0), _n_total_items(0), _category_index(0), @@ -147,8 +148,7 @@ PlacesGroup::PlacesGroup(dash::StyleInterface& style) _group_layout = new nux::VLayout("", NUX_TRACKER_LOCATION); - // -2 because the icons have an useless border. - int top_space = style.GetPlacesGroupTopSpace() - 2; + int top_space = style.GetPlacesGroupTopSpace(); _group_layout->AddLayout(new nux::SpaceLayout(top_space, top_space, top_space, top_space), 0); _header_view = new HeaderView(NUX_TRACKER_LOCATION); @@ -159,8 +159,8 @@ PlacesGroup::PlacesGroup(dash::StyleInterface& style) _header_layout->SetSpaceBetweenChildren(10); _header_view->SetLayout(_header_layout); - _icon = new IconTexture("", kCategoryIconSize); - _icon->SetMinMaxSize(kCategoryIconSize, kCategoryIconSize); + _icon = new IconTexture("", _style.GetCategoryIconSize()); + _icon->SetMinMaxSize(_style.GetCategoryIconSize(), _style.GetCategoryIconSize()); _header_layout->AddView(_icon, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX); _text_layout = new nux::HLayout(NUX_TRACKER_LOCATION); @@ -276,29 +276,30 @@ PlacesGroup::GetExpandLabel() void PlacesGroup::SetIcon(std::string const& path_to_emblem) { - _icon->SetByIconName(path_to_emblem, kCategoryIconSize); + _icon->SetByIconName(path_to_emblem, _style.GetCategoryIconSize()); } void PlacesGroup::SetChildView(dash::ResultView* view) { - if (_child_view != NULL) - { - _group_layout->RemoveChildObject(_child_view); - } - - debug::Introspectable *i = dynamic_cast<debug::Introspectable*>(view); - if (i) - AddChild(i); + if (_child_view) + { + RemoveChild(_child_view); + } + if (_child_layout != NULL) + { + _group_layout->RemoveChildObject(_child_layout); + } + AddChild(view); _child_view = view; - nux::VLayout* layout = new nux::VLayout(); - layout->AddView(_child_view, 0); + _child_layout = new nux::VLayout(); + _child_layout->AddView(_child_view, 0); - layout->SetLeftAndRightPadding(25, 0); - _group_layout->AddLayout(new nux::SpaceLayout(2,2,2,2), 0); // top padding - _group_layout->AddLayout(layout, 1); + _child_layout->SetTopAndBottomPadding(_style.GetPlacesGroupResultTopPadding(),0); + _child_layout->SetLeftAndRightPadding(_style.GetPlacesGroupResultLeftPadding(), 0); + _group_layout->AddLayout(_child_layout, 1); view->results_per_row.changed.connect([&] (int results_per_row) { @@ -309,7 +310,7 @@ PlacesGroup::SetChildView(dash::ResultView* view) QueueDraw(); } -nux::View* +dash::ResultView* PlacesGroup::GetChildView() { return _child_view; @@ -556,6 +557,18 @@ PlacesGroup::SetExpanded(bool is_expanded) } void +PlacesGroup::PushExpanded() +{ + _is_expanded_pushed = GetExpanded(); +} + +void +PlacesGroup::PopExpanded() +{ + SetExpanded(_is_expanded_pushed); +} + +void PlacesGroup::RecvMouseClick(int x, int y, unsigned long button_flags, unsigned long key_flags) { SetExpanded(!_is_expanded); @@ -599,6 +612,12 @@ bool PlacesGroup::ShouldBeHighlighted() const return HeaderHasKeyFocus(); } +void PlacesGroup::SetResultsPreviewAnimationValue(float preview_animation) +{ + if (_child_view) + _child_view->desaturation_progress = preview_animation; +} + void PlacesGroup::SetFiltersExpanded(bool filters_expanded) { nux::ROPConfig rop; diff --git a/dash/PlacesGroup.h b/dash/PlacesGroup.h index 226079c05..e76f3ca7c 100644 --- a/dash/PlacesGroup.h +++ b/dash/PlacesGroup.h @@ -67,7 +67,7 @@ public: StaticCairoText* GetExpandLabel(); void SetChildView(dash::ResultView* view); - nux::View* GetChildView(); + dash::ResultView* GetChildView(); void SetChildLayout(nux::Layout* layout); @@ -82,6 +82,11 @@ public: void SetExpanded(bool is_expanded); bool GetExpanded() const; + void PushExpanded(); + void PopExpanded(); + + void SetResultsPreviewAnimationValue(float preview_animation); + int GetHeaderHeight() const; bool HeaderIsFocusable() const; nux::View* GetHeaderFocusableView() const; @@ -93,6 +98,7 @@ public: protected: long ComputeContentSize(); + void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw); void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw); @@ -127,7 +133,8 @@ private: nux::HLayout* _text_layout; nux::HLayout* _expand_label_layout; nux::HLayout* _expand_layout; - nux::View* _child_view; + nux::VLayout* _child_layout; + dash::ResultView* _child_view; std::unique_ptr<nux::AbstractPaintLayer> _focus_layer; IconTexture* _icon; @@ -141,6 +148,7 @@ private: std::unique_ptr<nux::TextureLayer> _background_layer; bool _is_expanded; + bool _is_expanded_pushed; unsigned _n_visible_items_in_unexpand_mode; unsigned _n_total_items; unsigned _category_index; diff --git a/dash/ResultRenderer.cpp b/dash/ResultRenderer.cpp index a7bc6e965..7ddc35391 100644 --- a/dash/ResultRenderer.cpp +++ b/dash/ResultRenderer.cpp @@ -126,7 +126,9 @@ ResultRenderer::ResultRenderer(NUX_FILE_LINE_DECL) void ResultRenderer::Render(nux::GraphicsEngine& GfxContext, Result& /*row*/, ResultRendererState /*state*/, - nux::Geometry const& geometry, int /*x_offset*/, int /*y_offset*/) + nux::Geometry const& geometry, int /*x_offset*/, int /*y_offset*/, + nux::Color const& color, + float saturate) { nux::GetPainter().PushDrawSliceScaledTextureLayer(GfxContext, geometry, nux::eBUTTON_NORMAL, nux::color::White, nux::eAllCorners); } diff --git a/dash/ResultRenderer.h b/dash/ResultRenderer.h index 6ba94aa77..a26429b6f 100644 --- a/dash/ResultRenderer.h +++ b/dash/ResultRenderer.h @@ -44,7 +44,7 @@ public: RESULT_RENDERER_ACTIVE, RESULT_RENDERER_PRELIGHT, RESULT_RENDERER_SELECTED, - RESULT_RENDERER_INSENSITIVE, + RESULT_RENDERER_INSENSITIVE }; ResultRenderer(NUX_FILE_LINE_PROTO); @@ -53,7 +53,9 @@ public: Result& row, ResultRendererState state, nux::Geometry const& geometry, - int x_offset, int y_offset); + int x_offset, int y_offset, + nux::Color const& color, + float saturate); // this is just to start preloading images and text that the renderer might // need - can be ignored diff --git a/dash/ResultRendererHorizontalTile.cpp b/dash/ResultRendererHorizontalTile.cpp index 93201af58..65f4e26a4 100644 --- a/dash/ResultRendererHorizontalTile.cpp +++ b/dash/ResultRendererHorizontalTile.cpp @@ -44,6 +44,41 @@ const int CARD_VIEW_HEIGHT = 74; // pixels const int CARD_VIEW_HIGHLIGHT_CORNER_RADIUS = 2; // pixels const int CARD_VIEW_ICON_OUTLINE_WIDTH = 1; // pixels const int CARD_VIEW_TEXT_LINE_SPACING = 0; // points + +void RenderTexture(nux::GraphicsEngine& GfxContext, + int x, + int y, + int width, + int height, + nux::ObjectPtr<nux::IOpenGLBaseTexture> const& texture, + nux::TexCoordXForm &texxform, + const nux::Color &color, + float saturate +) +{ + if (saturate == 1.0) + { + GfxContext.QRP_1Tex(x, + y, + width, + height, + texture, + texxform, + color); + } + else + { + GfxContext.QRP_TexDesaturate(x, + y, + width, + height, + texture, + texxform, + color, + saturate); + } +} + } namespace dash @@ -74,7 +109,9 @@ void ResultRendererHorizontalTile::Render(nux::GraphicsEngine& GfxContext, Result& row, ResultRendererState state, nux::Geometry const& geometry, - int x_offset, int y_offset) + int x_offset, int y_offset, + nux::Color const& color, + float saturate) { TextureContainer* container = row.renderer<TextureContainer*>(); if (container == nullptr) @@ -100,13 +137,15 @@ void ResultRendererHorizontalTile::Render(nux::GraphicsEngine& GfxContext, GfxContext.GetRenderStates().GetBlend(alpha, src, dest); GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - GfxContext.QRP_1Tex(x, - y, - w, - h, - normal_cache_->GetDeviceTexture(), - texxform, - nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); + RenderTexture(GfxContext, + x, + y, + w, + h, + normal_cache_->GetDeviceTexture(), + texxform, + color, + saturate); GfxContext.GetRenderStates().SetBlend(alpha, src, dest); } @@ -119,13 +158,15 @@ void ResultRendererHorizontalTile::Render(nux::GraphicsEngine& GfxContext, int w = CARD_VIEW_WIDTH; int h = CARD_VIEW_HEIGHT; - GfxContext.QRP_1Tex(x, - y, - w, - h, - prelight_cache_->GetDeviceTexture(), - texxform, - nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); + RenderTexture(GfxContext, + x, + y, + w, + h, + prelight_cache_->GetDeviceTexture(), + texxform, + color, + saturate); } // draw the icon @@ -141,13 +182,15 @@ void ResultRendererHorizontalTile::Render(nux::GraphicsEngine& GfxContext, w + 2 * CARD_VIEW_ICON_OUTLINE_WIDTH, h + 2 * CARD_VIEW_ICON_OUTLINE_WIDTH, nux::color::Black); - GfxContext.QRP_1Tex(x, - y, - w, - h, - container->icon->GetDeviceTexture(), - texxform, - nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); + RenderTexture(GfxContext, + x, + y, + w, + h, + container->icon->GetDeviceTexture(), + texxform, + color, + saturate); } if (container->text) @@ -157,13 +200,15 @@ void ResultRendererHorizontalTile::Render(nux::GraphicsEngine& GfxContext, int w = container->text->GetWidth(); int h = container->text->GetHeight(); - GfxContext.QRP_1Tex(x, - y, - w, - h, - container->text->GetDeviceTexture(), - texxform, - nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); + RenderTexture(GfxContext, + x, + y, + w, + h, + container->text->GetDeviceTexture(), + texxform, + color, + saturate); } } diff --git a/dash/ResultRendererHorizontalTile.h b/dash/ResultRendererHorizontalTile.h index 88c7f5b86..3efbeb278 100644 --- a/dash/ResultRendererHorizontalTile.h +++ b/dash/ResultRendererHorizontalTile.h @@ -44,7 +44,9 @@ public: Result& row, ResultRendererState state, nux::Geometry const& geometry, - int x_offset, int y_offset); + int x_offset, int y_offset, + nux::Color const& color, + float saturate); virtual nux::NBitmapData* GetDndImage(Result const& row) const; diff --git a/dash/ResultRendererTile.cpp b/dash/ResultRendererTile.cpp index c5ce010f3..a3c9781a1 100644 --- a/dash/ResultRendererTile.cpp +++ b/dash/ResultRendererTile.cpp @@ -41,11 +41,47 @@ bool neko; namespace unity { DECLARE_LOGGER(logger, "unity.dash.results"); + namespace { const int FONT_SIZE = 10; const float CORNER_HIGHTLIGHT_RADIUS = 2.0f; + +void RenderTexture(nux::GraphicsEngine& GfxContext, + int x, + int y, + int width, + int height, + nux::ObjectPtr<nux::IOpenGLBaseTexture> const& texture, + nux::TexCoordXForm &texxform, + const nux::Color &color, + float saturate +) +{ + if (saturate == 1.0) + { + GfxContext.QRP_1Tex(x, + y, + width, + height, + texture, + texxform, + color); + } + else + { + GfxContext.QRP_TexDesaturate(x, + y, + width, + height, + texture, + texxform, + color, + saturate); + } +} + } namespace dash @@ -72,7 +108,9 @@ void ResultRendererTile::Render(nux::GraphicsEngine& GfxContext, Result& row, ResultRendererState state, nux::Geometry const& geometry, - int x_offset, int y_offset) + int x_offset, int y_offset, + nux::Color const& color, + float saturate) { TextureContainer* container = row.renderer<TextureContainer*>(); if (container == nullptr) @@ -104,36 +142,42 @@ void ResultRendererTile::Render(nux::GraphicsEngine& GfxContext, int highlight_x = (geometry.x + geometry.width/2) - style.GetTileIconHightlightWidth()/2; int highlight_y = (geometry.y + padding + tile_icon_size / 2) - style.GetTileIconHightlightHeight()/2; - GfxContext.QRP_1Tex(highlight_x, - highlight_y, - container->prelight->GetWidth(), - container->prelight->GetHeight(), - container->prelight->GetDeviceTexture(), - texxform, - nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); + RenderTexture(GfxContext, + highlight_x, + highlight_y, + container->prelight->GetWidth(), + container->prelight->GetHeight(), + container->prelight->GetDeviceTexture(), + texxform, + color, + saturate); } // draw the icon if (container->icon) { - GfxContext.QRP_1Tex(icon_left_hand_side, - icon_top_side, - container->icon->GetWidth(), - container->icon->GetHeight(), - container->icon->GetDeviceTexture(), - texxform, - nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); + RenderTexture(GfxContext, + icon_left_hand_side, + icon_top_side, + container->icon->GetWidth(), + container->icon->GetHeight(), + container->icon->GetDeviceTexture(), + texxform, + color, + saturate); } if (container->text) { - GfxContext.QRP_1Tex(geometry.x + padding, - geometry.y + tile_icon_size + spacing, - style.GetTileWidth() - (padding * 2), - style.GetTileHeight() - tile_icon_size - spacing, - container->text->GetDeviceTexture(), - texxform, - nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); + RenderTexture(GfxContext, + geometry.x + padding, + geometry.y + tile_icon_size + spacing, + style.GetTileWidth() - (padding * 2), + style.GetTileHeight() - tile_icon_size - spacing, + container->text->GetDeviceTexture(), + texxform, + color, + saturate); } } diff --git a/dash/ResultRendererTile.h b/dash/ResultRendererTile.h index 86a003d9e..4349d66c4 100644 --- a/dash/ResultRendererTile.h +++ b/dash/ResultRendererTile.h @@ -65,7 +65,9 @@ public: Result& row, ResultRendererState state, nux::Geometry const& geometry, - int x_offset, int y_offset); + int x_offset, int y_offset, + nux::Color const& color, + float saturate); virtual void Preload(Result& row); virtual void Unload(Result& row); diff --git a/dash/ResultView.cpp b/dash/ResultView.cpp index a53754632..4118f5fc3 100644 --- a/dash/ResultView.cpp +++ b/dash/ResultView.cpp @@ -27,6 +27,7 @@ #include <UnityCore/Variant.h> #include "unity-shared/IntrospectableWrappers.h" +#include "unity-shared/GraphicsUtils.h" namespace unity { @@ -38,6 +39,8 @@ NUX_IMPLEMENT_OBJECT_TYPE(ResultView); ResultView::ResultView(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) , expanded(true) + , desaturation_progress(0.0) + , enable_texture_render(false) , renderer_(NULL) , cached_result_(nullptr, nullptr, nullptr) { @@ -46,6 +49,13 @@ ResultView::ResultView(NUX_FILE_LINE_DECL) QueueRelayout(); NeedRedraw(); }); + + desaturation_progress.changed.connect([&](float value) + { + NeedRedraw(); + }); + + enable_texture_render.changed.connect(sigc::mem_fun(this, &ResultView::OnEnableRenderToTexture)); } ResultView::~ResultView() @@ -61,11 +71,6 @@ ResultView::~ResultView() renderer_->UnReference(); } -void ResultView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) -{ - -} - void ResultView::SetModelRenderer(ResultRenderer* renderer) { if (renderer_ != NULL) @@ -187,6 +192,10 @@ long ResultView::ComputeContentSize() return View::ComputeContentSize(); } +void ResultView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) +{ + +} void ResultView::DrawContent(nux::GraphicsEngine& GfxContent, bool force_draw) { @@ -199,6 +208,80 @@ void ResultView::DrawContent(nux::GraphicsEngine& GfxContent, bool force_draw) GfxContent.PopClippingRectangle(); } +void ResultView::OnEnableRenderToTexture(bool enable_render_to_texture) +{ + if (!enable_render_to_texture) + { + result_textures_.clear(); + } +} + +std::vector<ResultViewTexture::Ptr> const& ResultView::GetResultTextureContainers() +{ + UpdateRenderTextures(); + return result_textures_; +} + +void ResultView::RenderResultTexture(ResultViewTexture::Ptr const& result_texture) +{ + // Do we need to re-create the texture? + if (!result_texture->texture.IsValid() || + result_texture->texture->GetWidth() != GetWidth() || + result_texture->texture->GetHeight() != GetHeight()) + { + result_texture->texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(GetHeight(), + GetWidth(), + 1, + nux::BITFMT_R8G8B8A8); + + if (!result_texture->texture.IsValid()) + return; + } + + nux::GetPainter().PushBackgroundStack(); + + graphics::PushOffscreenRenderTarget(result_texture->texture); + + // clear the texture. + CHECKGL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); + CHECKGL(glClear(GL_COLOR_BUFFER_BIT)); + + nux::GraphicsEngine& graphics_engine(nux::GetWindowThread()->GetGraphicsEngine()); + nux::Geometry offset_rect = graphics_engine.ModelViewXFormRect(GetGeometry()); + graphics_engine.PushModelViewMatrix(nux::Matrix4::TRANSLATE(-offset_rect.x, -offset_rect.y, 0)); + + ProcessDraw(graphics_engine, true); + + graphics_engine.PopModelViewMatrix(); + graphics::PopOffscreenRenderTarget(); + + nux::GetPainter().PopBackgroundStack(); +} + +void ResultView::UpdateRenderTextures() +{ + if (!enable_texture_render) + return; + + nux::Geometry root_geo(GetAbsoluteGeometry()); + + if (result_textures_.size() > 0) + { + ResultViewTexture::Ptr const& result_texture = result_textures_[0]; + result_texture->abs_geo.x = root_geo.x; + result_texture->abs_geo.y = root_geo.y; + result_texture->abs_geo.width = GetWidth(); + result_texture->abs_geo.height = GetHeight(); + } + else + { + ResultViewTexture::Ptr result_texture(new ResultViewTexture); + result_texture->abs_geo = root_geo; + result_texture->row_index = 0; + result_textures_.push_back(result_texture); + } +} + std::string ResultView::GetName() const { return "ResultView"; diff --git a/dash/ResultView.h b/dash/ResultView.h index 9fdcc0b83..9b651dbc1 100644 --- a/dash/ResultView.h +++ b/dash/ResultView.h @@ -43,6 +43,18 @@ class ResultWrapper; namespace dash { + +struct ResultViewTexture +{ + typedef std::shared_ptr<ResultViewTexture> Ptr; + + unsigned int category_index; + nux::Geometry abs_geo; + int row_index; + nux::ObjectPtr<nux::IOpenGLBaseTexture> texture; +}; + + class ResultView : public nux::View, public debug::Introspectable { public: @@ -66,6 +78,8 @@ public: nux::Property<bool> expanded; nux::Property<int> results_per_row; nux::Property<std::string> unique_id; + nux::Property<float> desaturation_progress; + nux::Property<bool> enable_texture_render; sigc::signal<void, std::string const&, ActivateType, GVariant*> UriActivated; std::string GetName() const; @@ -75,10 +89,15 @@ public: virtual void Activate(std::string const& uri, int index, ActivateType type) = 0; + std::vector<ResultViewTexture::Ptr> const& GetResultTextureContainers(); + virtual void RenderResultTexture(ResultViewTexture::Ptr const& result_texture); + protected: virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw); - virtual long ComputeContentSize(); + virtual long ComputeContentSize(); + + virtual void UpdateRenderTextures(); virtual void AddResult(Result& result); virtual void RemoveResult(Result& result); @@ -89,12 +108,16 @@ protected: virtual debug::ResultWrapper* CreateResultWrapper(Result const& result, int index); virtual void UpdateResultWrapper(debug::ResultWrapper* wrapper, Result const& result, int index); + void OnEnableRenderToTexture(bool enable_render_to_texture); + // properties ResultRenderer* renderer_; glib::Object<DeeModel> result_model_; DeeModelTag* renderer_tag_; glib::SignalManager sig_manager_; std::map<std::string, debug::ResultWrapper*> introspectable_children_; + + std::vector<ResultViewTexture::Ptr> result_textures_; private: void OnRowAdded(DeeModel* model, DeeModelIter* iter); diff --git a/dash/ResultViewGrid.cpp b/dash/ResultViewGrid.cpp index 7d273f451..cb73422ed 100644 --- a/dash/ResultViewGrid.cpp +++ b/dash/ResultViewGrid.cpp @@ -33,6 +33,7 @@ #include "unity-shared/Timer.h" #include "unity-shared/UBusWrapper.h" #include "unity-shared/UBusMessages.h" +#include "unity-shared/GraphicsUtils.h" #include "ResultViewGrid.h" #include "math.h" @@ -42,6 +43,16 @@ namespace unity { namespace dash { + +namespace +{ + const float UNFOCUSED_GHOST_ICON_OPACITY_REF = 0.3f; + const float UNFOCUSED_ICON_SATURATION_REF = 0.05f; + + const float FOCUSED_GHOST_ICON_OPACITY_REF = 0.7f; + const float FOCUSED_ICON_SATURATION_REF = 0.5f; +} + NUX_IMPLEMENT_OBJECT_TYPE(ResultViewGrid); ResultViewGrid::ResultViewGrid(NUX_FILE_LINE_DECL) @@ -102,6 +113,16 @@ ResultViewGrid::ResultViewGrid(NUX_FILE_LINE_DECL) g_variant_get (data, "(ii)", &recorded_dash_width_, &recorded_dash_height_); }); + // We are interested in the color of the desktop background. + ubus_.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED, [this] (GVariant* data) { + double red = 0.0f, green = 0.0f, blue = 0.0f, alpha = 0.0f; + + g_variant_get(data, "(dddd)", &red, &green, &blue, &alpha); + background_color_ = nux::Color(red, green, blue, alpha); + QueueDraw(); + }); + ubus_.SendMessage(UBUS_BACKGROUND_REQUEST_COLOUR_EMIT); + ubus_.RegisterInterest(UBUS_DASH_PREVIEW_NAVIGATION_REQUEST, [&] (GVariant* data) { int nav_mode = 0; gchar* uri = NULL; @@ -137,6 +158,7 @@ ResultViewGrid::ResultViewGrid(NUX_FILE_LINE_DECL) } else { + selected_index_ = active_index_ = current_index; activated_uri_ = GetUriForIndex(current_index); LOG_DEBUG(logger) << "activating preview for index: " << "(" << current_index << ")" @@ -162,22 +184,31 @@ void ResultViewGrid::Activate(std::string const& uri, int index, ResultView::Act int right_results = num_results ? (num_results - index) - 1 : 0; //FIXME - just uses y right now, needs to use the absolute position of the bottom of the result // (jay) Here is the fix: Compute the y position of the row where the item is located. - int row_y = padding + GetRootGeometry().y; + nux::Geometry abs_geo = GetAbsoluteGeometry(); + int row_y = padding + abs_geo.y; + int column_x = padding + abs_geo.x; int row_height = renderer_->height + vertical_spacing; + int column_width = renderer_->width + horizontal_spacing; if (GetItemsPerRow()) { - int num_row = GetNumResults() / GetItemsPerRow(); - if (GetNumResults() % GetItemsPerRow()) + int num_results = GetNumResults(); + int items_per_row = GetItemsPerRow(); + + int num_row = num_results / items_per_row; + if (num_results % items_per_row) { ++num_row; } - int row_index = index / GetItemsPerRow(); + int column_index = index % items_per_row; + int row_index = index / items_per_row; + column_x += column_index * column_width; row_y += row_index * row_height; } - glib::Variant data(g_variant_new("(iiii)", row_y, row_height, left_results, right_results)); + active_index_ = index; + glib::Variant data(g_variant_new("(iiiiii)", column_x, row_y, column_width, row_height, left_results, right_results)); UriActivated.emit(uri, type, data); } @@ -608,84 +639,130 @@ void ResultViewGrid::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) unsigned num_results = GetNumResults(); int total_rows = (!expanded) ? 0 : (num_results / items_per_row) + 1; - //find the row we start at - int absolute_y = GetAbsoluteY(); int row_size = renderer_->height + vertical_spacing; - int y_position = padding + GetGeometry().y; ResultListBounds visible_bounds = GetVisableResults(); + nux::Geometry absolute_geometry(GetAbsoluteGeometry()); + for (int row_index = 0; row_index <= total_rows; row_index++) { - int row_lower_bound = row_index * items_per_row; - if (row_lower_bound >= std::get<0>(visible_bounds) && - row_lower_bound <= std::get<1>(visible_bounds)) + DrawRow(GfxContext, visible_bounds, row_index, y_position, absolute_geometry); + + y_position += row_size; + } +} + +void ResultViewGrid::DrawRow(nux::GraphicsEngine& GfxContext, ResultListBounds const& visible_bounds, int row_index, int y_position, nux::Geometry const& absolute_position) +{ + unsigned int current_alpha_blend; + unsigned int current_src_blend_factor; + unsigned int current_dest_blend_factor; + GfxContext.GetRenderStates().GetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); + GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + float saturation_progress = 1.0 - desaturation_progress(); + float saturation = 1.0; + float opacity = 1.0; + + int items_per_row = GetItemsPerRow(); + + int row_lower_bound = row_index * items_per_row; + if (row_lower_bound >= std::get<0>(visible_bounds) && + row_lower_bound <= std::get<1>(visible_bounds)) + { + int x_position = padding + GetGeometry().x; + for (int column_index = 0; column_index < items_per_row; column_index++) { - int x_position = padding + GetGeometry().x; - for (int column_index = 0; column_index < items_per_row; column_index++) - { - unsigned index = (row_index * items_per_row) + column_index; - if (index >= num_results) - break; + int index = (row_index * items_per_row) + column_index; + if (index < 0 || index >= (int)GetNumResults()) + break; - ResultRenderer::ResultRendererState state = ResultRenderer::RESULT_RENDERER_NORMAL; - if ((int)(index) == selected_index_) + ResultRenderer::ResultRendererState state = ResultRenderer::RESULT_RENDERER_NORMAL; + + if (enable_texture_render() == false) + { + if (index == selected_index_) { state = ResultRenderer::RESULT_RENDERER_SELECTED; } - else if ((int)(index) == active_index_) - { - state = ResultRenderer::RESULT_RENDERER_ACTIVE; - } - - int half_width = recorded_dash_width_ / 2; - int half_height = recorded_dash_height_; + } + else if (index == active_index_) + { + state = ResultRenderer::RESULT_RENDERER_SELECTED; + } - int offset_x, offset_y; + int half_width = recorded_dash_width_ / 2; + int half_height = recorded_dash_height_ / 2; - /* Guard against divide-by-zero. SIGFPEs are not mythological - * contrary to popular belief */ - if (half_width >= 10) - offset_x = MAX(MIN((x_position - half_width) / (half_width / 10), 5), -5); - else - offset_x = 0; + int offset_x, offset_y; - if (half_height >= 10) - offset_y = MAX(MIN(((y_position + absolute_y) - half_height) / (half_height / 10), 5), -5); - else - offset_y = 0; + /* Guard against divide-by-zero. SIGFPEs are not mythological + * contrary to popular belief */ + if (half_width >= 10) + offset_x = std::max(std::min((x_position - half_width) / (half_width / 10), 5), -5); + else + offset_x = 0; - if (recorded_dash_width_ < 1 || recorded_dash_height_ < 1) - { - offset_x = 0; - offset_y = 0; - } + if (half_height >= 10) + offset_y = std::max(std::min(((y_position + absolute_position.y) - half_height) / (half_height / 10), 5), -5); + else + offset_y = 0; - nux::Geometry render_geo(x_position, y_position, renderer_->width, renderer_->height); - Result result(*GetIteratorAtRow(index)); - renderer_->Render(GfxContext, result, state, render_geo, offset_x, offset_y); + if (recorded_dash_width_ < 1 || recorded_dash_height_ < 1) + { + offset_x = 0; + offset_y = 0; + } - x_position += renderer_->width + horizontal_spacing + extra_horizontal_spacing_; + // Color and saturation + if (state == ResultRenderer::RESULT_RENDERER_SELECTED) + { + saturation = saturation_progress + (1.0-saturation_progress) * FOCUSED_ICON_SATURATION_REF; + opacity = saturation_progress + (1.0-saturation_progress) * FOCUSED_GHOST_ICON_OPACITY_REF; } + else + { + saturation = saturation_progress + (1.0-saturation_progress) * UNFOCUSED_ICON_SATURATION_REF; + opacity = saturation_progress + (1.0-saturation_progress) * UNFOCUSED_GHOST_ICON_OPACITY_REF; + } + nux::Color tint(opacity + (1.0f-opacity) * background_color_.red, + opacity + (1.0f-opacity) * background_color_.green, + opacity + (1.0f-opacity) * background_color_.blue, + opacity); + + nux::Geometry render_geo(x_position, y_position, renderer_->width, renderer_->height); + Result result(*GetIteratorAtRow(index)); + renderer_->Render(GfxContext, + result, + state, + render_geo, + offset_x, + offset_y, + tint, + saturation); + + x_position += renderer_->width + horizontal_spacing + extra_horizontal_spacing_; } - - y_position += row_size; } + + GfxContext.GetRenderStates().SetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor); } -void ResultViewGrid::DrawContent(nux::GraphicsEngine& GfxContent, bool force_draw) + +void ResultViewGrid::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) { nux::Geometry base = GetGeometry(); - GfxContent.PushClippingRectangle(base); + GfxContext.PushClippingRectangle(base); if (GetCompositionLayout()) { nux::Geometry geo = GetCompositionLayout()->GetGeometry(); - GetCompositionLayout()->ProcessDraw(GfxContent, force_draw); + GetCompositionLayout()->ProcessDraw(GfxContext, force_draw); } - GfxContent.PopClippingRectangle(); + GfxContext.PopClippingRectangle(); } @@ -867,6 +944,93 @@ ResultViewGrid::GetSelectedIndex() return selected_index_; } +void +ResultViewGrid::UpdateRenderTextures() +{ + nux::Geometry root_geo(GetAbsoluteGeometry()); + + int items_per_row = GetItemsPerRow(); + unsigned num_results = GetNumResults(); + + unsigned int total_rows = (!expanded) ? 1 : std::ceil(num_results / (double)items_per_row); + int row_height = renderer_->height + vertical_spacing; + + int cumulative_height = 0; + unsigned int row_index = 0; + for (; row_index < total_rows; row_index++) + { + // only one texture for non-expanded. + if (!expanded && row_index > 0) + break; + + if (row_index >= result_textures_.size()) + { + ResultViewTexture::Ptr result_texture(new ResultViewTexture); + result_texture->abs_geo.x = root_geo.x; + result_texture->abs_geo.y = root_geo.y + cumulative_height; + result_texture->abs_geo.width = GetWidth(); + result_texture->abs_geo.height = row_height; + result_texture->row_index = row_index; + + result_textures_.push_back(result_texture); + } + else + { + ResultViewTexture::Ptr const& result_texture(result_textures_[row_index]); + + result_texture->abs_geo.x = root_geo.x; + result_texture->abs_geo.y = root_geo.y + cumulative_height; + result_texture->abs_geo.width = GetWidth(); + result_texture->abs_geo.height = row_height; + result_texture->row_index = row_index; + } + + cumulative_height += row_height; + } + + // get rid of old textures. + for (; row_index < result_textures_.size(); row_index++) + { + result_textures_.pop_back(); + } +} + +void ResultViewGrid::RenderResultTexture(ResultViewTexture::Ptr const& result_texture) +{ + int row_height = renderer_->height + vertical_spacing; + + // Do we need to re-create the texture? + if (!result_texture->texture.IsValid() || + result_texture->texture->GetWidth() != GetWidth() || + result_texture->texture->GetHeight() != row_height) + { + result_texture->texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(GetWidth(), + row_height, + 1, + nux::BITFMT_R8G8B8A8); + if (!result_texture->texture.IsValid()) + return; + } + + ResultListBounds visible_bounds(0, GetNumResults()-1); + + graphics::PushOffscreenRenderTarget(result_texture->texture); + + // clear the texture. + CHECKGL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f)); + CHECKGL(glClear(GL_COLOR_BUFFER_BIT)); + + nux::GraphicsEngine& graphics_engine(nux::GetWindowThread()->GetGraphicsEngine()); + nux::Geometry offset_rect = graphics_engine.ModelViewXFormRect(GetGeometry()); + graphics_engine.PushModelViewMatrix(nux::Matrix4::TRANSLATE(-offset_rect.x, 0, 0)); + + DrawRow(graphics_engine, visible_bounds, result_texture->row_index, 0, GetAbsoluteGeometry()); + + graphics_engine.PopModelViewMatrix(); + + graphics::PopOffscreenRenderTarget(); +} + debug::ResultWrapper* ResultViewGrid::CreateResultWrapper(Result const& result, int index) { int x_offset = GetAbsoluteX(); diff --git a/dash/ResultViewGrid.h b/dash/ResultViewGrid.h index cb89f27dc..822689980 100644 --- a/dash/ResultViewGrid.h +++ b/dash/ResultViewGrid.h @@ -55,6 +55,8 @@ public: virtual void Activate(std::string const& uri, int index, ActivateType type); + virtual void RenderResultTexture(ResultViewTexture::Ptr const& result_texture); + protected: void MouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); void MouseClick(int x, int y, unsigned long button_flags, unsigned long key_flags); @@ -71,10 +73,12 @@ protected: virtual void OnKeyNavFocusChange(nux::Area* area, bool has_focus, nux::KeyNavDirection direction); void OnKeyDown(unsigned long event_type, unsigned long event_keysym, unsigned long event_state, const TCHAR* character, unsigned short key_repeat_count); - virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);; + virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw); virtual long ComputeContentSize(); + virtual void UpdateRenderTextures(); + void AddResult(Result& result); void RemoveResult(Result& result); @@ -86,6 +90,8 @@ private: typedef std::tuple <int, int> ResultListBounds; ResultListBounds GetVisableResults(); + void DrawRow(nux::GraphicsEngine& GfxContext, ResultListBounds const& visible_bounds, int row_index, int y_position, nux::Geometry const& absolute_position); + void QueueLazyLoad(); void QueueViewChanged(); bool DoLazyLoad(); @@ -119,6 +125,7 @@ private: UBusManager ubus_; glib::Source::UniquePtr lazy_load_source_; glib::Source::UniquePtr view_changed_idle_; + nux::Color background_color_; }; } // namespace dash diff --git a/dash/StandaloneDash.cpp b/dash/StandaloneDash.cpp index 3b7fa1264..bfd050903 100644 --- a/dash/StandaloneDash.cpp +++ b/dash/StandaloneDash.cpp @@ -33,6 +33,7 @@ #include "DashView.h" #include "unity-shared/UnitySettings.h" #include "unity-shared/DashStyle.h" +#include "unity-shared/PanelStyle.h" #include "unity-shared/ThumbnailGenerator.h" #define WIDTH 1024 @@ -95,6 +96,7 @@ int main(int argc, char **argv) unity::ThumbnailGenerator thumb_generator; unity::Settings settings; unity::dash::Style dash_style; + unity::panel::Style panel_style; TestRunner *test_runner = new TestRunner (); wt = nux::CreateGUIThread(TEXT("Unity Dash"), diff --git a/dash/previews/PreviewContainer.cpp b/dash/previews/PreviewContainer.cpp index fc3e4b850..b4055408f 100644 --- a/dash/previews/PreviewContainer.cpp +++ b/dash/previews/PreviewContainer.cpp @@ -23,10 +23,12 @@ #include "PreviewContainer.h" #include <NuxCore/Logger.h> #include <Nux/HLayout.h> +#include <Nux/VLayout.h> #include "unity-shared/IntrospectableWrappers.h" #include "unity-shared/TimeUtil.h" #include "unity-shared/PreviewStyle.h" +#include "unity-shared/GraphicsUtils.h" #include "PreviewNavigator.h" #include <boost/math/constants/constants.hpp> #include "config.h" @@ -47,7 +49,7 @@ Navigation operator&(const Navigation lhs, const Navigation rhs) namespace { const int ANIM_DURATION_LONG = 500; -const int PREVIEW_SPINNER_WAIT = 300; +const int PREVIEW_SPINNER_WAIT = 2000; const std::string ANIMATION_IDLE = "animation-idle"; } @@ -73,7 +75,7 @@ public: }); Style& style = previews::Style::Instance(); - spin_= style.GetSearchSpinIcon(256); + spin_= style.GetSearchSpinIcon(32); } // From debug::Introspectable @@ -272,7 +274,6 @@ public: if (swipe_.preview && swipe_.preview->IsVisible()) { swipe_.preview->ProcessDraw(gfx_engine, force_draw); } if (current_preview_ && current_preview_->IsVisible()) { current_preview_->ProcessDraw(gfx_engine, force_draw); } - if (waiting_preview_) { nux::Geometry const& base = GetGeometry(); @@ -297,11 +298,15 @@ public: int spin_offset_w = !(base.width % 2) ? 0 : 1; int spin_offset_h = !(base.height % 2) ? 0 : 1; - gfx_engine.PushModelViewMatrix(nux::Matrix4::TRANSLATE(-spin_geo.x - (spin_geo.width + spin_offset_w) / 2.0f, - -spin_geo.y - (spin_geo.height + spin_offset_h) / 2.0f, 0)); - gfx_engine.PushModelViewMatrix(rotate_matrix_); - gfx_engine.PushModelViewMatrix(nux::Matrix4::TRANSLATE(spin_geo.x + (spin_geo.width + spin_offset_w) / 2.0f, - spin_geo.y + (spin_geo.height + spin_offset_h) / 2.0f, 0)); + // we need to apply the rotation transformation first. + nux::Matrix4 matrix_texture; + matrix_texture = nux::Matrix4::TRANSLATE(-spin_geo.x - (spin_geo.width + spin_offset_w) / 2.0f, + -spin_geo.y - (spin_geo.height + spin_offset_h) / 2.0f, 0) * matrix_texture; + matrix_texture = rotate_matrix_ * matrix_texture; + matrix_texture = nux::Matrix4::TRANSLATE(spin_geo.x + (spin_geo.width + spin_offset_w) / 2.0f, + spin_geo.y + (spin_geo.height + spin_offset_h) / 2.0f, 0) * matrix_texture; + + gfx_engine.SetModelViewMatrix(gfx_engine.GetModelViewMatrix() * matrix_texture); gfx_engine.QRP_1Tex(spin_geo.x, spin_geo.y, @@ -311,9 +316,8 @@ public: texxform, nux::color::White); - gfx_engine.PopModelViewMatrix(); - gfx_engine.PopModelViewMatrix(); - gfx_engine.PopModelViewMatrix(); + // revert to model view matrix stack + gfx_engine.ApplyModelViewMatrix(); gfx_engine.GetRenderStates().SetBlend(alpha, src, dest); @@ -390,7 +394,7 @@ NUX_IMPLEMENT_OBJECT_TYPE(PreviewContainer); PreviewContainer::PreviewContainer(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) - , content_layout_(nullptr) + , preview_layout_(nullptr) , nav_disabled_(Navigation::NONE) , navigation_progress_speed_(0.0) , navigation_count_(0) @@ -412,14 +416,14 @@ PreviewContainer::~PreviewContainer() void PreviewContainer::Preview(dash::Preview::Ptr preview_model, Navigation direction) { - previews::Preview::Ptr preview_view = previews::Preview::PreviewForModel(preview_model); + previews::Preview::Ptr preview_view = preview_model ? previews::Preview::PreviewForModel(preview_model) : previews::Preview::Ptr(); if (preview_view) { preview_view->request_close.connect([this]() { request_close.emit(); }); } - content_layout_->PushPreview(preview_view, direction); + preview_layout_->PushPreview(preview_view, direction); } void PreviewContainer::DisableNavButton(Navigation button) @@ -452,92 +456,103 @@ void PreviewContainer::SetupViews() { previews::Style& style = previews::Style::Instance(); - layout_ = new nux::HLayout(); - layout_->SetSpaceBetweenChildren(6); - SetLayout(layout_); - layout_->AddSpace(0, 1); + nux::VLayout* layout = new nux::VLayout(); + SetLayout(layout); + layout->AddLayout(new nux::SpaceLayout(0,0,style.GetPreviewTopPadding(),style.GetPreviewTopPadding())); + + layout_content_ = new nux::HLayout(); + layout_content_->SetSpaceBetweenChildren(6); + layout->AddLayout(layout_content_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); + layout_content_->AddSpace(0, 1); nav_left_ = new PreviewNavigator(Orientation::LEFT, NUX_TRACKER_LOCATION); AddChild(nav_left_); nav_left_->SetMinimumWidth(style.GetNavigatorWidth()); nav_left_->SetMaximumWidth(style.GetNavigatorWidth()); nav_left_->activated.connect([&]() { navigate_left.emit(); }); - layout_->AddView(nav_left_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + layout_content_->AddView(nav_left_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); - content_layout_ = new PreviewContent(this); - content_layout_->SetMinMaxSize(style.GetPreviewWidth(), style.GetPreviewHeight()); - AddChild(content_layout_); - layout_->AddLayout(content_layout_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + preview_layout_ = new PreviewContent(this); + preview_layout_->SetMinMaxSize(style.GetPreviewWidth(), style.GetPreviewHeight()); + AddChild(preview_layout_); + layout_content_->AddLayout(preview_layout_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); nav_right_ = new PreviewNavigator(Orientation::RIGHT, NUX_TRACKER_LOCATION); AddChild(nav_right_); nav_right_->SetMinimumWidth(style.GetNavigatorWidth()); nav_right_->SetMaximumWidth(style.GetNavigatorWidth()); nav_right_->activated.connect([&]() { navigate_right.emit(); }); - layout_->AddView(nav_right_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + layout_content_->AddView(nav_right_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT); + layout_content_->AddSpace(0, 1); - layout_->AddSpace(0, 1); + layout->AddSpace(0, 1); - content_layout_->start_navigation.connect([&]() + preview_layout_->start_navigation.connect([&]() { // reset animation clock. if (navigation_count_ == 0) clock_gettime(CLOCK_MONOTONIC, &last_progress_time_); - float navigation_progress_remaining = CLAMP((1.0 - content_layout_->GetAnimationProgress()) + navigation_count_, 1.0f, 10.0f); + float navigation_progress_remaining = CLAMP((1.0 - preview_layout_->GetAnimationProgress()) + navigation_count_, 1.0f, 10.0f); navigation_count_++; navigation_progress_speed_ = navigation_progress_remaining / ANIM_DURATION_LONG; QueueAnimation(); }); - content_layout_->continue_navigation.connect([&]() + preview_layout_->continue_navigation.connect([&]() { QueueAnimation(); }); - content_layout_->end_navigation.connect([&]() + preview_layout_->end_navigation.connect([&]() { navigation_count_ = 0; navigation_progress_speed_ = 0; }); - navigate_right.connect( [&]() { content_layout_->StartPreviewWait(); } ); - navigate_left.connect( [&]() { content_layout_->StartPreviewWait(); } ); + navigate_right.connect( [&]() { preview_layout_->StartPreviewWait(); } ); + navigate_left.connect( [&]() { preview_layout_->StartPreviewWait(); } ); } void PreviewContainer::Draw(nux::GraphicsEngine& gfx_engine, bool force_draw) { - nux::Geometry const& geo = GetGeometry(); - - gfx_engine.PushClippingRectangle(geo); - nux::GetPainter().PaintBackground(gfx_engine, geo); - gfx_engine.PopClippingRectangle(); } void PreviewContainer::DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw) { - nux::Geometry base = GetGeometry(); + nux::Geometry const& base = GetGeometry(); gfx_engine.PushClippingRectangle(base); + bool redirect_to_texture = RedirectRenderingToTexture(); + + // This is necessary when doing redirected rendering. Clean the area below this view. + if (redirect_to_texture) + { + // This is necessary when doing redirected rendering. + // Clean the area below this view before drawing anything. + gfx_engine.GetRenderStates().SetBlend(false); + gfx_engine.QRP_Color(GetX(), GetY(), GetWidth(), GetHeight(), nux::Color(0.0f, 0.0f, 0.0f, 0.0f)); + } + // rely on the compiz event loop to come back to us in a nice throttling if (AnimationInProgress()) { if (!animation_timer_) animation_timer_.reset(new glib::Timeout(1000/60, sigc::mem_fun(this, &PreviewContainer::QueueAnimation))); } - else if (content_layout_ && content_layout_->IsAnimating()) + else if (preview_layout_ && preview_layout_->IsAnimating()) { - content_layout_->UpdateAnimationProgress(1.0f, 1.0f); + preview_layout_->UpdateAnimationProgress(1.0f, 1.0f); } // Paint using ProcessDraw2. ProcessDraw is overrided by empty impl so we can control z order. - if (content_layout_) + if (preview_layout_) { - content_layout_->ProcessDraw2(gfx_engine, force_draw); + preview_layout_->ProcessDraw2(gfx_engine, force_draw || redirect_to_texture); } if (GetCompositionLayout()) - GetCompositionLayout()->ProcessDraw(gfx_engine, force_draw); + GetCompositionLayout()->ProcessDraw(gfx_engine, force_draw || RedirectRenderingToTexture()); gfx_engine.PopClippingRectangle(); } @@ -548,7 +563,7 @@ bool PreviewContainer::AnimationInProgress() struct timespec current; clock_gettime(CLOCK_MONOTONIC, ¤t); - if (content_layout_ == nullptr) + if (preview_layout_ == nullptr) return false; // hover in animation @@ -572,7 +587,7 @@ static float easeInOutQuart(float t) float PreviewContainer::GetSwipeAnimationProgress(struct timespec const& current) const { DeltaTime time_delta = TimeUtil::TimeDelta(¤t, &last_progress_time_); - float progress = content_layout_->GetAnimationProgress() + (navigation_progress_speed_ * time_delta); + float progress = preview_layout_->GetAnimationProgress() + (navigation_progress_speed_ * time_delta); return progress; } @@ -584,7 +599,7 @@ bool PreviewContainer::QueueAnimation() timespec current; clock_gettime(CLOCK_MONOTONIC, ¤t); float progress = GetSwipeAnimationProgress(current); - content_layout_->UpdateAnimationProgress(progress, easeInOutQuart(progress)); // ease in/out. + preview_layout_->UpdateAnimationProgress(progress, easeInOutQuart(progress)); // ease in/out. last_progress_time_ = current; QueueDraw(); @@ -631,7 +646,7 @@ nux::Area* PreviewContainer::FindKeyFocusArea(unsigned int key_symbol, unsigned long x11_key_code, unsigned long special_keys_state) { - nux::Area* area = content_layout_->FindKeyFocusArea(key_symbol, x11_key_code, special_keys_state); + nux::Area* area = preview_layout_->FindKeyFocusArea(key_symbol, x11_key_code, special_keys_state); if (area) return area; @@ -641,7 +656,7 @@ nux::Area* PreviewContainer::FindKeyFocusArea(unsigned int key_symbol, nux::Area* PreviewContainer::KeyNavIteration(nux::KeyNavDirection direction) { using namespace nux; - nux::Area* area = content_layout_->KeyNavIteration(direction); + nux::Area* area = preview_layout_->KeyNavIteration(direction); if (area) return area; @@ -672,6 +687,11 @@ void PreviewContainer::OnMouseDown(int x, int y, unsigned long button_flags, uns } } +nux::Geometry PreviewContainer::GetLayoutGeometry() const +{ + return layout_content_->GetAbsoluteGeometry(); +} + } // namespace previews } // namespace dash diff --git a/dash/previews/PreviewContainer.h b/dash/previews/PreviewContainer.h index 498da7fd2..38cbf3334 100644 --- a/dash/previews/PreviewContainer.h +++ b/dash/previews/PreviewContainer.h @@ -81,6 +81,8 @@ public: unsigned long x11_key_code, unsigned long special_keys_state); + nux::Geometry GetLayoutGeometry() const; + protected: void Draw(nux::GraphicsEngine& gfx_engine, bool force_draw); void DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw); @@ -99,10 +101,10 @@ private: private: // View related - nux::HLayout* layout_; + nux::HLayout* layout_content_; PreviewNavigator* nav_left_; PreviewNavigator* nav_right_; - PreviewContent* content_layout_; + PreviewContent* preview_layout_; Navigation nav_disabled_; // Animation diff --git a/dash/previews/PreviewNavigator.cpp b/dash/previews/PreviewNavigator.cpp index 2181c8496..2c765007d 100644 --- a/dash/previews/PreviewNavigator.cpp +++ b/dash/previews/PreviewNavigator.cpp @@ -51,8 +51,11 @@ PreviewNavigator::PreviewNavigator(Orientation direction, NUX_FILE_LINE_DECL) void PreviewNavigator::SetEnabled(bool enabled) { - texture_->SetEnableView(enabled); - texture_->SetVisible(enabled); + if (enabled != texture_->IsVisible()) + { + texture_->SetVisible(enabled); + QueueRelayout(); + } } std::string PreviewNavigator::GetName() const diff --git a/dash/previews/SocialPreview.cpp b/dash/previews/SocialPreview.cpp index ef97f1967..d439f4e5c 100644 --- a/dash/previews/SocialPreview.cpp +++ b/dash/previews/SocialPreview.cpp @@ -281,12 +281,12 @@ void SocialPreview::PreLayoutManagement() nux::Geometry geo_content(geo.x, geo.y, style.GetAppImageAspectRatio() * geo.height, geo.height); if (geo.width - geo_content.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() < style.GetDetailsPanelMinimumWidth()) - geo_content.width = MAX(0, geo.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() - style.GetDetailsPanelMinimumWidth()); + geo_content.width = std::max(0, geo.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin() - style.GetDetailsPanelMinimumWidth()); if (content_) { content_->SetMinMaxSize(geo_content.width, geo_content.height); } if (image_) { image_->SetMinMaxSize(geo_content.width, geo_content.height); } - int details_width = MAX(0, geo.width - geo_content.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); - int top_social_info_max_width = details_width - style.GetAppIconAreaWidth() - style.GetSpaceBetweenIconAndDetails(); + int details_width = std::max(0, geo.width - geo_content.width - style.GetPanelSplitWidth() - style.GetDetailsLeftMargin() - style.GetDetailsRightMargin()); + int top_social_info_max_width = std::max(0, details_width - style.GetAppIconAreaWidth() - style.GetSpaceBetweenIconAndDetails()); if (title_) { title_->SetMaximumWidth(top_social_info_max_width); } if (subtitle_) { subtitle_->SetMaximumWidth(top_social_info_max_width); } diff --git a/dash/previews/SocialPreviewContent.cpp b/dash/previews/SocialPreviewContent.cpp index ca6ff0ff5..4cff81af2 100644 --- a/dash/previews/SocialPreviewContent.cpp +++ b/dash/previews/SocialPreviewContent.cpp @@ -149,8 +149,8 @@ void SocialPreviewContent::UpdateBaloonTexture() nux::Geometry geo_cr(GetBubbleGeometry(geo)); - int max_width = geo_cr.width - 2*(geo_cr.width*0.1); - int max_height = (geo_cr.height - TAIL_HEIGHT) - 2*((geo_cr.height - TAIL_HEIGHT)*0.1); + int max_width = std::max(0, (int)(geo_cr.width - 2*(geo_cr.width*0.1))); + int max_height = std::max(0, (int)((geo_cr.height - TAIL_HEIGHT) - 2*((geo_cr.height - TAIL_HEIGHT)*0.1))); // this will update the texture with the actual size of the text. text_->SetMaximumHeight(max_height); @@ -169,8 +169,8 @@ void SocialPreviewContent::UpdateBaloonTexture() void SocialPreviewContent::RedrawBubble(nux::Geometry const& geom, cairo_t* cr, nux::ButtonVisualState faked_state) { - double width = MAX(0, cairo_image_surface_get_width(cairo_get_target(cr))); - double height = MAX(0, cairo_image_surface_get_height(cairo_get_target(cr)) - TAIL_HEIGHT); + double width = std::max(0, cairo_image_surface_get_width(cairo_get_target(cr))); + double height = std::max(0, cairo_image_surface_get_height(cairo_get_target(cr)) - TAIL_HEIGHT); double tailPosition = width - TAIL_POS_FROM_RIGHT - TAIL_HEIGHT; if (width > 0 && height > 0) diff --git a/tests/test_places_group.cpp b/tests/test_places_group.cpp index aafd53861..a58de9f88 100644 --- a/tests/test_places_group.cpp +++ b/tests/test_places_group.cpp @@ -48,8 +48,12 @@ public: MOCK_METHOD0(GetGroupExpandIcon, nux::BaseTexture*()); MOCK_METHOD0(GetGroupUnexpandIcon, nux::BaseTexture*()); + MOCK_CONST_METHOD0(GetCategoryIconSize, int()); MOCK_CONST_METHOD0(GetCategoryHeaderLeftPadding, int()); + MOCK_CONST_METHOD0(GetPlacesGroupTopSpace, int()); + MOCK_CONST_METHOD0(GetPlacesGroupResultTopPadding, int()); + MOCK_CONST_METHOD0(GetPlacesGroupResultLeftPadding, int()); nux::ObjectPtr<nux::BaseTexture> base_texture_; }; diff --git a/unity-shared/CoverArt.cpp b/unity-shared/CoverArt.cpp index b7e6986a1..97375a6c2 100644 --- a/unity-shared/CoverArt.cpp +++ b/unity-shared/CoverArt.cpp @@ -378,7 +378,7 @@ void CoverArt::DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw) else if (IsFullRedraw()) { if (waiting_) - { + { nux::TexCoordXForm texxform; texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); @@ -395,11 +395,15 @@ void CoverArt::DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw) int spin_offset_w = !(base.width % 2) ? 0 : 1; int spin_offset_h = !(base.height % 2) ? 0 : 1; - gfx_engine.PushModelViewMatrix(nux::Matrix4::TRANSLATE(-spin_geo.x - (spin_geo.width + spin_offset_w) / 2.0f, - -spin_geo.y - (spin_geo.height + spin_offset_h) / 2.0f, 0)); - gfx_engine.PushModelViewMatrix(rotate_matrix_); - gfx_engine.PushModelViewMatrix(nux::Matrix4::TRANSLATE(spin_geo.x + (spin_geo.width + spin_offset_w) / 2.0f, - spin_geo.y + (spin_geo.height + spin_offset_h) / 2.0f, 0)); + // we need to apply the rotation transformation first. + nux::Matrix4 matrix_texture; + matrix_texture = nux::Matrix4::TRANSLATE(-spin_geo.x - (spin_geo.width + spin_offset_w) / 2.0f, + -spin_geo.y - (spin_geo.height + spin_offset_h) / 2.0f, 0) * matrix_texture; + matrix_texture = rotate_matrix_ * matrix_texture; + matrix_texture = nux::Matrix4::TRANSLATE(spin_geo.x + (spin_geo.width + spin_offset_w) / 2.0f, + spin_geo.y + (spin_geo.height + spin_offset_h) / 2.0f, 0) * matrix_texture; + + gfx_engine.SetModelViewMatrix(gfx_engine.GetModelViewMatrix() * matrix_texture); gfx_engine.QRP_1Tex(spin_geo.x, spin_geo.y, @@ -409,9 +413,8 @@ void CoverArt::DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw) texxform, nux::color::White); - gfx_engine.PopModelViewMatrix(); - gfx_engine.PopModelViewMatrix(); - gfx_engine.PopModelViewMatrix(); + // revert to model view matrix stack + gfx_engine.ApplyModelViewMatrix(); if (!frame_timeout_) { diff --git a/unity-shared/DashStyle.cpp b/unity-shared/DashStyle.cpp index 8dca2c037..8e3f040c8 100755 --- a/unity-shared/DashStyle.cpp +++ b/unity-shared/DashStyle.cpp @@ -2362,6 +2362,11 @@ int Style::GetScrollbarWidth() const return 3; } +int Style::GetCategoryIconSize() const +{ + return 22; +} + int Style::GetCategoryHighlightHeight() const { return 24; @@ -2372,6 +2377,16 @@ int Style::GetPlacesGroupTopSpace() const return 7; } +int Style::GetPlacesGroupResultTopPadding() const +{ + return 2; +} + +int Style::GetPlacesGroupResultLeftPadding() const +{ + return 25; +} + int Style::GetCategoryHeaderLeftPadding() const { return 19; diff --git a/unity-shared/DashStyle.h b/unity-shared/DashStyle.h index a1c6b93a8..53f70165d 100755 --- a/unity-shared/DashStyle.h +++ b/unity-shared/DashStyle.h @@ -243,8 +243,11 @@ public: int GetScrollbarWidth() const; // Places Group + int GetCategoryIconSize() const; int GetCategoryHighlightHeight() const; int GetPlacesGroupTopSpace() const; + int GetPlacesGroupResultTopPadding() const; + int GetPlacesGroupResultLeftPadding() const; int GetCategoryHeaderLeftPadding() const; int GetCategorySeparatorLeftPadding() const; int GetCategorySeparatorRightPadding() const; diff --git a/unity-shared/DashStyleInterface.h b/unity-shared/DashStyleInterface.h index 43d488bc4..24e30f361 100644 --- a/unity-shared/DashStyleInterface.h +++ b/unity-shared/DashStyleInterface.h @@ -43,8 +43,11 @@ public: virtual nux::BaseTexture* GetGroupUnexpandIcon() = 0; virtual nux::BaseTexture* GetGroupExpandIcon() = 0; + virtual int GetCategoryIconSize() const = 0; virtual int GetCategoryHeaderLeftPadding() const = 0; virtual int GetPlacesGroupTopSpace() const = 0; + virtual int GetPlacesGroupResultTopPadding() const = 0; + virtual int GetPlacesGroupResultLeftPadding() const = 0; }; } diff --git a/unity-shared/OverlayRenderer.cpp b/unity-shared/OverlayRenderer.cpp index 3c04864fa..ef8120c68 100644 --- a/unity-shared/OverlayRenderer.cpp +++ b/unity-shared/OverlayRenderer.cpp @@ -816,7 +816,7 @@ void OverlayRendererImpl::DrawContent(nux::GraphicsEngine& gfx_context, nux::Geo int excess_border = (Settings::Instance().form_factor() != FormFactor::NETBOOK) ? EXCESS_BORDER : 0; - nux::Geometry larger_content_geo = nux::Geometry(content_geo.x, content_geo.y, content_geo.width, content_geo.height); + nux::Geometry larger_content_geo = content_geo; larger_content_geo.OffsetSize(excess_border, excess_border); nux::Geometry larger_geo(larger_content_geo); @@ -824,7 +824,6 @@ void OverlayRendererImpl::DrawContent(nux::GraphicsEngine& gfx_context, nux::Geo nux::Geometry larger_absolute_geo = absolute_geo; larger_absolute_geo.OffsetSize(excess_border, excess_border); - gfx_context.PushClippingRectangle(larger_geo); unsigned int blend_alpha, blend_src, blend_dest = 0; @@ -913,15 +912,13 @@ void OverlayRendererImpl::DrawContent(nux::GraphicsEngine& gfx_context, nux::Geo } } + gfx_context.GetRenderStates().SetBlend(blend_alpha, blend_src, blend_dest); + gfx_context.PopClippingRectangle(); } void OverlayRendererImpl::DrawContentCleanup(nux::GraphicsEngine& gfx_context, nux::Geometry const& content_geo, nux::Geometry const& absolute_geo, nux::Geometry const& geometry) { nux::GetPainter().PopBackground(bgs); - - gfx_context.GetRenderStates().SetBlend(false); - gfx_context.PopClippingRectangle(); - bgs = 0; } diff --git a/unity-shared/PlacesOverlayVScrollBar.cpp b/unity-shared/PlacesOverlayVScrollBar.cpp index 6943176e6..8ba19c988 100644 --- a/unity-shared/PlacesOverlayVScrollBar.cpp +++ b/unity-shared/PlacesOverlayVScrollBar.cpp @@ -56,6 +56,7 @@ PlacesOverlayVScrollBar::PlacesOverlayVScrollBar(NUX_FILE_LINE_DECL) _track->geometry_changed.connect(sigc::mem_fun(this, &PlacesOverlayVScrollBar::OnTrackGeometryChanged)); OnVisibleChanged.connect(sigc::mem_fun(this, &PlacesOverlayVScrollBar::OnVisibilityChanged)); + OnSensitiveChanged.connect(sigc::mem_fun(this, &PlacesOverlayVScrollBar::OnSensitivityChanged)); } void PlacesOverlayVScrollBar::OnTrackGeometryChanged(nux::Area* /*area*/, nux::Geometry& /*geo*/) @@ -79,6 +80,15 @@ void PlacesOverlayVScrollBar::OnVisibilityChanged(nux::Area* /*area*/, bool visi } } +void PlacesOverlayVScrollBar::OnSensitivityChanged(nux::Area* /*area*/, bool sensitive) +{ + if (!sensitive) + { + overlay_window_->ResetStates(); + ResetConnector(); + } +} + void PlacesOverlayVScrollBar::SetupAnimation(int start, int stop, int milliseconds) { tweening_connection_.disconnect(); @@ -152,7 +162,7 @@ void PlacesOverlayVScrollBar::OnMouseLeave(int x, int y, unsigned int button_fla void PlacesOverlayVScrollBar::OnMouseNear(nux::Point const& mouse_pos) { - if (IsVisible() && IsScrollBarVisible()) + if (IsSensitive() && IsVisible() && IsScrollBarVisible()) { animation_.Stop(); diff --git a/unity-shared/PlacesOverlayVScrollBar.h b/unity-shared/PlacesOverlayVScrollBar.h index 64945b944..dc8962608 100644 --- a/unity-shared/PlacesOverlayVScrollBar.h +++ b/unity-shared/PlacesOverlayVScrollBar.h @@ -50,6 +50,7 @@ private: void OnTrackGeometryChanged(nux::Area* area, nux::Geometry& geo); void OnVisibilityChanged(nux::Area* area, bool visible); + void OnSensitivityChanged(nux::Area* area, bool sensitive); void OnMouseEnter(int x, int y, unsigned int button_flags, unsigned int key_flags); void OnMouseLeave(int x, int y, unsigned int button_flags, unsigned int key_flags); diff --git a/unity-shared/PreviewStyle.cpp b/unity-shared/PreviewStyle.cpp index 314d6bdbb..7b332176f 100644 --- a/unity-shared/PreviewStyle.cpp +++ b/unity-shared/PreviewStyle.cpp @@ -171,6 +171,12 @@ int Style::GetPreviewHeight() const return preview_height; } + +int Style::GetPreviewTopPadding() const +{ + return 100; +} + int Style::GetDetailsTopMargin() const { return 5; diff --git a/unity-shared/PreviewStyle.h b/unity-shared/PreviewStyle.h index fc823f36b..1a2eec4ac 100644 --- a/unity-shared/PreviewStyle.h +++ b/unity-shared/PreviewStyle.h @@ -62,6 +62,7 @@ public: int GetPreviewWidth() const; int GetPreviewHeight() const; + int GetPreviewTopPadding() const; int GetDetailsTopMargin() const; int GetDetailsBottomMargin() const; diff --git a/unity-shared/SearchBarSpinner.cpp b/unity-shared/SearchBarSpinner.cpp index 39b62b523..6e1dbaec2 100644 --- a/unity-shared/SearchBarSpinner.cpp +++ b/unity-shared/SearchBarSpinner.cpp @@ -88,11 +88,14 @@ SearchBarSpinner::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) int spin_offset_w = !(geo.width % 2) ? 0 : 1; int spin_offset_h = !(geo.height % 2) ? 0 : 1; - GfxContext.PushModelViewMatrix(nux::Matrix4::TRANSLATE(-spin_geo.x - (spin_geo.width + spin_offset_w) / 2.0f, - -spin_geo.y - (spin_geo.height + spin_offset_h) / 2.0f, 0)); - GfxContext.PushModelViewMatrix(_2d_rotate); - GfxContext.PushModelViewMatrix(nux::Matrix4::TRANSLATE(spin_geo.x + (spin_geo.width + spin_offset_w) / 2.0f, - spin_geo.y + (spin_geo.height + spin_offset_h) / 2.0f, 0)); + nux::Matrix4 matrix_texture; + matrix_texture = nux::Matrix4::TRANSLATE(-spin_geo.x - (spin_geo.width + spin_offset_w) / 2.0f, + -spin_geo.y - (spin_geo.height + spin_offset_h) / 2.0f, 0) * matrix_texture; + matrix_texture = _2d_rotate * matrix_texture; + matrix_texture = nux::Matrix4::TRANSLATE(spin_geo.x + (spin_geo.width + spin_offset_w) / 2.0f, + spin_geo.y + (spin_geo.height + spin_offset_h) / 2.0f, 0) * matrix_texture; + + GfxContext.SetModelViewMatrix(GfxContext.GetModelViewMatrix() * matrix_texture); GfxContext.QRP_1Tex(spin_geo.x, spin_geo.y, @@ -102,9 +105,8 @@ SearchBarSpinner::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) texxform, nux::color::White); - GfxContext.PopModelViewMatrix(); - GfxContext.PopModelViewMatrix(); - GfxContext.PopModelViewMatrix(); + // revert to model view matrix stack + GfxContext.ApplyModelViewMatrix(); } else { diff --git a/unity-shared/UBusMessages.h b/unity-shared/UBusMessages.h index c2b2f502f..034e710ad 100644 --- a/unity-shared/UBusMessages.h +++ b/unity-shared/UBusMessages.h @@ -40,8 +40,6 @@ #define UBUS_OVERLAY_HIDDEN "OVERLAY_HIDDEN" #define UBUS_OVERLAY_SHOWN "OVERLAY_SHOWN" -#define UBUS_PLACE_VIEW_QUEUE_DRAW "PLACE_VIEW_QUEUE_DRAW" - // Signal send by Launcher/Quicklist when it wants to exit key-nav and wants to // get rid of keyboard-input-focus #define UBUS_LAUNCHER_START_KEY_NAV "LAUNCHER_START_KEY_NAV" |
