The Battle for Wesnoth  1.17.12+dev
scrollarea.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2004 - 2022
3  by Guillaume Melquiond <guillaume.melquiond@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #define GETTEXT_DOMAIN "wesnoth-lib"
17 
18 #include "widgets/scrollarea.hpp"
19 #include "sdl/input.hpp" // for get_mouse_state
20 #include "sdl/rect.hpp"
21 #include "video.hpp" // for converting input events to game coordinates
22 
23 namespace gui {
24 
25 scrollarea::scrollarea(const bool auto_join)
26  : widget(auto_join), scrollbar_(),
27  old_position_(0), recursive_(false), shown_scrollbar_(false),
28  shown_size_(0), full_size_(0), swipe_dy_(0)
29 {
30  scrollbar_.hide(true);
31 }
32 
34 {
35  return shown_size_ < full_size_;
36 }
37 
39 {
41  h.push_back(&scrollbar_);
42  return h;
43 }
44 
45 void scrollarea::update_location(const SDL_Rect& rect)
46 {
47  SDL_Rect r = rect;
49  if (shown_scrollbar_) {
50  int w = r.w - scrollbar_.width();
51  r.x += w;
52  r.w -= w;
54  r.x -= w;
55  r.w = w;
56  }
57 
58  if (!hidden())
61 }
62 
64 {
65  if (recursive_)
66  return;
67  recursive_ = true;
70  }
71  recursive_ = false;
72 }
73 
74 void scrollarea::hide(bool value)
75 {
76  widget::hide(value);
77  if (shown_scrollbar_)
78  scrollbar_.hide(value);
79 }
80 
81 unsigned scrollarea::get_position() const
82 {
83  return scrollbar_.get_position();
84 }
85 
87 {
89 }
90 
91 void scrollarea::set_position(unsigned pos)
92 {
94 }
95 
96 void scrollarea::adjust_position(unsigned pos)
97 {
99 }
100 
102 {
104 }
105 
107 {
109  shown_size_ = h;
110  test_scrollbar();
111 }
112 
114 {
116  full_size_ = h;
117  test_scrollbar();
118 }
119 
121 {
123 }
124 
126 {
127  int grip_position = scrollbar_.get_position();
128  if (grip_position == old_position_)
129  return;
130  old_position_ = grip_position;
131  scroll(grip_position);
132 }
133 
135 {
136  rect r = location();
137  if (shown_scrollbar_)
138  r.w -= scrollbar_.width();
139  return r;
140 }
141 
143 {
144  return scrollbar_.width();
145 }
146 
147 void scrollarea::handle_event(const SDL_Event& event)
148 {
150 
151  if (mouse_locked() || hidden())
152  return;
153 
154  if (event.type == SDL_MOUSEWHEEL) {
155  const SDL_MouseWheelEvent &ev = event.wheel;
156  int x, y;
157  sdl::get_mouse_state(&x, &y);
158  if (inner_location().contains(x, y)) {
159  if (ev.y > 0) {
161  } else if (ev.y < 0) {
163  }
164  }
165  }
166 
167  if (event.type == SDL_FINGERUP) {
168  swipe_dy_ = 0;
169  }
170 
171  if (event.type == SDL_FINGERDOWN || event.type == SDL_FINGERMOTION) {
172  // These events are given as a proportion of the full game canvas.
173  // 0.0 is top/left edge, 1.0 is bottom/right edge.
174  // Thus first convert them to game pixels.
175  point canvas_size = video::game_canvas_size();
176  auto tx = static_cast<int>(event.tfinger.x * canvas_size.x);
177  auto ty = static_cast<int>(event.tfinger.y * canvas_size.y);
178  auto dy = static_cast<int>(event.tfinger.dy * canvas_size.y);
179 
180  if (event.type == SDL_FINGERDOWN) {
181  swipe_dy_ = 0;
182  swipe_origin_.x = tx;
183  swipe_origin_.y = ty;
184  }
185 
186  if (event.type == SDL_FINGERMOTION) {
187 
188  swipe_dy_ += dy;
189  if (scrollbar_.get_max_position() == 0) {
190  return;
191  }
192 
193  int scrollbar_step = scrollbar_.height() / scrollbar_.get_max_position();
194  if (scrollbar_step <= 0) {
195  return;
196  }
197 
199  && abs(swipe_dy_) >= scrollbar_step)
200  {
201  unsigned int pos = std::max(
202  static_cast<int>(scrollbar_.get_position() - swipe_dy_ / scrollbar_step),
203  0);
205  swipe_dy_ %= scrollbar_step;
206  }
207  }
208  }
209 
210 }
211 
212 } // end namespace gui
virtual void set_inner_location(const SDL_Rect &rect)=0
void set_shown_size(unsigned h)
Definition: scrollarea.cpp:106
void adjust_position(unsigned pos)
Definition: scrollarea.cpp:96
std::vector< events::sdl_handler * > sdl_handler_vector
Definition: events.hpp:190
bool hidden() const
Definition: widget.cpp:162
unsigned get_position() const
Determine where the scrollbar is.
Definition: scrollbar.cpp:65
unsigned scrollbar_width() const
Definition: scrollarea.cpp:142
virtual sdl_handler_vector handler_members()
Definition: scrollarea.cpp:38
unsigned get_max_position() const
Definition: scrollbar.cpp:70
General purpose widgets.
virtual void update_location(const SDL_Rect &rect)
Definition: scrollarea.cpp:45
#define h
void set_scroll_rate(unsigned r)
Definition: scrollarea.cpp:120
scrollarea(bool auto_join=true)
Create a zone with automatic handling of scrollbar.
Definition: scrollarea.cpp:25
void test_scrollbar()
Definition: scrollarea.cpp:63
void move_position(int dep)
Definition: scrollarea.cpp:101
Contains functions for cleanly handling SDL input.
void rect(const SDL_Rect &rect)
Draw a rectangle.
Definition: draw.cpp:141
void scroll_down()
Scrolls down one step.
Definition: scrollbar.cpp:134
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
Definition: general.hpp:84
virtual void scroll(unsigned int pos)=0
void set_full_size(unsigned h)
Definition: scrollarea.cpp:113
bool has_scrollbar() const
Definition: scrollarea.cpp:33
void set_position(unsigned pos)
Definition: scrollarea.cpp:91
virtual void hide(bool value=true)
Definition: widget.cpp:142
const rect & location() const
Definition: widget.cpp:124
virtual void set_location(const SDL_Rect &rect)
Definition: widget.cpp:70
void set_position(unsigned pos)
Manually update the scrollbar.
Definition: scrollbar.cpp:75
void adjust_position(unsigned pos)
Ensure the viewport contains the position.
Definition: scrollbar.cpp:85
unsigned full_size_
Definition: scrollarea.hpp:61
scrollbar scrollbar_
Definition: scrollarea.hpp:57
virtual void handle_event(const SDL_Event &) override
Definition: widget.hpp:91
point game_canvas_size()
The size of the game canvas, in drawing coordinates / game pixels.
Definition: video.cpp:427
virtual void handle_event(const SDL_Event &event)
Definition: scrollarea.cpp:147
unsigned get_max_position() const
Definition: scrollarea.cpp:86
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:46
Holds a 2D point.
Definition: point.hpp:24
int width() const
Definition: widget.cpp:114
int w
int height() const
Definition: widget.cpp:119
void scroll_up()
Scrolls up one step.
Definition: scrollbar.cpp:139
bool mouse_locked() const
Definition: widget.cpp:65
virtual void hide(bool value=true)
Definition: scrollarea.cpp:74
unsigned shown_size_
Definition: scrollarea.hpp:60
Contains the SDL_Rect helper code.
void set_shown_size(unsigned h)
Set the relative size of the grip.
Definition: scrollbar.cpp:102
uint32_t get_mouse_state(int *x, int *y)
A wrapper for SDL_GetMouseState that gives coordinates in draw space.
Definition: input.cpp:27
void set_full_size(unsigned h)
Set the relative size of the scrollbar.
Definition: scrollbar.cpp:116
void set_scroll_rate(unsigned r)
Set scroll rate.
Definition: scrollbar.cpp:129
rect inner_location() const
Definition: scrollarea.cpp:134
void move_position(int dep)
Move the scrollbar.
Definition: scrollbar.cpp:93
virtual void process_event()
Definition: scrollarea.cpp:125
unsigned get_position() const
Definition: scrollarea.cpp:81
struct gui::scrollarea::@9 swipe_origin_