// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
/*
* Copyright 2011 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version 3, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranties of
* MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the applicable version of the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of both the GNU Lesser General Public
* License version 3 along with this program. If not, see
*
*
* Authored by: Gordon Allott
*
*/
#include "Preview.h"
#include "TabIterator.h"
#include "unity-shared/IntrospectableWrappers.h"
#include "unity-shared/CoverArt.h"
#include
#include
#include
#include
#include "ActionButton.h"
#include "GenericPreview.h"
#include "ApplicationPreview.h"
#include "ErrorPreview.h"
#include "MusicPreview.h"
#include "MoviePreview.h"
#include "MusicPaymentPreview.h"
#include "SocialPreview.h"
#include "PreviewInfoHintWidget.h"
#include "ActionButton.h"
namespace unity
{
namespace dash
{
namespace previews
{
DECLARE_LOGGER(logger, "unity.dash.preview.view");
previews::Preview::Ptr Preview::PreviewForModel(dash::Preview::Ptr model)
{
if (!model)
{
LOG_WARN(logger) << "Unable to create Preview object";
return previews::Preview::Ptr();
}
if (model->renderer_name == "preview-generic")
{
return Preview::Ptr(new GenericPreview(model));
}
else if (model->renderer_name == "preview-payment")
{
dash::PaymentPreview* payment_preview_model = dynamic_cast(
model.get());
if (payment_preview_model->preview_type.Get() == dash::PaymentPreview::MUSIC)
{
return Preview::Ptr(new MusicPaymentPreview(model));
}
else
{
return Preview::Ptr(new ErrorPreview(model));
}
}
else if (model->renderer_name == "preview-application")
{
return Preview::Ptr(new ApplicationPreview(model));
}
else if (model->renderer_name == "preview-music")
{
return Preview::Ptr(new MusicPreview(model));
}
else if (model->renderer_name == "preview-movie")
{
return Preview::Ptr(new MoviePreview(model));
}
else if (model->renderer_name == "preview-social")
{
return Preview::Ptr(new SocialPreview(model));
}
else
{
LOG_WARN(logger) << "Unable to create Preview for renderer: " << model->renderer_name.Get() << "; using generic";
}
return Preview::Ptr(new GenericPreview(model));
}
NUX_IMPLEMENT_OBJECT_TYPE(Preview);
Preview::Preview(dash::Preview::Ptr preview_model)
: View(NUX_TRACKER_LOCATION)
, scale(1.0f)
, preview_model_(preview_model)
, tab_iterator_(new TabIterator())
, full_data_layout_(nullptr)
, image_(nullptr)
, title_(nullptr)
, subtitle_(nullptr)
, preview_container_(new PreviewContainer)
{
scale.changed.connect(sigc::mem_fun(this, &Preview::UpdateScale));
}
Preview::~Preview()
{
delete tab_iterator_;
}
std::string Preview::GetName() const
{
return "Preview";
}
void Preview::AddProperties(debug::IntrospectionData& introspection)
{
introspection
.add(GetAbsoluteGeometry())
.add("uri", preview_model_->preview_result.uri);
}
void Preview::OnActionActivated(ActionButton* button, std::string const& id)
{
if (preview_model_)
preview_model_->PerformAction(id);
}
nux::Layout* Preview::BuildGridActionsLayout(dash::Preview::ActionPtrList actions, std::list& buttons)
{
previews::Style& style = dash::previews::Style::Instance();
nux::VLayout* actions_layout_v = new nux::VLayout();
actions_layout_v->SetSpaceBetweenChildren(style.GetSpaceBetweenActions().CP(scale));
uint rows = actions.size() / 2 + ((actions.size() % 2 > 0) ? 1 : 0);
uint action_iter = 0;
for (uint i = 0; i < rows; i++)
{
nux::HLayout* actions_layout_h = new TabIteratorHLayout(tab_iterator_);
actions_layout_h->SetSpaceBetweenChildren(style.GetSpaceBetweenActions().CP(scale));
for (uint j = 0; j < 2 && action_iter < actions.size(); j++, action_iter++)
{
dash::Preview::ActionPtr action = actions[action_iter];
ActionButton* button = new ActionButton(action->id, action->display_name, action->icon_hint, NUX_TRACKER_LOCATION);
tab_iterator_->Append(button);
AddChild(button);
button->SetFont(style.action_font());
button->SetExtraHint(action->extra_text, style.action_extra_font());
button->activate.connect(sigc::mem_fun(this, &Preview::OnActionActivated));
buttons.push_back(button);
actions_layout_h->AddView(button, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL, 100.0f, nux::NUX_LAYOUT_BEGIN);
}
actions_layout_v->AddLayout(actions_layout_h, 0, nux::MINOR_POSITION_END, nux::MINOR_SIZE_FULL, 100.0f, nux::NUX_LAYOUT_BEGIN);
}
return actions_layout_v;
}
nux::Layout* Preview::BuildVerticalActionsLayout(dash::Preview::ActionPtrList actions, std::list& buttons)
{
previews::Style& style = dash::previews::Style::Instance();
nux::VLayout* actions_layout_v = new TabIteratorVLayout(tab_iterator_);
actions_layout_v->SetSpaceBetweenChildren(style.GetSpaceBetweenActions().CP(scale));
uint action_iter = 0;
for (uint i = 0; i < actions.size(); i++)
{
dash::Preview::ActionPtr action = actions[action_iter++];
ActionButton* button = new ActionButton(action->id, action->display_name, action->icon_hint, NUX_TRACKER_LOCATION);
tab_iterator_->Append(button);
AddChild(button);
button->SetFont(style.action_font());
button->SetExtraHint(action->extra_text, style.action_extra_font());
button->activate.connect(sigc::mem_fun(this, &Preview::OnActionActivated));
buttons.push_back(button);
actions_layout_v->AddView(button, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL, 100.0f, nux::NUX_LAYOUT_BEGIN);
}
return actions_layout_v;
}
void Preview::UpdateCoverArtImage(CoverArt* cover_art)
{
if (!preview_model_)
return;
previews::Style& style = dash::previews::Style::Instance();
auto on_mouse_down = [this](int x, int y, unsigned long button_flags, unsigned long key_flags) { this->preview_container_->OnMouseDown(x, y, button_flags, key_flags); };
std::string image_hint;
if (preview_model_->image.Get())
{
glib::String tmp_icon(g_icon_to_string(preview_model_->image.Get()));
image_hint = tmp_icon.Str();
}
if (!image_hint.empty())
cover_art->SetImage(image_hint);
else if (!preview_model_->image_source_uri.Get().empty())
cover_art->GenerateImage(preview_model_->image_source_uri);
else
cover_art->SetNoImageAvailable();
cover_art->SetFont(style.no_preview_image_font());
cover_art->mouse_click.connect(on_mouse_down);
}
nux::Area* Preview::FindKeyFocusArea(unsigned int key_symbol,
unsigned long x11_key_code,
unsigned long special_keys_state)
{
nux::Area* tab_area = tab_iterator_->FindKeyFocusArea(key_symbol, x11_key_code, special_keys_state);
if (tab_area)
{
return tab_area;
}
return nullptr;
}
nux::Area* Preview::KeyNavIteration(nux::KeyNavDirection direction)
{
return tab_iterator_->KeyNavIteration(direction);
}
void Preview::SetFirstInTabOrder(nux::InputArea* area)
{
tab_iterator_->Prepend(area);
}
void Preview::SetLastInTabOrder(nux::InputArea* area)
{
tab_iterator_->Append(area);
}
void Preview::SetTabOrder(nux::InputArea* area, int index)
{
tab_iterator_->Insert(area, index);
}
void Preview::SetTabOrderBefore(nux::InputArea* area, nux::InputArea* after)
{
tab_iterator_->InsertBefore(area, after);
}
void Preview::SetTabOrderAfter(nux::InputArea* area, nux::InputArea* before)
{
tab_iterator_->InsertAfter(area, before);
}
void Preview::RemoveFromTabOrder(nux::InputArea* area)
{
tab_iterator_->Remove(area);
}
void Preview::OnNavigateIn()
{
nux::InputArea* default_focus = tab_iterator_->DefaultFocus();
if (default_focus)
nux::GetWindowCompositor().SetKeyFocusArea(default_focus);
}
sigc::signal Preview::request_close() const
{
return preview_container_->request_close;
}
void Preview::UpdateScale(double scale)
{
if (image_)
image_->scale = scale;
if (title_)
title_->SetScale(scale);
if (subtitle_)
subtitle_->SetScale(scale);
if (description_)
description_->SetScale(scale);
if (preview_container_)
preview_container_->scale = scale;
if (preview_info_hints_)
preview_info_hints_->scale = scale;
for (nux::AbstractButton* button : action_buttons_)
{
if (ActionButton* bn = dynamic_cast(button))
bn->scale = scale;
if (ActionLink* link = dynamic_cast(button))
link->scale = scale;
}
QueueRelayout();
QueueDraw();
}
} // preview
} // dash
} // unity