diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index e3b7b64d3..359ec6156 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -292,6 +292,7 @@ add_library(app-lib ui/color_button.cpp ui/color_selector.cpp ui/color_sliders.cpp + ui/color_spectrum.cpp ui/configure_timeline_popup.cpp ui/context_bar.cpp ui/devconsole_view.cpp diff --git a/src/app/ui/color_bar.cpp b/src/app/ui/color_bar.cpp index 5562a7fd5..39da5139f 100644 --- a/src/app/ui/color_bar.cpp +++ b/src/app/ui/color_bar.cpp @@ -23,6 +23,7 @@ #include "app/modules/gui.h" #include "app/pref/preferences.h" #include "app/transaction.h" +#include "app/ui/color_spectrum.h" #include "app/ui/skin/skin_theme.h" #include "app/ui/status_bar.h" #include "app/ui_context.h" @@ -35,6 +36,7 @@ #include "ui/graphics.h" #include "ui/menu.h" #include "ui/paint_event.h" +#include "ui/splitter.h" #include "ui/system.h" #include @@ -106,8 +108,15 @@ ColorBar::ColorBar(int align) m_remapButton.setVisible(false); + ColorSpectrum* spectrum = new ColorSpectrum; + Splitter* splitter = new Splitter(Splitter::ByPercentage, JI_VERTICAL); + splitter->setPosition(80); + splitter->setExpansive(true); + splitter->addChild(&m_scrollableView); + splitter->addChild(spectrum); + addChild(&m_paletteButton); - addChild(&m_scrollableView); + addChild(splitter); addChild(&m_remapButton); addChild(&m_fgColor); addChild(&m_bgColor); @@ -115,6 +124,7 @@ ColorBar::ColorBar(int align) m_remapButton.Click.connect(Bind(&ColorBar::onRemapButtonClick, this)); m_fgColor.Change.connect(&ColorBar::onFgColorButtonChange, this); m_bgColor.Change.connect(&ColorBar::onBgColorButtonChange, this); + spectrum->ColorChange.connect(&ColorBar::onPickSpectrum, this); // Set background color reading its value from the configuration. setBgColor(get_config_color("ColorBar", "BG", getBgColor())); @@ -303,6 +313,18 @@ void ColorBar::onColorButtonChange(const app::Color& color) m_paletteView.selectColor(color.getIndex()); } +void ColorBar::onPickSpectrum(const app::Color& color, ui::MouseButtons buttons) +{ + m_lock = true; + + if ((buttons & kButtonRight) == kButtonRight) + setBgColor(color); + else + setFgColor(color); + + m_lock = false; +} + void ColorBar::destroyRemap() { if (!m_remap) diff --git a/src/app/ui/color_bar.h b/src/app/ui/color_bar.h index 2c3263bd3..73dd09d7c 100644 --- a/src/app/ui/color_bar.h +++ b/src/app/ui/color_bar.h @@ -65,6 +65,7 @@ namespace app { void onFgColorButtonChange(const app::Color& color); void onBgColorButtonChange(const app::Color& color); void onColorButtonChange(const app::Color& color); + void onPickSpectrum(const app::Color& color, ui::MouseButtons buttons); // PaletteViewDelegate impl void onPaletteViewIndexChange(int index, ui::MouseButtons buttons) override; diff --git a/src/app/ui/color_spectrum.cpp b/src/app/ui/color_spectrum.cpp new file mode 100644 index 000000000..4765f1592 --- /dev/null +++ b/src/app/ui/color_spectrum.cpp @@ -0,0 +1,165 @@ +// Aseprite +// Copyright (C) 2001-2015 David Capello +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "app/ui/color_spectrum.h" + +#include "app/color_utils.h" +#include "app/ui/skin/skin_theme.h" +#include "app/ui/status_bar.h" +#include "ui/graphics.h" +#include "ui/message.h" +#include "ui/paint_event.h" +#include "ui/preferred_size_event.h" +#include "ui/resize_event.h" +#include "ui/system.h" + +namespace app { + +using namespace app::skin; +using namespace gfx; +using namespace ui; + +ColorSpectrum::ColorSpectrum() + : Widget(kGenericWidget) +{ + setAlign(JI_HORIZONTAL); +} + +ColorSpectrum::~ColorSpectrum() +{ +} + +app::Color ColorSpectrum::pickColor(const gfx::Point& pos) const +{ + gfx::Rect rc = getBounds().shrink(3*ui::guiscale()); + if (rc.isEmpty() || !rc.contains(pos)) + return app::Color::fromMask(); + + int vmid = (getAlign() & JI_HORIZONTAL ? rc.h/2 : rc.w/2); + vmid = MAX(1, vmid); + + int u, v, umax; + if (getAlign() & JI_HORIZONTAL) { + u = pos.x - rc.x; + v = pos.y - rc.y; + umax = MAX(1, rc.w-1); + } + else { + u = pos.y - rc.y; + v = pos.x - rc.x; + umax = MAX(1, rc.h-1); + } + + int hue = 360 * u / umax; + int sat = (v < vmid ? 100 * v / vmid : 100); + int val = (v < vmid ? 100 : 100-(100 * (v-vmid) / vmid)); + + return app::Color::fromHsv( + MID(0, hue, 360), + MID(0, sat, 100), + MID(0, val, 100)); +} + +void ColorSpectrum::onPreferredSize(PreferredSizeEvent& ev) +{ + ev.setPreferredSize(gfx::Size(32*ui::guiscale(), 32*ui::guiscale())); +} + +void ColorSpectrum::onResize(ui::ResizeEvent& ev) +{ + Widget::onResize(ev); +} + +void ColorSpectrum::onPaint(ui::PaintEvent& ev) +{ + ui::Graphics* g = ev.getGraphics(); + SkinTheme* theme = static_cast(getTheme()); + + theme->draw_bounds_nw(g, getClientBounds(), + PART_EDITOR_NORMAL_NW, getBgColor()); + + gfx::Rect rc = getClientBounds().shrink(3*ui::guiscale()); + if (rc.isEmpty()) + return; + + int vmid = (getAlign() & JI_HORIZONTAL ? rc.h/2 : rc.w/2); + vmid = MAX(1, vmid); + + for (int y=0; yputPixel(color, rc.x+x, rc.y+y); + } + } +} + +bool ColorSpectrum::onProcessMessage(ui::Message* msg) +{ + switch (msg->type()) { + + case kMouseDownMessage: + captureMouse(); + // Continue... + + case kMouseMoveMessage: { + MouseMessage* mouseMsg = static_cast(msg); + + app::Color color = pickColor(mouseMsg->position()); + if (color != app::Color::fromMask()) { + StatusBar::instance()->showColor(0, "", color, 255); + if (hasCapture()) + ColorChange(color, mouseMsg->buttons()); + } + break; + } + + case kMouseUpMessage: + if (hasCapture()) { + releaseMouse(); + } + return true; + + case kSetCursorMessage: { + MouseMessage* mouseMsg = static_cast(msg); + if (getBounds().shrink(3*ui::guiscale()).contains(mouseMsg->position())) { + ui::set_mouse_cursor(kEyedropperCursor); + return true; + } + break; + } + + } + + return Widget::onProcessMessage(msg); +} + +} // namespace app diff --git a/src/app/ui/color_spectrum.h b/src/app/ui/color_spectrum.h new file mode 100644 index 000000000..a8bd8941f --- /dev/null +++ b/src/app/ui/color_spectrum.h @@ -0,0 +1,38 @@ +// Aseprite +// Copyright (C) 2001-2015 David Capello +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. + +#ifndef APP_UI_COLOR_SPECTRUM_H_INCLUDED +#define APP_UI_COLOR_SPECTRUM_H_INCLUDED +#pragma once + +#include "app/color.h" +#include "base/signal.h" +#include "ui/mouse_buttons.h" +#include "ui/widget.h" + +namespace app { + + class ColorSpectrum : public ui::Widget { + public: + ColorSpectrum(); + ~ColorSpectrum(); + + app::Color pickColor(const gfx::Point& pos) const; + + // Signals + Signal2 ColorChange; + + protected: + void onPreferredSize(ui::PreferredSizeEvent& ev) override; + void onResize(ui::ResizeEvent& ev) override; + void onPaint(ui::PaintEvent& ev) override; + bool onProcessMessage(ui::Message* msg) override; + }; + +} // namespace app + +#endif