22 PGScrollFrame(
const std::string &name) :
24 _needs_remanage(false),
25 _needs_recompute_clip(false),
26 _has_virtual_frame(false),
27 _virtual_frame(0.0f, 0.0f, 0.0f, 0.0f),
28 _manage_pieces(false),
31 _canvas_computed.test_and_set();
51 _has_virtual_frame(copy._has_virtual_frame),
52 _virtual_frame(copy._virtual_frame),
53 _manage_pieces(copy._manage_pieces),
54 _auto_hide(copy._auto_hide)
56 _needs_remanage =
false;
57 _needs_recompute_clip =
true;
58 _canvas_computed.clear();
93 if (_manage_pieces && _needs_remanage) {
96 if (_needs_recompute_clip) {
99 if (!_canvas_computed.test_and_set()) {
102 return PGVirtualFrame::cull_callback(trav, data);
112 PGVirtualFrame::xform(mat);
114 _needs_remanage =
true;
115 _needs_recompute_clip =
true;
123 setup(PN_stdfloat width, PN_stdfloat height,
124 PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top,
125 PN_stdfloat slider_width, PN_stdfloat bevel) {
136 style.
set_type(PGFrameStyle::T_ridge);
140 bevel, height - bevel);
145 if (_horizontal_slider !=
nullptr) {
149 if (_vertical_slider !=
nullptr) {
156 horizontal_slider->setup_scroll_bar(
false, width - slider_width - bevel * 2, slider_width, bevel);
157 horizontal_slider->set_transform(TransformState::make_pos(LVector3::rfu(width / 2.0f - slider_width / 2.0f, 0, slider_width / 2.0f + bevel)));
158 add_child(horizontal_slider);
162 vertical_slider->setup_scroll_bar(
true, width - slider_width - bevel * 2, slider_width, bevel);
163 add_child(vertical_slider);
164 vertical_slider->set_transform(TransformState::make_pos(LVector3::rfu(width - slider_width / 2.0f - bevel, 0, width / 2.0f + slider_width / 2.0f)));
178 _needs_remanage =
false;
185 bool got_horizontal =
false;
186 PN_stdfloat horizontal_width = 0.0f;
187 if (_horizontal_slider !=
nullptr) {
188 got_horizontal =
true;
189 const LVecBase4 &slider_frame = _horizontal_slider->get_frame();
190 horizontal_width = slider_frame[3] - slider_frame[2];
193 bool got_vertical =
false;
194 PN_stdfloat vertical_width = 0.0f;
195 if (_vertical_slider !=
nullptr) {
197 const LVecBase4 &slider_frame = _vertical_slider->get_frame();
198 vertical_width = slider_frame[1] - slider_frame[0];
205 PN_stdfloat clip_width = clip[1] - clip[0];
206 PN_stdfloat clip_height = clip[3] - clip[2];
210 PN_stdfloat virtual_width = virtual_frame[1] - virtual_frame[0];
211 PN_stdfloat virtual_height = virtual_frame[3] - virtual_frame[2];
213 if (virtual_width <= clip_width &&
214 virtual_height <= clip_height) {
216 got_horizontal =
false;
217 got_vertical =
false;
220 if (virtual_width <= clip_width - vertical_width) {
222 got_horizontal =
false;
225 if (virtual_height <= clip_height - horizontal_width) {
227 got_vertical =
false;
230 if (virtual_width <= clip_width) {
231 got_horizontal =
false;
237 if (_horizontal_slider !=
nullptr) {
238 if (got_horizontal) {
239 _horizontal_slider->set_overall_hidden(
false);
241 _horizontal_slider->set_overall_hidden(
true);
242 _horizontal_slider->set_ratio(0.0f);
243 horizontal_width = 0.0f;
246 if (_vertical_slider !=
nullptr) {
248 _vertical_slider->set_overall_hidden(
false);
250 _vertical_slider->set_overall_hidden(
true);
251 _vertical_slider->set_ratio(0.0f);
252 vertical_width = 0.0f;
258 _needs_remanage =
false;
262 if (got_horizontal && _horizontal_slider->is_overall_hidden()) {
263 got_horizontal =
false;
264 horizontal_width = 0.0f;
266 if (got_vertical && _vertical_slider->is_overall_hidden()) {
267 got_vertical =
false;
268 vertical_width = 0.0f;
271 if (got_horizontal) {
272 _horizontal_slider->set_frame(clip[0], clip[1] - vertical_width,
273 clip[2], clip[2] + horizontal_width);
274 _horizontal_slider->clear_transform();
277 _vertical_slider->set_frame(clip[1] - vertical_width, clip[1],
278 clip[2] + horizontal_width, clip[3]);
279 _vertical_slider->clear_transform();
292 PGVirtualFrame::frame_changed();
293 _needs_remanage =
true;
294 _needs_recompute_clip =
true;
301 item_transform_changed(
PGItem *) {
303 _needs_recompute_clip =
true;
310 item_frame_changed(
PGItem *) {
312 _needs_recompute_clip =
true;
319 item_draw_mask_changed(
PGItem *) {
321 _needs_remanage =
true;
322 _needs_recompute_clip =
true;
332 _canvas_computed.clear();
343 _needs_recompute_clip =
false;
344 _canvas_computed.clear();
348 reduce_region(clip, _horizontal_slider);
349 reduce_region(clip, _vertical_slider);
353 if (_horizontal_slider !=
nullptr) {
354 _horizontal_slider->set_page_size((clip[1] - clip[0]) / (_virtual_frame[1] - _virtual_frame[0]));
356 if (_vertical_slider !=
nullptr) {
357 _vertical_slider->set_page_size((clip[3] - clip[2]) / (_virtual_frame[3] - _virtual_frame[2]));
369 const LVecBase4 &clip = _has_clip_frame ? _clip_frame :
get_frame();
374 _canvas_computed.test_and_set();
377 cx = interpolate_canvas(clip[0], clip[1],
378 _virtual_frame[0], _virtual_frame[1],
381 cy = interpolate_canvas(clip[3], clip[2],
382 _virtual_frame[3], _virtual_frame[2],
385 _canvas_node->set_transform(TransformState::make_pos(LVector3::rfu(cx, 0, cy)));
394 PN_stdfloat PGScrollFrame::
395 interpolate_canvas(PN_stdfloat clip_min, PN_stdfloat clip_max,
396 PN_stdfloat canvas_min, PN_stdfloat canvas_max,
398 PN_stdfloat t = 0.0f;
399 if (slider_bar !=
nullptr) {
403 PN_stdfloat min = clip_min - canvas_min;
404 PN_stdfloat max = clip_max - canvas_max;
406 return min + t * (max - min);
LVecBase4 get_internal_frame(const LVecBase4 &frame) const
Computes the size of the internal frame, given the indicated external frame, appropriate for this kin...
A basic node of the scene graph or data graph.
void set_width(PN_stdfloat x, PN_stdfloat y)
Sets the width parameter, which has meaning only for certain frame types.
PGFrameStyle get_frame_style(int state)
Returns the kind of frame that will be drawn behind the item when it is in the indicated state.
void remove_child(int child_index, Thread *current_thread=Thread::get_current_thread())
Removes the nth child from the node.
This is the base class for all the various kinds of gui widget objects.
int get_state() const
Returns the "state" of this particular PGItem.
This represents a frame that is rendered as a window onto another (possibly much larger) canvas.
void set_clip_frame(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top)
Sets the bounding rectangle of the clip frame.
void set_type(Type type)
Sets the basic type of frame.
void set_frame(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top)
Sets the bounding rectangle of the item, in local coordinates.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
void set_frame_style(int state, const PGFrameStyle &style)
Changes the kind of frame that will be drawn behind the item when it is in the indicated state.
void set_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a)
Sets the dominant color of the frame.
Similar to MutexHolder, but for a light reentrant mutex.
void set_state(int state)
Sets the "state" of this particular PGItem.
void clear_state_def(int state)
Resets the NodePath assigned to the indicated state to its initial default, with only a frame represe...
const LVecBase4 & get_frame() const
Returns the bounding rectangle of the item.
TypeHandle is the identifier used to differentiate C++ class types.
PN_stdfloat get_ratio() const
Returns the current value of the slider, expressed in the range 0 .
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
This is a particular kind of PGItem that draws a little bar with a slider that moves from left to rig...