• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

KazDragon / munin / 23712240864

29 Mar 2026 03:20PM UTC coverage: 98.291%. Remained the same
23712240864

push

github

web-flow
Vcpkg metaproject support (#276)

* feat: add gitattributes for sane cross-platform line endings

* Add transitive dependencies to CMake package config

* Generated files now generated in binary directory

* Update CI runner to use vcpkg

* Cache vcpkg in appveyor

* Fix runner script

* Correct linkage of test to "local" munin target

* include GoogleTest for gmock

* Build diagnostic.

* Fix terminalpp import to have a build type

* Fix line endings

* Revert diagnostic patch

---------

Co-authored-by: PerdixOfMars <perdix.p76l@googlemail.com>

706 of 712 new or added lines in 11 files covered. (99.16%)

2530 of 2574 relevant lines covered (98.29%)

470.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.36
/src/container.cpp
1
#include "munin/container.hpp"
2

3
#include "munin/detail/algorithm.hpp"
4
#include "munin/detail/json_adaptors.hpp"
5
#include "munin/layout.hpp"
6
#include "munin/null_layout.hpp"
7
#include "munin/render_surface.hpp"
8

9
#include <boost/scope_exit.hpp>
10
#include <terminalpp/mouse.hpp>
11
#include <terminalpp/rectangle.hpp>
12

13
#include <algorithm>
14
#include <memory>
15
#include <ranges>
16
#include <vector>
17

18
namespace munin {
19

20
namespace {
21

22
using component_connections = std::vector<boost::signals2::connection>;
23

24
auto find_first_focussed_component(std::ranges::forward_range auto const &rng)
167✔
25
{
26
    auto const &component_has_focus = [](auto const &comp) {
520✔
27
        return comp->has_focus();
353✔
28
    };
29

30
    return std::ranges::find_if(rng, component_has_focus);
334✔
31
}
32

33
template <class ForwardRange, class IncrementFunction>
34
auto increment_focus(ForwardRange const &rng, IncrementFunction &&increment)
103✔
35
{
36
    return std::ranges::find_if(
81✔
37
        rng, std::forward<IncrementFunction>(increment));
184✔
38
}
39

40
template <class ForwardRange>
41
auto find_component_at_point(
6✔
42
    ForwardRange const &rng, terminalpp::point const &location)
43
{
44
    auto const &has_location_at_point = [&location](auto const &comp) {
13✔
45
        auto const &position = comp->get_position();
7✔
46
        auto const &size = comp->get_size();
7✔
47

48
        // Check to see if the reported position is within the component's
49
        // bounds.
50
        return (
51
            location.x_ >= position.x_
7✔
52
            && location.x_ < position.x_ + size.width_
7✔
53
            && location.y_ >= position.y_
6✔
54
            && location.y_ < position.y_ + size.height_);
21✔
55
    };
56

57
    return std::ranges::find_if(rng, has_location_at_point);
12✔
58
}
59

60
}  // namespace
61

62
// ==========================================================================
63
// CONTAINER::IMPLEMENTATION STRUCTURE
64
// ==========================================================================
65
struct container::impl
66
{
67
    // ======================================================================
68
    // CONSTRUCTOR
69
    // ======================================================================
70
    explicit impl(container &self) : self_(self)
500✔
71
    {
72
    }
500✔
73

74
    // ======================================================================
75
    // SET_LAYOUT
76
    // ======================================================================
77
    void set_layout(std::unique_ptr<munin::layout> &&lyt)
393✔
78
    {
79
        layout_ = lyt == nullptr ? make_null_layout() : std::move(lyt);
393✔
80
        layout_container();
393✔
81
    }
393✔
82

83
    // ======================================================================
84
    // ADD_COMPONENT
85
    // ======================================================================
86
    void add_component(
1,177✔
87
        std::shared_ptr<component> const &comp, std::any const &layout_hint)
88
    {
89
        component_connections cnx;
1,177✔
90

91
        cnx.push_back(comp->on_focus_set.connect(
2,354✔
92
            [this, wcomp = std::weak_ptr<component>(comp)] {
2,354✔
93
                this->subcomponent_focus_set_handler(wcomp);
28✔
94
            }));
28✔
95

96
        cnx.push_back(comp->on_focus_lost.connect(
2,354✔
97
            [this] { this->subcomponent_focus_lost_handler(); }));
1,188✔
98

99
        cnx.push_back(comp->on_cursor_state_changed.connect(
2,354✔
100
            [this, wcomp = std::weak_ptr<component>(comp)] {
2,354✔
101
                this->subcomponent_cursor_state_change_handler(wcomp);
8✔
102
            }));
8✔
103

104
        cnx.push_back(comp->on_cursor_position_changed.connect(
2,354✔
105
            [this, wcomp = std::weak_ptr<component>(comp)] {
2,354✔
106
                this->subcomponent_cursor_position_change_handler(wcomp);
9✔
107
            }));
9✔
108

109
        cnx.push_back(comp->on_redraw.connect(
2,354✔
110
            [this, wcomp = std::weak_ptr<component>(comp)](
2,354✔
111
                auto const &redraw_regions) {
112
                this->subcomponent_redraw_handler(wcomp, redraw_regions);
182✔
113
            }));
182✔
114

115
        components_.push_back(comp);
1,177✔
116
        hints_.push_back(layout_hint);
1,177✔
117
        component_connections_.push_back(cnx);
1,177✔
118
        layout_container();
1,177✔
119
        self_.on_preferred_size_changed();
1,177✔
120
    }
1,177✔
121

122
    // ======================================================================
123
    // REMOVE_COMPONENT
124
    // ======================================================================
125
    void remove_component(std::shared_ptr<component> const &comp)
3✔
126
    {
127
        auto const &disconnect_connection = [](auto &cnx) { cnx.disconnect(); };
15✔
128

129
        for (auto index = 0; index < components_.size(); ++index)
6✔
130
        {
131
            if (components_[index] == comp)
3✔
132
            {
133
                components_.erase(components_.begin() + index);
3✔
134
                hints_.erase(hints_.begin() + index);
3✔
135
                std::ranges::for_each(
3✔
136
                    component_connections_[index], disconnect_connection);
3✔
137

138
                component_connections_.erase(
3✔
139
                    component_connections_.begin() + index);
6✔
140
            }
141
        }
142

143
        layout_container();
3✔
144
        self_.on_preferred_size_changed();
3✔
145
    }
3✔
146

147
    // ======================================================================
148
    // SET_POSITION
149
    // ======================================================================
150
    void set_position(terminalpp::point const &position)
1,477✔
151
    {
152
        bounds_.origin_ = position;
1,477✔
153
    }
1,477✔
154

155
    // ======================================================================
156
    // GET_POSITION
157
    // ======================================================================
158
    [[nodiscard]] terminalpp::point get_position() const
272✔
159
    {
160
        return bounds_.origin_;
272✔
161
    }
162

163
    // ======================================================================
164
    // SET_SIZE
165
    // ======================================================================
166
    void set_size(terminalpp::extent const &size)
1,556✔
167
    {
168
        bounds_.size_ = size;
1,556✔
169
        layout_container();
1,556✔
170
    }
1,556✔
171

172
    // ======================================================================
173
    // GET_SIZE
174
    // ======================================================================
175
    [[nodiscard]] terminalpp::extent get_size() const
256✔
176
    {
177
        return bounds_.size_;
256✔
178
    }
179

180
    // ======================================================================
181
    // GET_PREFERRED_SIZE
182
    // ======================================================================
183
    [[nodiscard]] terminalpp::extent get_preferred_size() const
1,349✔
184
    {
185
        return layout_->get_preferred_size(components_, hints_);
1,349✔
186
    }
187

188
    // ==========================================================================
189
    // DO_HAS_FOCUS
190
    // ==========================================================================
191
    [[nodiscard]] bool has_focus() const
203✔
192
    {
193
        return has_focus_;
203✔
194
    }
195

196
    // ======================================================================
197
    // SET_FOCUS
198
    // ======================================================================
199
    void set_focus()
58✔
200
    {
201
        in_focus_operation_ = true;
58✔
202

203
        BOOST_SCOPE_EXIT_ALL(this)
58✔
204
        {
205
            in_focus_operation_ = false;
58✔
206
        };
58✔
207

208
        if (!has_focus_)
58✔
209
        {
210
            auto const &set_component_focus = [](auto const &comp) {
157✔
211
                comp->set_focus();
100✔
212
                return comp->has_focus();
100✔
213
            };
214

215
            auto const &focussed_component =
216
                increment_focus(components_, set_component_focus);
57✔
217

218
            has_focus_ = focussed_component != components_.end();
57✔
219

220
            if (has_focus_)
57✔
221
            {
222
                self_.on_focus_set();
33✔
223
                self_.on_cursor_state_changed();
33✔
224
                self_.on_cursor_position_changed();
33✔
225
            }
226
        }
227
    }
58✔
228

229
    // ======================================================================
230
    // LOSE_FOCUS
231
    // ======================================================================
232
    void lose_focus()
5✔
233
    {
234
        in_focus_operation_ = true;
5✔
235

236
        BOOST_SCOPE_EXIT_ALL(this)
5✔
237
        {
238
            in_focus_operation_ = false;
5✔
239
        };
5✔
240

241
        if (auto focussed_component =
5✔
242
                find_first_focussed_component(components_);
5✔
243
            focussed_component != components_.end())
5✔
244
        {
245
            (*focussed_component)->lose_focus();
3✔
246
            has_focus_ = false;
3✔
247
            self_.on_focus_lost();
3✔
248
            self_.on_cursor_state_changed();
3✔
249
            self_.on_cursor_position_changed();
3✔
250
        }
251
    }
5✔
252

253
    // ======================================================================
254
    // FOCUS_NEXT
255
    // ======================================================================
256
    void focus_next()
24✔
257
    {
258
        auto const &focus_next_component = [](auto const &comp) {
55✔
259
            comp->focus_next();
31✔
260
            return comp->has_focus();
31✔
261
        };
262

263
        focus_incremental(components_, focus_next_component);
24✔
264
    }
24✔
265

266
    // ======================================================================
267
    // FOCUS_PREVIOUS
268
    // ======================================================================
269
    void focus_previous()
22✔
270
    {
271
        auto const &focus_previous_component = [](auto const &comp) {
49✔
272
            comp->focus_previous();
27✔
273
            return comp->has_focus();
27✔
274
        };
275

276
        focus_incremental(
22✔
277
            components_ | std::views::reverse, focus_previous_component);
22✔
278
    }
22✔
279

280
    // ======================================================================
281
    // GET_CURSOR_STATE
282
    // ======================================================================
283
    [[nodiscard]] bool get_cursor_state() const
53✔
284
    {
285
        auto comp = find_first_focussed_component(components_);
53✔
286

287
        return comp == components_.end() ? false : (*comp)->get_cursor_state();
53✔
288
    }
289

290
    // ======================================================================
291
    // GET_CURSOR_POSITION
292
    // ======================================================================
293
    [[nodiscard]] terminalpp::point get_cursor_position() const
53✔
294
    {
295
        auto comp = find_first_focussed_component(components_);
53✔
296

297
        return comp == components_.end()
53✔
298
                 ? terminalpp::point{}
53✔
299
                 : (*comp)->get_position() + (*comp)->get_cursor_position();
106✔
300
    }
301

302
    // ======================================================================
303
    // SET_CURSOR_POSITION
304
    // ======================================================================
305
    void set_cursor_position(terminalpp::point const &position)
5✔
306
    {
307
        // Note: Setting the cursor position on a container doesn't really
308
        // make too much sense, but an implementation is required to fulfil the
309
        // component interface.  Our default implementation sets the relative
310
        // cursor position in the focussed component.
311
        auto comp = find_first_focussed_component(components_);
5✔
312

313
        if (comp != components_.end())
5✔
314
        {
315
            (*comp)->set_cursor_position(position - (*comp)->get_position());
4✔
316
        }
317
    }
5✔
318

319
    // ======================================================================
320
    // DRAW
321
    // ======================================================================
322
    void draw(
136✔
323
        render_surface &surface, terminalpp::rectangle const &region) const
324
    {
325
        for (auto const &comp : components_)
528✔
326
        {
327
            draw_component(comp, surface, region);
392✔
328
        }
329
    }
136✔
330

331
    // ======================================================================
332
    // EVENT
333
    // ======================================================================
334
    void event(std::any const &ev)
11✔
335
    {
336
        // We split incoming events into two types:
337
        // * Common events (e.g. keypressed, etc.) are passed on to the
338
        //   subcomponent with focus.
339
        // * Mouse events are passed on to the subcomponent at the location
340
        //   of the event, and the co-ordinates of the event are passed on
341
        //   relative to the subcomponent's location.
342
        if (auto const *mouse_event =
11✔
343
                std::any_cast<terminalpp::mouse::event>(&ev);
11✔
344
            mouse_event == nullptr)
345
        {
346
            handle_common_event(ev);
5✔
347
        }
348
        else
349
        {
350
            handle_mouse_event(*mouse_event);
6✔
351
        }
352
    }
11✔
353

354
    // ======================================================================
355
    // TO_JSON
356
    // ======================================================================
357
    [[nodiscard]] nlohmann::json to_json() const
44✔
358
    {
359
        nlohmann::json json = {
360
            {"type",            "container"                           },
361
            {"position",        detail::to_json(get_position())       },
88✔
362
            {"size",            detail::to_json(get_size())           },
88✔
363
            {"preferred_size",  detail::to_json(get_preferred_size()) },
88✔
NEW
364
            {"has_focus",       has_focus()                           },
×
NEW
365
            {"cursor_state",    get_cursor_state()                    },
×
366
            {"cursor_position", detail::to_json(get_cursor_position())},
88✔
367
            {"layout",          layout_->to_json()                    }
88✔
368
        };
1,100✔
369

370
        auto &subcomponents = json["subcomponents"];
88✔
371

372
        for (auto index = size_t{0}; index < components_.size(); ++index)
167✔
373
        {
374
            subcomponents[index] = components_[index]->to_json();
123✔
375
        }
376

377
        return json;
44✔
378
    }
1,232✔
379

380
private:
381
    // ======================================================================
382
    // LAYOUT_CONTAINER
383
    // ======================================================================
384
    void layout_container()
3,129✔
385
    {
386
        (*layout_)(components_, hints_, bounds_.size_);
3,129✔
387
    }
3,129✔
388

389
    // ======================================================================
390
    // FOCUS_INCREMENTAL
391
    // ======================================================================
392
    template <typename ForwardRange, typename Op>
393
    void focus_incremental(ForwardRange const &components, Op &&increment_op)
46✔
394
    {
395
        using std::cbegin;
396
        using std::cend;
397

398
        in_focus_operation_ = true;
46✔
399

400
        BOOST_SCOPE_EXIT_ALL(this)
92✔
401
        {
402
            in_focus_operation_ = false;
46✔
403
        };
404

405
        bool const had_focus = has_focus_;
46✔
406

407
        auto const &first_focussed_component =
46✔
408
            find_first_focussed_component(components);
24✔
409

410
        auto const &increment_from =
15✔
411
            first_focussed_component == cend(components)
46✔
412
                ? cbegin(components)
62✔
413
                : first_focussed_component;
414

415
        auto const &incrementally_focussed_component = increment_focus(
92✔
416
            std::ranges::subrange(increment_from, cend(components)),
92✔
417
            std::forward<Op>(increment_op));
418

419
        has_focus_ = incrementally_focussed_component != cend(components);
46✔
420

421
        // Announce a change in focus if that changed.
422
        if (had_focus != has_focus_)
46✔
423
        {
424
            if (has_focus_)
29✔
425
            {
426
                self_.on_focus_set();
25✔
427
            }
428
            else
429
            {
430
                self_.on_focus_lost();
4✔
431
            }
432

433
            self_.on_cursor_position_changed();
29✔
434
            self_.on_cursor_state_changed();
29✔
435
        }
436

437
        // If we had focus continuously, but the focussed subcomponent changed,
438
        // then we also want to announce cursor changes, since even though the
439
        // position and state of the cursor in the individual subcomponents
440
        // hasn't changed (and therefore they have no reason to send such a
441
        // signal), we know that the cursor may have moved about due to focus.
442
        if (had_focus && has_focus_
13✔
443
            && increment_from != incrementally_focussed_component)
59✔
444
        {
445
            self_.on_cursor_position_changed();
5✔
446
            self_.on_cursor_state_changed();
5✔
447
        }
448
    }
46✔
449

450
    // ======================================================================
451
    // DRAW_COMPONENT
452
    // ======================================================================
453
    void draw_component(
392✔
454
        std::shared_ptr<component> const &comp,
455
        render_surface &surface,
456
        terminalpp::rectangle const &region) const
457
    {
458
        auto const component_region =
459
            terminalpp::rectangle{comp->get_position(), comp->get_size()};
392✔
460

461
        if (auto draw_region = detail::intersection(component_region, region);
784✔
462
            draw_region)
392✔
463
        {
464
            // The draw region is currently relative to this container's
465
            // origin.  It should be relative to the child's origin.
466
            draw_region->origin_ -= component_region.origin_;
383✔
467

468
            // The canvas must have an offset applied to it so that the
469
            // inner component can pretend that it is being drawn with its
470
            // container being at position (0,0).
471
            surface.offset_by(
383✔
472
                {component_region.origin_.x_, component_region.origin_.y_});
383✔
473

474
            // Ensure that the offset is unapplied before exit of this
475
            // function.
476
            BOOST_SCOPE_EXIT_ALL(&surface, &component_region)
383✔
477
            {
478
                surface.offset_by(
383✔
479
                    {-component_region.origin_.x_,
383✔
480
                     -component_region.origin_.y_});
383✔
481
            };
383✔
482

483
            comp->draw(surface, draw_region.value());
383✔
484
        }
383✔
485
    }
392✔
486

487
    // ======================================================================
488
    // SUBCOMPONENT_REDRAW_HANDLER
489
    // ======================================================================
490
    void subcomponent_redraw_handler(
182✔
491
        std::weak_ptr<component> const &weak_subcomponent,
492
        std::vector<terminalpp::rectangle> regions)
493
    {
494
        auto subcomponent = weak_subcomponent.lock();
182✔
495

496
        if (subcomponent != nullptr)
182✔
497
        {
498
            // Each region is bound to the origin of the component in question.
499
            // It must be rebound to the origin of the container.  We do this
500
            // by offsetting the regions' origins by the origin of the
501
            // subcomponent within this container.
502
            auto origin = subcomponent->get_position();
182✔
503

504
            for (auto &rect : regions)
415✔
505
            {
506
                rect.origin_.x_ += origin.x_;
233✔
507
                rect.origin_.y_ += origin.y_;
233✔
508
            }
509

510
            // This new information must be passed up the component heirarchy.
511
            self_.on_redraw(regions);
182✔
512
        }
513
    }
182✔
514

515
    // ======================================================================
516
    // SUBCOMPONENT_FOCUS_SET_HANDLER
517
    // ======================================================================
518
    void subcomponent_focus_set_handler(
28✔
519
        std::weak_ptr<component> const &weak_comp)
520
    {
521
        if (!in_focus_operation_)
28✔
522
        {
523
            auto const &another_component_has_focus =
524
                [orig = weak_comp.lock()](auto const &comp) {
10✔
525
                    return comp != orig && comp->has_focus();
10✔
526
                };
6✔
527

528
            if (auto comp = std::ranges::find_if(
12✔
529
                    components_, another_component_has_focus);
6✔
530
                comp != components_.end())
6✔
531
            {
532
                in_focus_operation_ = true;
3✔
533

534
                BOOST_SCOPE_EXIT_ALL(this)
3✔
535
                {
536
                    in_focus_operation_ = false;
3✔
537
                };
3✔
538

539
                (*comp)->lose_focus();
3✔
540
            }
3✔
541
            else
542
            {
543
                has_focus_ = true;
3✔
544
                self_.on_focus_set();
3✔
545
            }
546

547
            self_.on_cursor_position_changed();
6✔
548
            self_.on_cursor_state_changed();
6✔
549
        }
6✔
550
    }
28✔
551

552
    // ======================================================================
553
    // SUBCOMPONENT_FOCUS_LOST_HANDLER
554
    // ======================================================================
555
    void subcomponent_focus_lost_handler()
11✔
556
    {
557
        if (!in_focus_operation_)
11✔
558
        {
559
            has_focus_ = false;
2✔
560
            self_.on_focus_lost();
2✔
561
        }
562
    }
11✔
563

564
    // ======================================================================
565
    // SUBCOMPONENT_CURSOR_STATE_CHANGE_HANDLER
566
    // ======================================================================
567
    void subcomponent_cursor_state_change_handler(
8✔
568
        std::weak_ptr<component> const &weak_subcomponent)
569
    {
570
        if (auto subcomponent = weak_subcomponent.lock();
8✔
571
            subcomponent && subcomponent->has_focus())
8✔
572
        {
573
            self_.on_cursor_state_changed();
6✔
574
        }
8✔
575
    }
8✔
576

577
    // ======================================================================
578
    // SUBCOMPONENT_CURSOR_POSITION_CHANGE_HANDLER
579
    // ======================================================================
580
    void subcomponent_cursor_position_change_handler(
9✔
581
        std::weak_ptr<component> const &weak_subcomponent)
582
    {
583
        if (auto subcomponent = weak_subcomponent.lock();
9✔
584
            subcomponent && subcomponent->has_focus())
9✔
585
        {
586
            self_.on_cursor_position_changed();
6✔
587
        }
9✔
588
    }
9✔
589

590
    // ======================================================================
591
    // HANDLE_COMMON_EVENT
592
    // ======================================================================
593
    void handle_common_event(std::any const &event)
5✔
594
    {
595
        if (auto comp = find_first_focussed_component(components_);
5✔
596
            comp != components_.end())
5✔
597
        {
598
            (*comp)->event(event);
4✔
599
        }
600
    }
5✔
601

602
    // ======================================================================
603
    // HANDLE_MOUSE_EVENT
604
    // ======================================================================
605
    void handle_mouse_event(terminalpp::mouse::event const &ev)
6✔
606
    {
607
        if (auto const &comp =
6✔
608
                find_component_at_point(components_, ev.position_);
6✔
609
            comp != components_.end())
6✔
610
        {
611
            auto const &position = (*comp)->get_position();
6✔
612

613
            (*comp)->event(
12✔
614
                terminalpp::mouse::event{ev.action_, ev.position_ - position});
12✔
615
        }
616
    }
6✔
617

618
    container &self_;
619
    terminalpp::rectangle bounds_;
620
    std::unique_ptr<munin::layout> layout_ = make_null_layout();
621
    std::vector<std::shared_ptr<component>> components_;
622
    std::vector<std::any> hints_;
623
    std::vector<component_connections> component_connections_;
624
    bool has_focus_ = false;
625
    bool in_focus_operation_ = false;
626
};
627

628
// ==========================================================================
629
// CONSTRUCTOR
630
// ==========================================================================
631
container::container() : pimpl_(std::make_unique<impl>(*this))
500✔
632
{
633
}
500✔
634

635
// ==========================================================================
636
// DESTRUCTOR
637
// ==========================================================================
638
container::~container() = default;
500✔
639

640
// ==========================================================================
641
// SET_LAYOUT
642
// ==========================================================================
643
void container::set_layout(std::unique_ptr<munin::layout> &&lyt)
393✔
644
{
645
    pimpl_->set_layout(std::move(lyt));
393✔
646
}
393✔
647

648
// ==========================================================================
649
// ADD_COMPONENT
650
// ==========================================================================
651
void container::add_component(
1,177✔
652
    std::shared_ptr<component> const &comp, std::any const &layout_hint)
653
{
654
    pimpl_->add_component(comp, layout_hint);
1,177✔
655
}
1,177✔
656

657
// ==========================================================================
658
// REMOVE_COMPONENT
659
// ==========================================================================
660
void container::remove_component(std::shared_ptr<component> const &comp)
3✔
661
{
662
    pimpl_->remove_component(comp);
3✔
663
}
3✔
664

665
// ==========================================================================
666
// DO_SET_POSITION
667
// ==========================================================================
668
void container::do_set_position(terminalpp::point const &position)
1,477✔
669
{
670
    pimpl_->set_position(position);
1,477✔
671
}
1,477✔
672

673
// ==========================================================================
674
// DO_GET_POSITION
675
// ==========================================================================
676
terminalpp::point container::do_get_position() const
228✔
677
{
678
    return pimpl_->get_position();
228✔
679
}
680

681
// ==========================================================================
682
// DO_SET_SIZE
683
// ==========================================================================
684
void container::do_set_size(terminalpp::extent const &size)
1,556✔
685
{
686
    pimpl_->set_size(size);
1,556✔
687
}
1,556✔
688

689
// ==========================================================================
690
// DO_GET_SIZE
691
// ==========================================================================
692
terminalpp::extent container::do_get_size() const
212✔
693
{
694
    return pimpl_->get_size();
212✔
695
}
696

697
// ==========================================================================
698
// DO_GET_PREFERRED_SIZE
699
// ==========================================================================
700
terminalpp::extent container::do_get_preferred_size() const
1,305✔
701
{
702
    return pimpl_->get_preferred_size();
1,305✔
703
}
704

705
// ==========================================================================
706
// DO_HAS_FOCUS
707
// ==========================================================================
708
bool container::do_has_focus() const
159✔
709
{
710
    return pimpl_->has_focus();
159✔
711
}
712

713
// ==========================================================================
714
// DO_SET_FOCUS
715
// ==========================================================================
716
void container::do_set_focus()
58✔
717
{
718
    pimpl_->set_focus();
58✔
719
}
58✔
720

721
// ==========================================================================
722
// DO_LOSE_FOCUS
723
// ==========================================================================
724
void container::do_lose_focus()
5✔
725
{
726
    pimpl_->lose_focus();
5✔
727
}
5✔
728

729
// ==========================================================================
730
// DO_FOCUS_NEXT
731
// ==========================================================================
732
void container::do_focus_next()
24✔
733
{
734
    pimpl_->focus_next();
24✔
735
}
24✔
736

737
// ==========================================================================
738
// DO_FOCUS_PREVIOUS
739
// ==========================================================================
740
void container::do_focus_previous()
22✔
741
{
742
    pimpl_->focus_previous();
22✔
743
}
22✔
744

745
// ==========================================================================
746
// DO_GET_CURSOR_STATE
747
// ==========================================================================
748
bool container::do_get_cursor_state() const
9✔
749
{
750
    return pimpl_->get_cursor_state();
9✔
751
}
752

753
// ==========================================================================
754
// DO_GET_CURSOR_POSITION
755
// ==========================================================================
756
terminalpp::point container::do_get_cursor_position() const
9✔
757
{
758
    return pimpl_->get_cursor_position();
9✔
759
}
760

761
// ==========================================================================
762
// DO_SET_CURSOR_POSITION
763
// ==========================================================================
764
void container::do_set_cursor_position(terminalpp::point const &position)
5✔
765
{
766
    pimpl_->set_cursor_position(position);
5✔
767
}
5✔
768

769
// ==========================================================================
770
// DO_DRAW
771
// ==========================================================================
772
void container::do_draw(
136✔
773
    render_surface &surface, terminalpp::rectangle const &region) const
774
{
775
    pimpl_->draw(surface, region);
136✔
776
}
136✔
777

778
// ==========================================================================
779
// DO_EVENT
780
// ==========================================================================
781
void container::do_event(std::any const &event)
11✔
782
{
783
    pimpl_->event(event);
11✔
784
}
11✔
785

786
// ==========================================================================
787
// DO_TO_JSON
788
// ==========================================================================
789
nlohmann::json container::do_to_json() const
44✔
790
{
791
    return pimpl_->to_json();
44✔
792
}
793

794
// ==========================================================================
795
// MAKE_CONTAINER
796
// ==========================================================================
797
std::shared_ptr<container> make_container()
207✔
798
{
799
    return std::make_shared<container>();
207✔
800
}
801

802
}  // namespace munin
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc