The Battle for Wesnoth  1.19.7+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;
157  if (ev.y > 0) {
159  } else if (ev.y < 0) {
161  }
162  }
163  }
164 
165  if (event.type == SDL_FINGERUP) {
166  swipe_dy_ = 0;
167  }
168 
169  if (event.type == SDL_FINGERDOWN || event.type == SDL_FINGERMOTION) {
170  // These events are given as a proportion of the full game canvas.
171  // 0.0 is top/left edge, 1.0 is bottom/right edge.
172  // Thus first convert them to game pixels.
173  point canvas_size = video::game_canvas_size();
174  auto tx = static_cast<int>(event.tfinger.x * canvas_size.x);
175  auto ty = static_cast<int>(event.tfinger.y * canvas_size.y);
176  auto dy = static_cast<int>(event.tfinger.dy * canvas_size.y);
177 
178  if (event.type == SDL_FINGERDOWN) {
179  swipe_dy_ = 0;
180  swipe_origin_.x = tx;
181  swipe_origin_.y = ty;
182  }
183 
184  if (event.type == SDL_FINGERMOTION) {
185 
186  swipe_dy_ += dy;
187  if (scrollbar_.get_max_position() == 0) {
188  return;
189  }
190 
191  int scrollbar_step = scrollbar_.height() / scrollbar_.get_max_position();
192  if (scrollbar_step <= 0) {
193  return;
194  }
195 
197  && abs(swipe_dy_) >= scrollbar_step)
198  {
199  unsigned int pos = std::max(
200  static_cast<int>(scrollbar_.get_position() - swipe_dy_ / scrollbar_step),
201  0);
203  swipe_dy_ %= scrollbar_step;
204  }
205  }
206  }
207 
208 }
209 
210 } // 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:182
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.
point get_mouse_location()
Returns the current mouse location in draw space.
Definition: input.cpp:54
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
Definition: general.hpp:86
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:53
#define h