The Battle for Wesnoth  1.19.4+dev
scrollarea.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2004 - 2024
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;
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
unsigned get_max_position() const
Definition: scrollarea.cpp:86
void test_scrollbar()
Definition: scrollarea.cpp:63
bool has_scrollbar() const
Definition: scrollarea.cpp:33
void set_shown_size(unsigned h)
Definition: scrollarea.cpp:106
virtual void hide(bool value=true)
Definition: scrollarea.cpp:74
void adjust_position(unsigned pos)
Definition: scrollarea.cpp:96
scrollarea(bool auto_join=true)
Create a zone with automatic handling of scrollbar.
Definition: scrollarea.cpp:25
unsigned get_position() const
Definition: scrollarea.cpp:81
struct gui::scrollarea::@8 swipe_origin_
void set_full_size(unsigned h)
Definition: scrollarea.cpp:113
void set_position(unsigned pos)
Definition: scrollarea.cpp:91
virtual void update_location(const SDL_Rect &rect)
Definition: scrollarea.cpp:45
virtual void scroll(unsigned int pos)=0
scrollbar scrollbar_
Definition: scrollarea.hpp:57
virtual void process_event()
Definition: scrollarea.cpp:125
virtual sdl_handler_vector handler_members()
Definition: scrollarea.cpp:38
unsigned full_size_
Definition: scrollarea.hpp:61
rect inner_location() const
Definition: scrollarea.cpp:134
void move_position(int dep)
Definition: scrollarea.cpp:101
virtual void set_inner_location(const SDL_Rect &rect)=0
virtual void handle_event(const SDL_Event &event)
Definition: scrollarea.cpp:147
unsigned scrollbar_width() const
Definition: scrollarea.cpp:142
unsigned shown_size_
Definition: scrollarea.hpp:60
void set_scroll_rate(unsigned r)
Definition: scrollarea.cpp:120
void set_shown_size(unsigned h)
Set the relative size of the grip.
Definition: scrollbar.cpp:102
void set_scroll_rate(unsigned r)
Set scroll rate.
Definition: scrollbar.cpp:129
void scroll_up()
Scrolls up one step.
Definition: scrollbar.cpp:139
void move_position(int dep)
Move the scrollbar.
Definition: scrollbar.cpp:93
void set_position(unsigned pos)
Manually update the scrollbar.
Definition: scrollbar.cpp:75
void scroll_down()
Scrolls down one step.
Definition: scrollbar.cpp:134
void set_full_size(unsigned h)
Set the relative size of the scrollbar.
Definition: scrollbar.cpp:116
unsigned get_position() const
Determine where the scrollbar is.
Definition: scrollbar.cpp:65
unsigned get_max_position() const
Definition: scrollbar.cpp:70
void adjust_position(unsigned pos)
Ensure the viewport contains the position.
Definition: scrollbar.cpp:85
virtual void set_location(const SDL_Rect &rect)
Definition: widget.cpp:69
virtual void handle_event(const SDL_Event &) override
Definition: widget.hpp:90
const rect & location() const
Definition: widget.cpp:123
int width() const
Definition: widget.cpp:113
virtual void hide(bool value=true)
Definition: widget.cpp:141
int height() const
Definition: widget.cpp:118
bool hidden() const
Definition: widget.cpp:161
bool mouse_locked() const
Definition: widget.cpp:64
std::vector< events::sdl_handler * > sdl_handler_vector
Definition: events.hpp:190
int w
Contains functions for cleanly handling SDL input.
void rect(const SDL_Rect &rect)
Draw a rectangle.
Definition: draw.cpp:150
General purpose widgets.
uint32_t get_mouse_state(int *x, int *y)
A wrapper for SDL_GetMouseState that gives coordinates in draw space.
Definition: input.cpp:27
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
Definition: general.hpp:83
point game_canvas_size()
The size of the game canvas, in drawing coordinates / game pixels.
Definition: video.cpp:432
Contains the SDL_Rect helper code.
Holds a 2D point.
Definition: point.hpp:25
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:47
bool contains(int x, int y) const
Whether the given point lies within the rectangle.
Definition: rect.cpp:52
#define h