~bilalakhtar/unity/sd-card-stop-device-960910

« back to all changes in this revision

Viewing changes to unity-shared/RatingsButton.cpp

  • Committer: Bilal Akhtar
  • Date: 2012-08-21 17:50:55 UTC
  • mfrom: (2540.2.61 unity)
  • Revision ID: bilalakhtar@ubuntu.com-20120821175055-2nyk2ne624tcd247
Merge from trunk and resolve conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2011 Canonical Ltd.
 
3
 *
 
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.
 
7
 *
 
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.
 
13
 *
 
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/>
 
17
 *
 
18
 * Authored by: Gordon Allott <gord.allott@canonical.com>
 
19
 *
 
20
 */
 
21
 
 
22
#include <math.h>
 
23
 
 
24
#include <Nux/Nux.h>
 
25
#include <NuxCore/Logger.h>
 
26
 
 
27
#include "RatingsButton.h"
 
28
#include "DashStyle.h"
 
29
 
 
30
namespace
 
31
{
 
32
const int num_stars = 5;
 
33
}
 
34
 
 
35
namespace unity
 
36
{
 
37
RatingsButton::RatingsButton(int star_size, int star_gap, NUX_FILE_LINE_DECL)
 
38
  : nux::ToggleButton(NUX_FILE_LINE_PARAM)
 
39
  , editable_(true)
 
40
  , rating_(0.0)
 
41
  , focused_star_(-1)
 
42
  , star_size_(star_size)
 
43
  , star_gap_(star_gap)
 
44
{
 
45
  SetAcceptKeyNavFocusOnMouseDown(false);
 
46
  SetAcceptKeyNavFocusOnMouseEnter(true);
 
47
 
 
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));
 
51
 
 
52
  key_nav_focus_change.connect([&](nux::Area* area, bool has_focus, nux::KeyNavDirection direction)
 
53
  {
 
54
    if (has_focus && direction != nux::KEY_NAV_NONE)
 
55
      focused_star_ = 0;
 
56
    else if (!has_focus)
 
57
      focused_star_ = -1;
 
58
 
 
59
    QueueDraw();
 
60
  });
 
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));
 
63
}
 
64
 
 
65
RatingsButton::~RatingsButton()
 
66
{
 
67
}
 
68
 
 
69
void RatingsButton::SetEditable(bool editable)
 
70
{
 
71
  editable_ = editable;
 
72
  if (!editable_)
 
73
    focused_star_ = -1;
 
74
  QueueDraw();
 
75
}
 
76
 
 
77
void RatingsButton::SetRating(float rating)
 
78
{
 
79
  rating_  = rating;
 
80
  QueueDraw();
 
81
}
 
82
 
 
83
float RatingsButton::GetRating() const
 
84
{
 
85
  return rating_;
 
86
}
 
87
 
 
88
void RatingsButton::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
 
89
{
 
90
  int rating =  static_cast<int>(rating_ * num_stars);
 
91
  // FIXME: 9/26/2011
 
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;
 
99
 
 
100
  nux::Geometry const& geo = GetGeometry();
 
101
  nux::Geometry geo_star(geo);
 
102
  geo_star.width = star_size_;
 
103
  geo_star.height = star_size_;
 
104
 
 
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);
 
111
 
 
112
  // clear what is behind us
 
113
  unsigned int alpha = 0, src = 0, dest = 0;
 
114
 
 
115
  GfxContext.GetRenderStates().GetBlend(alpha, src, dest);
 
116
  GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 
117
 
 
118
  nux::Color col = nux::color::Black;
 
119
  col.alpha = 0;
 
120
  GfxContext.QRP_Color(geo.x,
 
121
                       geo.y,
 
122
                       geo.width,
 
123
                       geo.height,
 
124
                       col);
 
125
 
 
126
  for (int index = 0; index < num_stars; ++index)
 
127
  {
 
128
    dash::Style& style = dash::Style::Instance();
 
129
    nux::BaseTexture* texture = style.GetStarSelectedIcon();
 
130
    if (index < total_full_stars)
 
131
    {
 
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();
 
138
    }
 
139
    else
 
140
    {
 
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();
 
147
    }
 
148
 
 
149
    GfxContext.QRP_1Tex(geo_star.x,
 
150
                        geo_star.y,
 
151
                        geo_star.width,
 
152
                        geo_star.height,
 
153
                        texture->GetDeviceTexture(),
 
154
                        texxform,
 
155
                        nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
 
156
 
 
157
    if (focused_star_ == index)
 
158
    {
 
159
      GfxContext.QRP_1Tex(geo_star.x,
 
160
                          geo_star.y,
 
161
                          geo_star.width,
 
162
                          geo_star.height,
 
163
                          style.GetStarHighlightIcon()->GetDeviceTexture(),
 
164
                          texxform,
 
165
                          nux::Color(1.0f, 1.0f, 1.0f, 0.5f));
 
166
    }
 
167
 
 
168
    geo_star.x += geo_star.width + star_gap_;
 
169
 
 
170
  }
 
171
 
 
172
  GfxContext.GetRenderStates().SetBlend(alpha, src, dest);
 
173
 
 
174
}
 
175
 
 
176
void RatingsButton::UpdateRatingToMouse(int x)
 
177
{
 
178
  int width = num_stars*star_size_ + (num_stars-1)*star_gap_;
 
179
  float new_rating = (static_cast<float>(x) / width);
 
180
 
 
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);
 
184
 
 
185
  SetRating(new_rating);
 
186
}
 
187
 
 
188
void RatingsButton::RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags)
 
189
{
 
190
  if (!editable_)
 
191
    return;
 
192
 
 
193
  UpdateRatingToMouse(x);
 
194
}
 
195
 
 
196
void RatingsButton::RecvMouseDrag(int x, int y, int dx, int dy,
 
197
                                        unsigned long button_flags,
 
198
                                        unsigned long key_flags)
 
199
{
 
200
  if (!editable_)
 
201
    return;
 
202
 
 
203
  UpdateRatingToMouse(x);
 
204
}
 
205
 
 
206
void RatingsButton::RecvMouseMove(int x, int y, int dx, int dy,
 
207
                                        unsigned long button_flags,
 
208
                                        unsigned long key_flags)
 
209
{
 
210
  if (!editable_)
 
211
    return;
 
212
 
 
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));
 
215
 
 
216
  if (!HasKeyFocus())
 
217
    nux::GetWindowCompositor().SetKeyFocusArea(this);
 
218
 
 
219
  QueueDraw();
 
220
}
 
221
 
 
222
 
 
223
bool RatingsButton::InspectKeyEvent(unsigned int eventType, unsigned int keysym, const char* character)
 
224
{
 
225
  nux::KeyNavDirection direction = nux::KEY_NAV_NONE;
 
226
 
 
227
  switch (keysym)
 
228
  {
 
229
    case NUX_VK_LEFT:
 
230
      direction = nux::KeyNavDirection::KEY_NAV_LEFT;
 
231
      break;
 
232
    case NUX_VK_RIGHT:
 
233
      direction = nux::KeyNavDirection::KEY_NAV_RIGHT;
 
234
      break;
 
235
    default:
 
236
      direction = nux::KeyNavDirection::KEY_NAV_NONE;
 
237
      break;
 
238
  }
 
239
 
 
240
  if (direction == nux::KeyNavDirection::KEY_NAV_NONE)
 
241
    return false;
 
242
  else if (direction == nux::KEY_NAV_LEFT && (focused_star_ <= 0))
 
243
    return false;
 
244
  else if (direction == nux::KEY_NAV_RIGHT && (focused_star_ >= num_stars - 1))
 
245
    return false;
 
246
  else
 
247
   return true;
 
248
}
 
249
 
 
250
 
 
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)
 
254
{
 
255
  if (!editable_)
 
256
    return;
 
257
 
 
258
  switch (event_keysym)
 
259
  {
 
260
    case NUX_VK_LEFT:
 
261
      --focused_star_;
 
262
      break;
 
263
    case NUX_VK_RIGHT:
 
264
      ++focused_star_;
 
265
      break;
 
266
    default:
 
267
      return;
 
268
  }
 
269
 
 
270
  QueueDraw();
 
271
}
 
272
 
 
273
bool RatingsButton::AcceptKeyNavFocus()
 
274
{
 
275
  return true;
 
276
}
 
277
 
 
278
} // namespace unity