| 1 | /* |
|---|---|
| 2 | src/colorpicker.cpp -- push button with a popup to tweak a color value |
| 3 | |
| 4 | This widget was contributed by Christian Schueller. |
| 5 | |
| 6 | NanoGUI was developed by Wenzel Jakob <wenzel.jakob@epfl.ch>. |
| 7 | The widget drawing code is based on the NanoVG demo application |
| 8 | by Mikko Mononen. |
| 9 | |
| 10 | All rights reserved. Use of this source code is governed by a |
| 11 | BSD-style license that can be found in the LICENSE.txt file. |
| 12 | */ |
| 13 | |
| 14 | #include <nanogui/colorpicker.h> |
| 15 | #include <nanogui/layout.h> |
| 16 | #include <nanogui/colorwheel.h> |
| 17 | |
| 18 | NAMESPACE_BEGIN(nanogui) |
| 19 | |
| 20 | ColorPicker::ColorPicker(Widget *parent, const Color& color) : PopupButton(parent, "") { |
| 21 | setBackgroundColor(color); |
| 22 | Popup *popup = this->popup(); |
| 23 | popup->setLayout(new GroupLayout()); |
| 24 | |
| 25 | // initialize callback to do nothing; this is for users to hook into |
| 26 | // receiving a new color value |
| 27 | mCallback = [](const Color &) {}; |
| 28 | mFinalCallback = [](const Color &) {}; |
| 29 | |
| 30 | // set the color wheel to the specified color |
| 31 | mColorWheel = new ColorWheel(popup, color); |
| 32 | |
| 33 | // set the pick button to the specified color |
| 34 | mPickButton = new Button(popup, "Pick"); |
| 35 | mPickButton->setBackgroundColor(color); |
| 36 | mPickButton->setTextColor(color.contrastingColor()); |
| 37 | mPickButton->setFixedSize(Vector2i(100, 20)); |
| 38 | |
| 39 | // set the reset button to the specified color |
| 40 | mResetButton = new Button(popup, "Reset"); |
| 41 | mResetButton->setBackgroundColor(color); |
| 42 | mResetButton->setTextColor(color.contrastingColor()); |
| 43 | mResetButton->setFixedSize(Vector2i(100, 20)); |
| 44 | |
| 45 | PopupButton::setChangeCallback([&](bool) { |
| 46 | if (this->mPickButton->pushed()) { |
| 47 | setColor(backgroundColor()); |
| 48 | mFinalCallback(backgroundColor()); |
| 49 | } |
| 50 | }); |
| 51 | |
| 52 | mColorWheel->setCallback([&](const Color &value) { |
| 53 | mPickButton->setBackgroundColor(value); |
| 54 | mPickButton->setTextColor(value.contrastingColor()); |
| 55 | mCallback(value); |
| 56 | }); |
| 57 | |
| 58 | mPickButton->setCallback([this]() { |
| 59 | if (mPushed) { |
| 60 | Color value = mColorWheel->color(); |
| 61 | setPushed(false); |
| 62 | setColor(value); |
| 63 | mFinalCallback(value); |
| 64 | } |
| 65 | }); |
| 66 | |
| 67 | mResetButton->setCallback([this]() { |
| 68 | Color bg = this->mResetButton->backgroundColor(); |
| 69 | Color fg = this->mResetButton->textColor(); |
| 70 | |
| 71 | mColorWheel->setColor(bg); |
| 72 | mPickButton->setBackgroundColor(bg); |
| 73 | mPickButton->setTextColor(fg); |
| 74 | |
| 75 | mCallback(bg); |
| 76 | mFinalCallback(bg); |
| 77 | }); |
| 78 | } |
| 79 | |
| 80 | Color ColorPicker::color() const { |
| 81 | return backgroundColor(); |
| 82 | } |
| 83 | |
| 84 | void ColorPicker::setColor(const Color& color) { |
| 85 | /* Ignore setColor() calls when the user is currently editing */ |
| 86 | if (!mPushed) { |
| 87 | Color fg = color.contrastingColor(); |
| 88 | setBackgroundColor(color); |
| 89 | setTextColor(fg); |
| 90 | mColorWheel->setColor(color); |
| 91 | |
| 92 | mPickButton->setBackgroundColor(color); |
| 93 | mPickButton->setTextColor(fg); |
| 94 | |
| 95 | mResetButton->setBackgroundColor(color); |
| 96 | mResetButton->setTextColor(fg); |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | NAMESPACE_END(nanogui) |
| 101 |