2
* Copyright 2011 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU Lesser General Public License version 3, as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranties of
10
* MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11
* PURPOSE. See the applicable version of the GNU Lesser General Public
12
* License for more details.
14
* You should have received a copy of both the GNU Lesser General Public
15
* License version 3 along with this program. If not, see
16
* <http://www.gnu.org/licenses/>
18
* Authored by: Gordon Allott <gord.allott@canonical.com>
25
#include <NuxCore/Logger.h>
27
#include "RatingsButton.h"
28
#include "DashStyle.h"
32
const int num_stars = 5;
37
RatingsButton::RatingsButton(int star_size, int star_gap, NUX_FILE_LINE_DECL)
38
: nux::ToggleButton(NUX_FILE_LINE_PARAM)
42
, star_size_(star_size)
45
SetAcceptKeyNavFocusOnMouseDown(false);
46
SetAcceptKeyNavFocusOnMouseEnter(true);
48
mouse_up.connect(sigc::mem_fun(this, &RatingsButton::RecvMouseUp));
49
mouse_move.connect(sigc::mem_fun(this, &RatingsButton::RecvMouseMove));
50
mouse_drag.connect(sigc::mem_fun(this, &RatingsButton::RecvMouseDrag));
52
key_nav_focus_change.connect([&](nux::Area* area, bool has_focus, nux::KeyNavDirection direction)
54
if (has_focus && direction != nux::KEY_NAV_NONE)
61
key_nav_focus_activate.connect([&](nux::Area*) { SetRating(static_cast<float>(focused_star_+1)/num_stars); });
62
key_down.connect(sigc::mem_fun(this, &RatingsButton::OnKeyDown));
65
RatingsButton::~RatingsButton()
69
void RatingsButton::SetEditable(bool editable)
77
void RatingsButton::SetRating(float rating)
83
float RatingsButton::GetRating() const
88
void RatingsButton::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
90
int rating = static_cast<int>(rating_ * num_stars);
92
// We should probably support an API for saying whether the ratings
93
// should or shouldn't support half stars...but our only consumer at
94
// the moment is the applications lens which according to design
95
// (Bug #839759) shouldn't. So for now just force rounding.
96
// int total_half_stars = rating % 2;
97
// int total_full_stars = rating / 2;
98
int total_full_stars = rating;
100
nux::Geometry const& geo = GetGeometry();
101
nux::Geometry geo_star(geo);
102
geo_star.width = star_size_;
103
geo_star.height = star_size_;
105
gPainter.PaintBackground(GfxContext, geo);
106
// set up our texture mode
107
nux::TexCoordXForm texxform;
108
texxform.SetWrap(nux::TEXWRAP_CLAMP_TO_BORDER, nux::TEXWRAP_CLAMP_TO_BORDER);
109
texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_SCALE_COORD);
110
texxform.SetFilter(nux::TEXFILTER_LINEAR, nux::TEXFILTER_LINEAR);
112
// clear what is behind us
113
unsigned int alpha = 0, src = 0, dest = 0;
115
GfxContext.GetRenderStates().GetBlend(alpha, src, dest);
116
GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
118
nux::Color col = nux::color::Black;
120
GfxContext.QRP_Color(geo.x,
126
for (int index = 0; index < num_stars; ++index)
128
dash::Style& style = dash::Style::Instance();
129
nux::BaseTexture* texture = style.GetStarSelectedIcon();
130
if (index < total_full_stars)
132
if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_NORMAL)
133
texture = style.GetStarSelectedIcon();
134
else if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRELIGHT)
135
texture = style.GetStarSelectedIcon();
136
else if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRESSED)
137
texture = style.GetStarSelectedIcon();
141
if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_NORMAL)
142
texture = style.GetStarDeselectedIcon();
143
else if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRELIGHT)
144
texture = style.GetStarDeselectedIcon();
145
else if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRESSED)
146
texture = style.GetStarDeselectedIcon();
149
GfxContext.QRP_1Tex(geo_star.x,
153
texture->GetDeviceTexture(),
155
nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
157
if (focused_star_ == index)
159
GfxContext.QRP_1Tex(geo_star.x,
163
style.GetStarHighlightIcon()->GetDeviceTexture(),
165
nux::Color(1.0f, 1.0f, 1.0f, 0.5f));
168
geo_star.x += geo_star.width + star_gap_;
172
GfxContext.GetRenderStates().SetBlend(alpha, src, dest);
176
void RatingsButton::UpdateRatingToMouse(int x)
178
int width = num_stars*star_size_ + (num_stars-1)*star_gap_;
179
float new_rating = (static_cast<float>(x) / width);
181
// FIXME: change to * 2 once we decide to support also half-stars
182
new_rating = ceil((num_stars * 1) * new_rating) / (num_stars * 1);
183
new_rating = (new_rating > 1) ? 1 : ((new_rating < 0) ? 0 : new_rating);
185
SetRating(new_rating);
188
void RatingsButton::RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags)
193
UpdateRatingToMouse(x);
196
void RatingsButton::RecvMouseDrag(int x, int y, int dx, int dy,
197
unsigned long button_flags,
198
unsigned long key_flags)
203
UpdateRatingToMouse(x);
206
void RatingsButton::RecvMouseMove(int x, int y, int dx, int dy,
207
unsigned long button_flags,
208
unsigned long key_flags)
213
int width = num_stars*star_size_+ (num_stars-1)*star_gap_;
214
focused_star_ = std::max(0, std::min(static_cast<int>(ceil((static_cast<float>(x) / width) * num_stars) - 1), num_stars - 1));
217
nux::GetWindowCompositor().SetKeyFocusArea(this);
223
bool RatingsButton::InspectKeyEvent(unsigned int eventType, unsigned int keysym, const char* character)
225
nux::KeyNavDirection direction = nux::KEY_NAV_NONE;
230
direction = nux::KeyNavDirection::KEY_NAV_LEFT;
233
direction = nux::KeyNavDirection::KEY_NAV_RIGHT;
236
direction = nux::KeyNavDirection::KEY_NAV_NONE;
240
if (direction == nux::KeyNavDirection::KEY_NAV_NONE)
242
else if (direction == nux::KEY_NAV_LEFT && (focused_star_ <= 0))
244
else if (direction == nux::KEY_NAV_RIGHT && (focused_star_ >= num_stars - 1))
251
void RatingsButton::OnKeyDown(unsigned long event_type, unsigned long event_keysym,
252
unsigned long event_state, const TCHAR* character,
253
unsigned short key_repeat_count)
258
switch (event_keysym)
273
bool RatingsButton::AcceptKeyNavFocus()