This repository has been archived by the owner on Nov 9, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathpopup.cpp
103 lines (82 loc) · 2.9 KB
/
popup.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
src/popup.cpp -- Simple popup widget which is attached to another given
window (can be nested)
NanoGUI was developed by Wenzel Jakob <wenzel.jakob@epfl.ch>.
The widget drawing code is based on the NanoVG demo application
by Mikko Mononen.
All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE.txt file.
*/
#include <nanogui/popup.h>
#include <nanogui/theme.h>
#include <nanogui/opengl.h>
#include <nanogui/serializer/core.h>
NAMESPACE_BEGIN(nanogui)
Popup::Popup(Widget *parent, Window *parentWindow)
: Window(parent, ""), mParentWindow(parentWindow),
mAnchorPos(Vector2i::Zero()), mAnchorHeight(30), mSide(Side::Right) {
}
void Popup::performLayout(NVGcontext *ctx) {
if (mLayout || mChildren.size() != 1) {
Widget::performLayout(ctx);
} else {
mChildren[0]->setPosition(Vector2i::Zero());
mChildren[0]->setSize(mSize);
mChildren[0]->performLayout(ctx);
}
if (mSide == Side::Left)
mAnchorPos[0] -= size()[0];
}
void Popup::refreshRelativePlacement() {
mParentWindow->refreshRelativePlacement();
mVisible &= mParentWindow->visibleRecursive();
mPos = mParentWindow->position() + mAnchorPos - Vector2i(0, mAnchorHeight);
}
void Popup::draw(NVGcontext* ctx) {
refreshRelativePlacement();
if (!mVisible)
return;
int ds = mTheme->mWindowDropShadowSize, cr = mTheme->mWindowCornerRadius;
nvgSave(ctx);
nvgResetScissor(ctx);
/* Draw a drop shadow */
NVGpaint shadowPaint = nvgBoxGradient(
ctx, mPos.x(), mPos.y(), mSize.x(), mSize.y(), cr*2, ds*2,
mTheme->mDropShadow, mTheme->mTransparent);
nvgBeginPath(ctx);
nvgRect(ctx, mPos.x()-ds,mPos.y()-ds, mSize.x()+2*ds, mSize.y()+2*ds);
nvgRoundedRect(ctx, mPos.x(), mPos.y(), mSize.x(), mSize.y(), cr);
nvgPathWinding(ctx, NVG_HOLE);
nvgFillPaint(ctx, shadowPaint);
nvgFill(ctx);
/* Draw window */
nvgBeginPath(ctx);
nvgRoundedRect(ctx, mPos.x(), mPos.y(), mSize.x(), mSize.y(), cr);
Vector2i base = mPos + Vector2i(0, mAnchorHeight);
int sign = -1;
if (mSide == Side::Left) {
base.x() += mSize.x();
sign = 1;
}
nvgMoveTo(ctx, base.x() + 15*sign, base.y());
nvgLineTo(ctx, base.x() - 1*sign, base.y() - 15);
nvgLineTo(ctx, base.x() - 1*sign, base.y() + 15);
nvgFillColor(ctx, mTheme->mWindowPopup);
nvgFill(ctx);
nvgRestore(ctx);
Widget::draw(ctx);
}
void Popup::save(Serializer &s) const {
Window::save(s);
s.set("anchorPos", mAnchorPos);
s.set("anchorHeight", mAnchorHeight);
s.set("side", mSide);
}
bool Popup::load(Serializer &s) {
if (!Window::load(s)) return false;
if (!s.get("anchorPos", mAnchorPos)) return false;
if (!s.get("anchorHeight", mAnchorHeight)) return false;
if (!s.get("side", mSide)) return false;
return true;
}
NAMESPACE_END(nanogui)