KDDockWidgets API Documentation 2.1
Loading...
Searching...
No Matches
flutter/views/View.cpp
Go to the documentation of this file.
1/*
2 This file is part of KDDockWidgets.
3
4 SPDX-FileCopyrightText: 2020 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5 Author: SĂ©rgio Martins <sergio.martins@kdab.com>
6
7 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
8
9 Contact KDAB at <info@kdab.com> for commercial licensing options.
10*/
11
12#include "View.h"
13#include "Platform.h"
14#include "core/Logging_p.h"
15#include "core/View_p.h"
16#include "core/layouting/Item_p.h"
17#include "../Window_p.h"
18#include "ViewWrapper_p.h"
19
20#include <utility>
21
22using namespace KDDockWidgets;
23using namespace KDDockWidgets::flutter;
24
27 : Core::View(controller, type)
28{
29 m_minSize = Core::Item::hardcodedMinimumSize;
30 m_maxSize = Core::Item::hardcodedMaximumSize;
31 m_geometry = Rect(0, 0, 400, 400);
32
33 setParent(parent);
34 m_inCtor = false;
35}
36
38{
39 m_inDtor = true;
40 if (hasFocus())
42
43 if (m_parentView) {
44 setParent(nullptr);
45 }
46}
47
48void View::setGeometry(Rect geo)
49{
50 if (geo != m_geometry) {
51 m_geometry = geo;
53 }
54}
55
56void View::move(int x, int y)
57{
58 if (m_geometry.topLeft() != Point(x, y)) {
59 m_geometry.moveTopLeft(Point(x, y));
61 }
62}
63
65{
66 // FLUTTER_TODO: Ask flutter if we should close
67
68 CloseEvent ev;
69 d->requestClose(&ev);
70
71 if (ev.isAccepted()) {
72 setVisible(false);
73 return true;
74 }
75
76 return false;
77}
78
79bool View::isVisible() const
80{
81 // No value means false
82 if (!m_visible.value_or(false))
83 return false;
84
85 // Parents need to be visible as well
86 return !m_parentView || m_parentView->isVisible();
87}
88
89void View::setVisible(bool is)
90{
91 if (!m_visible.has_value() || is != m_visible.value()) {
92 m_visible = is;
93
94 if (m_visible) {
95 // Mimic QWidgets: Set children visible, unless they were explicitly hidden
96 for (auto child : std::as_const(m_childViews)) {
97 if (!child->isExplicitlyHidden()) {
98 child->setVisible(true);
99 }
100 }
101 }
102
103 if (m_parentView) {
104 m_parentView->onChildVisibilityChanged(this);
105 }
106 }
107}
108
110{
111 return m_visible.has_value() && !m_visible.value();
112}
113
114void View::setSize(int w, int h)
115{
116 m_geometry.setSize(Size(w, h));
118}
119
120std::shared_ptr<Core::View> View::rootView() const
121{
122 if (m_parentView)
123 return m_parentView->rootView();
124
125 return const_cast<View *>(this)->asWrapper();
126}
127
131
133{
134 return false;
135}
136
138{
139}
140
142{
143 return {};
144}
145
146Size View::minSize() const
147{
148 return m_minSize;
149}
150
152{
153 return m_maxSize;
154}
155
156Rect View::geometry() const
157{
158 return m_geometry;
159}
160
162{
163 return m_geometry;
164}
165
167{
168}
169
171{
172 s = s.boundedTo(Core::Item::hardcodedMaximumSize);
173 if (s != m_maxSize) {
174 m_maxSize = s;
175 d->layoutInvalidated.emit();
176 }
177}
178
179void View::setWidth(int w)
180{
181 if (m_geometry.width() != w) {
182 m_geometry.setWidth(w);
184 }
185}
186
188{
189 if (m_geometry.height() != h) {
190 m_geometry.setHeight(h);
192 }
193}
194
196{
197 // FLUTTER_TODO Support fixed width
198 setWidth(w);
199}
200
202{
203 // FLUTTER_TODO Support fixed height
204 setHeight(h);
205}
206
208{
209 setVisible(true);
210}
211
213{
214 setVisible(false);
215}
216
218{
219}
220
222{
223}
224
226{
227 if (parent == m_parentView)
228 return;
229
230 auto oldParent = m_parentView;
231 m_parentView = static_cast<View *>(parent);
232
233 if (oldParent) {
234 if (!oldParent->inDtor())
235 oldParent->onChildRemoved(this);
236 oldParent->m_childViews.erase(std::remove_if(oldParent->m_childViews.begin(), oldParent->m_childViews.end(),
237 [this](Core::View *v) {
238 return v->equals(this);
239 }),
240 oldParent->m_childViews.end());
241 }
242
243 if (m_parentView) {
244 if (!m_inCtor) {
245 // When in ctor there's no ViewMixin yet. TODO: Check if we need to improve this
246
247 // Tell dart there's a new child
248 m_parentView->onChildAdded(this);
249 }
250
251 // Track it in C++
252 m_parentView->m_childViews.append(this);
253
254 if (!m_parentView->isVisible() && isExplicitlyHidden()) {
255 // Mimic QtWidget. Parenting removes the explicit hidden attribute if the parent is not visible
256 m_visible = std::nullopt;
257 }
258 } else {
259 if (!m_inDtor) {
260 // Mimic Qt and hide when unparenting
261 setVisible(false);
262 }
263 }
264}
265
267{
268 raise();
270}
271
273{
274}
275
277{
278 if (isRootView()) {
279 raiseWindow(this);
280 } else {
281 m_parentView->raiseChild(this);
282 }
283}
284
286{
287 return m_parentView == nullptr;
288}
289
290Point View::mapToGlobal(Point) const
291{
292 KDDW_WARN("View::mapToGlobal: Implemented in dart");
293 return {};
294}
295
296Point View::mapFromGlobal(Point) const
297{
298 KDDW_WARN("View::mapFromGlobal: Implemented in dart");
299 return {};
300}
301
302Point View::mapTo(Core::View *other, Point pt) const
303{
304 if (!other)
305 return {};
306
307 if (other->equals(this))
308 return pt;
309
310 const Point global = mapToGlobal(pt);
311 return other->mapFromGlobal(global);
312}
313
315{
316}
317
319{
320}
321
322void View::setWindowIcon(const Icon &)
323{
324}
325
327{
328 return false;
329}
330
332{
333}
334
336{
337}
338
340{
341}
342
344{
345 return {};
346}
347
349{
350 return {};
351}
352
353std::shared_ptr<Core::Window> View::window() const
354{
355 auto window = new flutter::Window(rootView());
356
357 return std::shared_ptr<Core::Window>(window);
358}
359
360std::shared_ptr<Core::View> View::childViewAt(Point localPos) const
361{
362 if (!isMounted())
363 return nullptr;
364
365 const Point globalPt = mapToGlobal(localPos);
366
367 for (auto child : m_childViews) {
368 // Needs to be mounted (i.e. being shown by flutter's render tree, otherwise there's no geometry)
369 if (!child->isVisible() || !static_cast<flutter::View *>(child)->isMounted())
370 continue;
371
372 if (auto result = child->childViewAt(child->mapFromGlobal(globalPt))) {
373 return result;
374 }
375
376 // We favored depth first, but now it's our turn
377 if (rect().contains(localPos))
378 return const_cast<flutter::View *>(this)->asWrapper();
379 }
380
381 return nullptr;
382}
383
384std::shared_ptr<Core::View> View::parentView() const
385{
386 if (m_parentView)
387 return m_parentView->asWrapper();
388
389 return {};
390}
391
392std::shared_ptr<Core::View> View::asWrapper()
393{
394 return ViewWrapper::create(this);
395}
396
397void View::setViewName(const QString &name)
398{
399 m_name = name;
400}
401
403{
404}
405
407{
408}
409
411{
412}
413
418
419bool View::hasFocus() const
420{
421 auto focusedView = Platform::platformFlutter()->focusedView();
422 return focusedView && focusedView->equals(this);
423}
424
426{
427 return {};
428}
429
433
435{
436 return m_name;
437}
438
440{
441 s = s.expandedTo(Core::Item::hardcodedMinimumSize);
442 if (s != m_minSize) {
443 m_minSize = s;
444 d->layoutInvalidated.emit();
445 }
446}
447
449{
450}
451
455
457{
458}
459
461{
463 children.reserve(m_childViews.size());
464 for (auto child : m_childViews)
465 children.append(ViewWrapper::create(static_cast<flutter::View *>(child)));
466
467 return children;
468}
469
471{
472}
473
475{
476 return this;
477}
478
480{
481 setSize(w, h);
482 return Core::View::onResize(w, h);
483}
484
486{
487 KDDW_UNUSED(childView);
488 dumpDebug();
489 KDDW_ERROR("Derived class should be called instead");
490}
491
493{
494 KDDW_UNUSED(childView);
495 dumpDebug();
496 KDDW_ERROR("Derived class should be called instead");
497}
498
500{
501 KDDW_UNUSED(childView);
502 dumpDebug();
503 KDDW_ERROR("Derived class should be called instead");
504}
505
507{
508 dumpDebug();
509 KDDW_ERROR("Derived class should be called instead");
510}
511
513{
514 dumpDebug();
515 KDDW_ERROR("Derived class should be called instead");
516}
517
519{
520 dumpDebug();
521 KDDW_ERROR("Derived class should be called instead");
522}
523
524void View::onMouseEvent(Event::Type eventType, Point localPos, Point globalPos, bool leftIsPressed)
525{
527 buttons.setFlag(Qt::LeftButton, leftIsPressed);
529
530 if (eventType == Event::MouseMove) {
531 // Poor man's QCursor::pos()
533 }
534
535 auto me = new MouseEvent(eventType, localPos, globalPos, globalPos, buttons, buttons, modifiers);
536
537 if (!deliverViewEventToFilters(me)) {
538 // filters allowed the event to propagate, give it to the view.
539 // only pressed handled, there's no use case for the others
540 if (eventType == Event::Type::MouseButtonPress)
541 onMousePress(me);
542 }
543
544 // FLUTTER_TODO: Who deletes the event ?
545}
546
547bool View::isMounted() const
548{
549 KDDW_WARN("View::isMounted: Implemented in dart instead");
550 return false;
551}
552
553
555{
556 KDDW_WARN("View::onRebuildRequested: Implemented in dart instead");
557}
#define KDDW_UNUSED(name)
bool equals(const View *other) const
Returns whether this view represents the same GUI element as the other.
virtual bool onResize(int h, int w)
virtual Point mapFromGlobal(Point) const =0
void dumpDebug()
Prints some debug to stderr.
virtual bool is(ViewType) const
Returns whether the view is of the specified type Virtual so it can be overridden by ViewWrapper....
bool deliverViewEventToFilters(Event *e)
Delivers mouse events and such to event filters.
std::shared_ptr< Core::View > focusedView() const override
Returns the focused view, if any.
void setFocusedView(std::shared_ptr< Core::View >)
Qt::FocusPolicy focusPolicy() const override
virtual void raiseChild(Core::View *childView)
bool isExplicitlyHidden() const override
Qt::WindowFlags flags() const override
std::shared_ptr< Core::View > rootView() const override
Returns the top-level gui element which this view is inside It's the root view of the window.
Point mapFromGlobal(Point globalPt) const override
void setWindowIcon(const Icon &icon) override
bool hasAttribute(Qt::WidgetAttribute attr) const override
bool onFlutterWidgetResized(int w, int h)
bool isActiveWindow() const override
std::shared_ptr< Core::View > childViewAt(Point p) const override
Point mapToGlobal(Point localPt) const override
void render(QPainter *) override
void setMaximumSize(Size sz) override
Core::HANDLE handle() const override
Returns a handle for the GUI element This value only makes sense to the frontend. For example,...
virtual void onChildAdded(Core::View *childView)
void setParent(Core::View *parent) override
Vector< std::shared_ptr< Core::View > > childViews() const override
@Returns a list of child views
void setMouseTracking(bool enable) override
void move(int x, int y) override
void setVisible(bool visible) override
QString viewName() const override
void setFlag(Qt::WindowType f, bool on=true) override
void setGeometry(Rect geometry) override
virtual void onChildRemoved(Core::View *childView)
View(Core::Controller *controller, Core::ViewType type, Core::View *, Qt::WindowFlags windowFlags={})
virtual void onMousePress(MouseEvent *)
View can override if it's interested in events which the event filter rejected.
void setMinimumSize(Size sz) override
virtual void raiseWindow(Core::View *rootView)
std::shared_ptr< Core::View > parentView() const override
Returns the gui element's parent. Like QWidget::parentWidget()
void enableAttribute(Qt::WidgetAttribute attr, bool enable=true) override
Rect normalGeometry() const override
void setFocusPolicy(Qt::FocusPolicy policy) override
void setCursor(Qt::CursorShape shape) override
void setFocus(Qt::FocusReason reason) override
std::shared_ptr< Core::Window > window() const override
Returns the window this view is inside For the Qt frontend, this wraps a QWindow. Like QWidget::windo...
void onMouseEvent(Event::Type eventType, Point localPos, Point globalPos, bool leftIsPressed)
Called by flutter when a mouse event is received.
void setSize(int w, int h) override
void setViewName(const QString &name) override
Equivalent to Qt's QObject::objectName()
virtual void onRebuildRequested()
Implemented in Dart.
void setWindowTitle(const QString &title) override
void setZOrder(int z) override
Sets the z order Not supported on all platforms and only relevant for MDI mode.
Point mapTo(Core::View *parent, Point pos) const override
virtual void onChildVisibilityChanged(Core::View *childView)
std::shared_ptr< Core::View > asWrapper() override
Returns this view, but as a wrapper.
void setWindowOpacity(double v) override
ViewType
Each View type also has a specific Controller associated with, except for ViewType::None.
Definition Controller.h:26
const void * HANDLE
Definition core/View.h:28
Class to abstract QAction, so code still works with QtQuick and Flutter.
CursorShape
FocusPolicy
FocusReason
typedef KeyboardModifiers
typedef MouseButtons
WidgetAttribute
typedef WindowFlags

© Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
KDDockWidgets
Advanced Dock Widget Framework for Qt
https://www.kdab.com/development-resources/qt-tools/kddockwidgets/
Generated by doxygen 1.9.8