// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
/*
* Copyright (C) 2014 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Marco Trevisan
*/
#include
#include "PanelIndicatorEntryDropdownView.h"
#include "unity-shared/WindowManager.h"
#include "unity-shared/PanelStyle.h"
namespace unity
{
namespace panel
{
using namespace indicator;
namespace
{
const std::string ICON_NAME = "go-down-symbolic";
}
PanelIndicatorEntryDropdownView::PanelIndicatorEntryDropdownView(std::string const& indicator, Indicators::Ptr const& indicators)
: PanelIndicatorEntryView(std::make_shared(indicator+"-dropdown"), 5, IndicatorEntryType::DROP_DOWN)
, indicators_(indicators)
{
proxy_->set_priority(std::numeric_limits::max());
// This is a workaround we need to compute the dropdown size on construction
SetProxyVisibility(true);
SetProxyVisibility(false);
}
void PanelIndicatorEntryDropdownView::SetProxyVisibility(bool visible)
{
if (proxy_->visible() == visible)
return;
proxy_->set_image(GTK_IMAGE_ICON_NAME, ICON_NAME, visible, visible);
}
void PanelIndicatorEntryDropdownView::Push(PanelIndicatorEntryView::Ptr const& child)
{
if (!child)
return;
if (std::find(children_.begin(), children_.end(), child) != children_.end())
return;
children_.push_back(child);
child->GetEntry()->add_parent(proxy_);
debug::Introspectable::AddChild(child.GetPointer());
SetProxyVisibility(true);
}
void PanelIndicatorEntryDropdownView::Insert(PanelIndicatorEntryView::Ptr const& child)
{
if (!child)
return;
if (std::find(children_.begin(), children_.end(), child) != children_.end())
return;
auto it = children_.begin();
for (; it != children_.end(); ++it)
{
if (child->GetEntryPriority() <= (*it)->GetEntryPriority())
break;
}
children_.insert(it, child);
child->GetEntry()->add_parent(proxy_);
debug::Introspectable::AddChild(child.GetPointer());
SetProxyVisibility(true);
}
PanelIndicatorEntryView::Ptr PanelIndicatorEntryDropdownView::Pop()
{
if (children_.empty())
return PanelIndicatorEntryView::Ptr();
auto child = children_.front();
Remove(child);
return child;
}
void PanelIndicatorEntryDropdownView::Clear()
{
children_.clear();
}
std::deque const& PanelIndicatorEntryDropdownView::Children() const
{
return children_;
}
PanelIndicatorEntryView::Ptr PanelIndicatorEntryDropdownView::Top() const
{
return (!children_.empty()) ? children_.front() : PanelIndicatorEntryView::Ptr();
}
size_t PanelIndicatorEntryDropdownView::Size() const
{
return children_.size();
}
bool PanelIndicatorEntryDropdownView::Empty() const
{
return children_.empty();
}
void PanelIndicatorEntryDropdownView::Remove(PanelIndicatorEntryView::Ptr const& child)
{
auto it = std::find(children_.begin(), children_.end(), child);
if (it != children_.end())
{
debug::Introspectable::RemoveChild(it->GetPointer());
child->GetEntry()->rm_parent(proxy_);
children_.erase(it);
}
if (children_.empty())
SetProxyVisibility(false);
}
void PanelIndicatorEntryDropdownView::ShowMenu(int button)
{
if (children_.empty())
return;
Indicator::Entries entries;
for (auto const& entry : children_)
entries.push_back(entry->GetEntry());
auto const& geo = GetAbsoluteGeometry();
indicators_->ShowEntriesDropdown(entries, active_entry_, entries[0]->parent_window(), geo.x, geo.y + geo.height);
}
bool PanelIndicatorEntryDropdownView::ActivateChild(PanelIndicatorEntryView::Ptr const& child)
{
for (auto const& entry : children_)
{
if (entry == child)
{
active_entry_ = entry->GetEntry();
Activate();
active_entry_ = nullptr;
return true;
}
}
return false;
}
} // panel namespace
} // unity namespace