2006-01-16 22:02:54 +01:00
|
|
|
// Copyright (c) 2005, Niels Martin Hansen
|
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without
|
|
|
|
// modification, are permitted provided that the following conditions are met:
|
|
|
|
//
|
|
|
|
// * Redistributions of source code must retain the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer.
|
|
|
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
|
|
// and/or other materials provided with the distribution.
|
|
|
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
|
|
|
// may be used to endorse or promote products derived from this software
|
|
|
|
// without specific prior written permission.
|
|
|
|
//
|
|
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// Aegisub Project http://www.aegisub.org/
|
2006-01-16 22:02:54 +01:00
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// $Id$
|
|
|
|
|
|
|
|
/// @file dialog_colorpicker.cpp
|
|
|
|
/// @brief Custom colour-selection dialogue box
|
|
|
|
/// @ingroup tools_ui
|
|
|
|
///
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2009-01-04 07:31:48 +01:00
|
|
|
#include "config.h"
|
|
|
|
|
2009-09-10 15:06:40 +02:00
|
|
|
#ifndef AGI_PRE
|
|
|
|
#include <stdio.h>
|
2010-06-09 10:14:50 +02:00
|
|
|
#include <vector>
|
2009-09-10 15:06:40 +02:00
|
|
|
|
2010-06-09 10:14:50 +02:00
|
|
|
#include <wx/bitmap.h>
|
|
|
|
#include <wx/button.h>
|
|
|
|
#include <wx/choice.h>
|
2009-09-10 15:06:40 +02:00
|
|
|
#include <wx/clipbrd.h>
|
|
|
|
#include <wx/dataobj.h>
|
2007-09-12 01:22:26 +02:00
|
|
|
#include <wx/dcclient.h>
|
|
|
|
#include <wx/dcmemory.h>
|
|
|
|
#include <wx/dcscreen.h>
|
2010-06-09 10:14:50 +02:00
|
|
|
#include <wx/dialog.h>
|
2009-09-10 15:06:40 +02:00
|
|
|
#include <wx/event.h>
|
|
|
|
#include <wx/gbsizer.h>
|
|
|
|
#include <wx/image.h>
|
2011-01-11 18:22:44 +01:00
|
|
|
#include <wx/rawbmp.h>
|
2007-09-12 01:22:26 +02:00
|
|
|
#include <wx/settings.h>
|
2009-09-10 15:06:40 +02:00
|
|
|
#include <wx/sizer.h>
|
2010-06-09 10:14:50 +02:00
|
|
|
#include <wx/spinctrl.h>
|
|
|
|
#include <wx/statbmp.h>
|
2009-09-10 15:06:40 +02:00
|
|
|
#include <wx/statbox.h>
|
|
|
|
#include <wx/stattext.h>
|
2010-06-09 10:14:50 +02:00
|
|
|
#include <wx/textctrl.h>
|
2009-09-10 15:06:40 +02:00
|
|
|
#include <wx/tokenzr.h>
|
|
|
|
#endif
|
|
|
|
|
2011-07-27 07:36:30 +02:00
|
|
|
#include <libaegisub/scoped_ptr.h>
|
|
|
|
|
2006-01-16 22:02:54 +01:00
|
|
|
#include "ass_style.h"
|
2009-09-10 15:06:40 +02:00
|
|
|
#include "colorspace.h"
|
2010-05-21 03:13:36 +02:00
|
|
|
#include "compat.h"
|
2009-09-10 15:06:40 +02:00
|
|
|
#include "dialog_colorpicker.h"
|
2008-01-13 23:06:04 +01:00
|
|
|
#include "help_button.h"
|
2009-07-24 02:08:25 +02:00
|
|
|
#include "libresrc/libresrc.h"
|
2010-05-21 03:13:36 +02:00
|
|
|
#include "main.h"
|
2011-07-27 07:36:30 +02:00
|
|
|
#include "persist_location.h"
|
2009-09-10 15:06:40 +02:00
|
|
|
#include "utils.h"
|
2008-07-16 03:29:36 +02:00
|
|
|
|
2010-06-09 10:14:50 +02:00
|
|
|
/// DOCME
|
|
|
|
/// @class ColorPickerSpectrum
|
|
|
|
/// @brief DOCME
|
|
|
|
///
|
|
|
|
/// DOCME
|
|
|
|
class ColorPickerSpectrum : public wxControl {
|
|
|
|
public:
|
|
|
|
enum PickerDirection {
|
|
|
|
HorzVert,
|
|
|
|
Horz,
|
|
|
|
Vert
|
|
|
|
};
|
|
|
|
private:
|
2011-10-17 19:52:49 +02:00
|
|
|
int x;
|
|
|
|
int y;
|
2010-06-09 10:14:50 +02:00
|
|
|
|
|
|
|
/// DOCME
|
|
|
|
wxBitmap *background;
|
|
|
|
|
|
|
|
/// DOCME
|
|
|
|
PickerDirection direction;
|
|
|
|
|
|
|
|
void OnPaint(wxPaintEvent &evt);
|
|
|
|
void OnMouse(wxMouseEvent &evt);
|
|
|
|
|
|
|
|
public:
|
2011-10-17 19:52:49 +02:00
|
|
|
ColorPickerSpectrum(wxWindow *parent, PickerDirection direction, wxSize size);
|
2010-06-09 10:14:50 +02:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
int GetX() const { return x; }
|
|
|
|
int GetY() const { return y; }
|
2010-06-09 10:14:50 +02:00
|
|
|
void SetXY(int xx, int yy);
|
2010-06-18 09:14:11 +02:00
|
|
|
void SetBackground(wxBitmap *new_background, bool force = false);
|
2010-06-09 10:14:50 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/// DOCME
|
|
|
|
/// @class ColorPickerRecent
|
|
|
|
/// @brief DOCME
|
|
|
|
///
|
|
|
|
/// DOCME
|
|
|
|
class ColorPickerRecent : public wxControl {
|
2011-10-17 19:52:49 +02:00
|
|
|
int rows; ///< Number of rows of colors
|
|
|
|
int cols; ///< Number of cols of colors
|
|
|
|
int cellsize; ///< Width/Height of each cell
|
2010-06-09 10:14:50 +02:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
/// The colors currently displayed in the control
|
2010-06-09 10:14:50 +02:00
|
|
|
std::vector<wxColour> colors;
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
/// Does the background need to be regenerated?
|
2010-06-09 10:14:50 +02:00
|
|
|
bool background_valid;
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
/// Bitmap storing the cached background
|
2010-06-09 10:14:50 +02:00
|
|
|
wxBitmap background;
|
|
|
|
|
|
|
|
void OnClick(wxMouseEvent &evt);
|
|
|
|
void OnPaint(wxPaintEvent &evt);
|
|
|
|
void OnSize(wxSizeEvent &evt);
|
|
|
|
|
|
|
|
public:
|
2011-10-17 19:52:49 +02:00
|
|
|
ColorPickerRecent(wxWindow *parent, int cols, int rows, int cellsize);
|
2010-06-09 10:14:50 +02:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
/// Load the colors to show from a string
|
|
|
|
void LoadFromString(const wxString &recent_string = "");
|
|
|
|
/// Save the colors currently shown to a string
|
2010-06-09 10:14:50 +02:00
|
|
|
wxString StoreToString();
|
2011-10-17 19:52:49 +02:00
|
|
|
/// Add a color to the beginning of the recent list
|
2010-06-09 10:14:50 +02:00
|
|
|
void AddColor(wxColour color);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// DOCME
|
|
|
|
/// @class ColorPickerScreenDropper
|
|
|
|
/// @brief DOCME
|
|
|
|
///
|
|
|
|
/// DOCME
|
|
|
|
class ColorPickerScreenDropper : public wxControl {
|
|
|
|
/// DOCME
|
|
|
|
wxBitmap capture;
|
|
|
|
|
|
|
|
/// DOCME
|
|
|
|
|
|
|
|
/// DOCME
|
|
|
|
int resx, resy;
|
|
|
|
|
|
|
|
/// DOCME
|
|
|
|
int magnification;
|
|
|
|
|
|
|
|
void OnMouse(wxMouseEvent &evt);
|
|
|
|
void OnPaint(wxPaintEvent &evt);
|
|
|
|
|
|
|
|
public:
|
2011-10-17 19:52:49 +02:00
|
|
|
ColorPickerScreenDropper(wxWindow *parent, int resx, int resy, int magnification);
|
2010-06-09 10:14:50 +02:00
|
|
|
|
|
|
|
void DropFromScreenXY(int x, int y);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// DOCME
|
|
|
|
/// @class DialogColorPicker
|
|
|
|
/// @brief DOCME
|
|
|
|
///
|
|
|
|
/// DOCME
|
|
|
|
class DialogColorPicker : public wxDialog {
|
2011-07-27 07:36:30 +02:00
|
|
|
agi::scoped_ptr<PersistLocation> persist;
|
2010-06-09 10:14:50 +02:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
wxColour cur_color; ///< Currently selected colour
|
2010-06-09 10:14:50 +02:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
bool spectrum_dirty; ///< Does the spectrum image need to be regenerated?
|
|
|
|
ColorPickerSpectrum *spectrum; ///< The 2D color spectrum
|
|
|
|
ColorPickerSpectrum *slider; ///< The 1D slider for the color component not in the slider
|
2010-06-09 10:14:50 +02:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
wxChoice *colorspace_choice; ///< The dropdown list to select colorspaces
|
2010-06-09 10:14:50 +02:00
|
|
|
|
2011-07-27 07:36:30 +02:00
|
|
|
static const int slider_width = 10; ///< width in pixels of the color slider control
|
2010-06-09 10:14:50 +02:00
|
|
|
|
|
|
|
wxSpinCtrl *rgb_input[3];
|
2011-10-17 19:52:49 +02:00
|
|
|
wxBitmap *rgb_spectrum[3]; ///< x/y spectrum bitmap where color "i" is excluded from
|
|
|
|
wxBitmap *rgb_slider[3]; ///< z spectrum for color "i"
|
|
|
|
|
2010-06-09 10:14:50 +02:00
|
|
|
wxSpinCtrl *hsl_input[3];
|
2011-10-17 19:52:49 +02:00
|
|
|
wxBitmap *hsl_spectrum; ///< h/s spectrum
|
|
|
|
wxBitmap *hsl_slider; ///< l spectrum
|
|
|
|
|
2010-06-09 10:14:50 +02:00
|
|
|
wxSpinCtrl *hsv_input[3];
|
2011-10-17 19:52:49 +02:00
|
|
|
wxBitmap *hsv_spectrum; ///< s/v spectrum
|
|
|
|
wxBitmap *hsv_slider; ///< h spectrum
|
2010-06-09 10:14:50 +02:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
wxTextCtrl *ass_input;
|
|
|
|
wxTextCtrl *html_input;
|
|
|
|
|
|
|
|
/// The eyedropper is set to a blank icon when it's clicked, so store its normal bitmap
|
2010-06-09 10:14:50 +02:00
|
|
|
wxBitmap eyedropper_bitmap;
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
/// The point where the eyedropper was click, used to make it possible to either
|
|
|
|
/// click the eyedropper or drag the eyedropper
|
2010-06-09 10:14:50 +02:00
|
|
|
wxPoint eyedropper_grab_point;
|
|
|
|
|
|
|
|
/// DOCME
|
|
|
|
bool eyedropper_is_grabbed;
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
wxStaticBitmap *preview_box; ///< A box which simply shows the current color
|
|
|
|
ColorPickerRecent *recent_box; ///< A grid of recently used colors
|
2010-06-09 10:14:50 +02:00
|
|
|
|
|
|
|
/// DOCME
|
|
|
|
ColorPickerScreenDropper *screen_dropper;
|
|
|
|
|
|
|
|
/// DOCME
|
|
|
|
wxStaticBitmap *screen_dropper_icon;
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
/// Update all other controls as a result of modifying an RGB control
|
|
|
|
void UpdateFromRGB(bool dirty = true);
|
|
|
|
/// Update all other controls as a result of modifying an HSL control
|
|
|
|
void UpdateFromHSL(bool dirty = true);
|
|
|
|
/// Update all other controls as a result of modifying an HSV control
|
|
|
|
void UpdateFromHSV(bool dirty = true);
|
|
|
|
/// Update all other controls as a result of modifying the ASS format control
|
|
|
|
void UpdateFromASS();
|
|
|
|
/// Update all other controls as a result of modifying the HTML format control
|
|
|
|
void UpdateFromHTML();
|
|
|
|
|
|
|
|
void SetRGB(unsigned char r, unsigned char g, unsigned char b);
|
|
|
|
void SetHSL(unsigned char r, unsigned char g, unsigned char b);
|
|
|
|
void SetHSV(unsigned char r, unsigned char g, unsigned char b);
|
|
|
|
|
|
|
|
/// Redraw the spectrum display
|
|
|
|
void UpdateSpectrumDisplay();
|
2010-06-09 10:14:50 +02:00
|
|
|
|
|
|
|
wxBitmap *MakeGBSpectrum();
|
|
|
|
wxBitmap *MakeRBSpectrum();
|
|
|
|
wxBitmap *MakeRGSpectrum();
|
|
|
|
wxBitmap *MakeHSSpectrum();
|
|
|
|
wxBitmap *MakeSVSpectrum();
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
/// Constructor helper function for making the color input box sizers
|
|
|
|
template<int N, class Control>
|
|
|
|
wxSizer *MakeColorInputSizer(wxString (&labels)[N], Control *(&inputs)[N]);
|
|
|
|
|
2010-06-09 10:14:50 +02:00
|
|
|
void OnChangeMode(wxCommandEvent &evt);
|
|
|
|
void OnSpectrumChange(wxCommandEvent &evt);
|
|
|
|
void OnSliderChange(wxCommandEvent &evt);
|
|
|
|
void OnRecentSelect(wxCommandEvent &evt); // also handles dropper pick
|
|
|
|
void OnDropperMouse(wxMouseEvent &evt);
|
|
|
|
void OnMouse(wxMouseEvent &evt);
|
|
|
|
|
|
|
|
ColorCallback callback;
|
|
|
|
void *callbackUserdata;
|
|
|
|
|
|
|
|
public:
|
|
|
|
DialogColorPicker(wxWindow *parent, wxColour initial_color, ColorCallback callback = NULL, void *userdata = NULL);
|
|
|
|
~DialogColorPicker();
|
|
|
|
|
|
|
|
void SetColor(wxColour new_color);
|
|
|
|
wxColour GetColor();
|
|
|
|
};
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
/// DOCME
|
2008-11-24 15:05:46 +01:00
|
|
|
static const int spectrum_horz_vert_arrow_size = 4;
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
ColorPickerSpectrum::ColorPickerSpectrum(wxWindow *parent, PickerDirection direction, wxSize size)
|
|
|
|
: wxControl(parent, -1, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE)
|
|
|
|
, x(-1)
|
|
|
|
, y(-1)
|
|
|
|
, background(0)
|
|
|
|
, direction(direction)
|
2006-01-16 22:02:54 +01:00
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
size.x += 2;
|
|
|
|
size.y += 2;
|
2008-11-24 15:05:46 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
if (direction == Vert) size.x += spectrum_horz_vert_arrow_size + 1;
|
|
|
|
if (direction == Horz) size.y += spectrum_horz_vert_arrow_size + 1;
|
2008-11-24 15:05:46 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
SetClientSize(size);
|
2008-11-24 15:05:46 +01:00
|
|
|
SetMinSize(GetSize());
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
Bind(wxEVT_LEFT_DOWN, &ColorPickerSpectrum::OnMouse, this);
|
|
|
|
Bind(wxEVT_LEFT_UP, &ColorPickerSpectrum::OnMouse, this);
|
|
|
|
Bind(wxEVT_MOTION, &ColorPickerSpectrum::OnMouse, this);
|
|
|
|
Bind(wxEVT_PAINT, &ColorPickerSpectrum::OnPaint, this);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void ColorPickerSpectrum::SetXY(int xx, int yy)
|
|
|
|
{
|
2010-06-11 04:25:23 +02:00
|
|
|
if (x != xx || y != yy) {
|
|
|
|
x = xx;
|
|
|
|
y = yy;
|
|
|
|
Refresh(false);
|
|
|
|
}
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2010-06-18 09:14:11 +02:00
|
|
|
/// @brief Set the background image for this spectrum
|
|
|
|
/// @param new_background New background image
|
|
|
|
/// @param force Repaint even if it appears to be the same image
|
|
|
|
void ColorPickerSpectrum::SetBackground(wxBitmap *new_background, bool force)
|
2006-01-16 22:02:54 +01:00
|
|
|
{
|
2010-06-18 09:14:11 +02:00
|
|
|
if (background == new_background && !force) return;
|
2006-01-16 22:02:54 +01:00
|
|
|
background = new_background;
|
2010-06-11 04:25:23 +02:00
|
|
|
Refresh(false);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
wxDEFINE_EVENT(EVT_SPECTRUM_CHANGE, wxCommandEvent);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
void ColorPickerSpectrum::OnPaint(wxPaintEvent &evt)
|
|
|
|
{
|
|
|
|
if (!background) return;
|
|
|
|
|
2010-06-11 04:25:23 +02:00
|
|
|
int height = background->GetHeight();
|
|
|
|
int width = background->GetWidth();
|
2006-01-16 22:02:54 +01:00
|
|
|
wxPaintDC dc(this);
|
|
|
|
|
|
|
|
wxMemoryDC memdc;
|
|
|
|
memdc.SelectObject(*background);
|
2010-06-11 04:25:23 +02:00
|
|
|
dc.Blit(1, 1, width, height, &memdc, 0, 0);
|
2008-11-24 15:05:46 +01:00
|
|
|
|
|
|
|
wxPoint arrow[3];
|
2010-06-11 04:25:23 +02:00
|
|
|
wxRect arrow_box;
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2010-06-11 04:25:23 +02:00
|
|
|
wxPen invpen(*wxWHITE, 3);
|
|
|
|
invpen.SetCap(wxCAP_BUTT);
|
2006-01-16 22:02:54 +01:00
|
|
|
dc.SetLogicalFunction(wxXOR);
|
2008-11-24 15:05:46 +01:00
|
|
|
dc.SetPen(invpen);
|
2010-06-11 04:25:23 +02:00
|
|
|
|
2006-01-16 22:02:54 +01:00
|
|
|
switch (direction) {
|
|
|
|
case HorzVert:
|
|
|
|
// Make a little cross
|
2008-11-24 15:05:46 +01:00
|
|
|
dc.DrawLine(x-4, y+1, x+7, y+1);
|
|
|
|
dc.DrawLine(x+1, y-4, x+1, y+7);
|
2006-01-16 22:02:54 +01:00
|
|
|
break;
|
|
|
|
case Horz:
|
|
|
|
// Make a vertical line stretching all the way across
|
2010-06-11 04:25:23 +02:00
|
|
|
dc.DrawLine(x+1, 1, x+1, height+1);
|
2008-11-24 15:05:46 +01:00
|
|
|
// Points for arrow
|
2010-06-11 04:25:23 +02:00
|
|
|
arrow[0] = wxPoint(x+1, height+2);
|
|
|
|
arrow[1] = wxPoint(x+1-spectrum_horz_vert_arrow_size, height+2+spectrum_horz_vert_arrow_size);
|
|
|
|
arrow[2] = wxPoint(x+1+spectrum_horz_vert_arrow_size, height+2+spectrum_horz_vert_arrow_size);
|
|
|
|
|
|
|
|
arrow_box.SetLeft(0);
|
|
|
|
arrow_box.SetTop(height + 2);
|
|
|
|
arrow_box.SetRight(width + 1 + spectrum_horz_vert_arrow_size);
|
|
|
|
arrow_box.SetBottom(height + 2 + spectrum_horz_vert_arrow_size);
|
2006-01-16 22:02:54 +01:00
|
|
|
break;
|
|
|
|
case Vert:
|
|
|
|
// Make a horizontal line stretching all the way across
|
2010-06-11 04:25:23 +02:00
|
|
|
dc.DrawLine(1, y+1, width+1, y+1);
|
2008-11-24 15:05:46 +01:00
|
|
|
// Points for arrow
|
2010-06-11 04:25:23 +02:00
|
|
|
arrow[0] = wxPoint(width+2, y+1);
|
|
|
|
arrow[1] = wxPoint(width+2+spectrum_horz_vert_arrow_size, y+1-spectrum_horz_vert_arrow_size);
|
|
|
|
arrow[2] = wxPoint(width+2+spectrum_horz_vert_arrow_size, y+1+spectrum_horz_vert_arrow_size);
|
|
|
|
|
|
|
|
arrow_box.SetLeft(width + 2);
|
|
|
|
arrow_box.SetTop(0);
|
|
|
|
arrow_box.SetRight(width + 2 + spectrum_horz_vert_arrow_size);
|
|
|
|
arrow_box.SetBottom(height + 1 + spectrum_horz_vert_arrow_size);
|
2006-01-16 22:02:54 +01:00
|
|
|
break;
|
|
|
|
}
|
2008-11-24 15:05:46 +01:00
|
|
|
|
|
|
|
if (direction == Horz || direction == Vert) {
|
2010-06-11 04:25:23 +02:00
|
|
|
wxBrush bgBrush;
|
|
|
|
bgBrush.SetColour(GetBackgroundColour());
|
2008-11-24 15:05:46 +01:00
|
|
|
dc.SetLogicalFunction(wxCOPY);
|
|
|
|
dc.SetPen(*wxTRANSPARENT_PEN);
|
2010-06-11 04:25:23 +02:00
|
|
|
dc.SetBrush(bgBrush);
|
|
|
|
dc.DrawRectangle(arrow_box);
|
|
|
|
|
|
|
|
// Arrow pointing at current point
|
2008-11-24 15:05:46 +01:00
|
|
|
dc.SetBrush(*wxBLACK_BRUSH);
|
|
|
|
dc.DrawPolygon(3, arrow);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Border around the spectrum
|
2010-06-11 04:25:23 +02:00
|
|
|
wxPen blkpen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), 1);
|
|
|
|
blkpen.SetCap(wxCAP_BUTT);
|
|
|
|
|
2008-11-24 15:05:46 +01:00
|
|
|
dc.SetLogicalFunction(wxCOPY);
|
|
|
|
dc.SetPen(blkpen);
|
|
|
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
|
|
|
dc.DrawRectangle(0, 0, background->GetWidth()+2, background->GetHeight()+2);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void ColorPickerSpectrum::OnMouse(wxMouseEvent &evt)
|
|
|
|
{
|
|
|
|
evt.Skip();
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
// We only care about mouse move events during a drag
|
|
|
|
if (evt.Moving())
|
2006-01-16 22:02:54 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (evt.LeftDown()) {
|
|
|
|
CaptureMouse();
|
2007-07-05 00:23:52 +02:00
|
|
|
SetCursor(wxCursor(wxCURSOR_BLANK));
|
2011-10-17 19:52:49 +02:00
|
|
|
}
|
|
|
|
else if (evt.LeftUp() && HasCapture()) {
|
2006-01-16 22:02:54 +01:00
|
|
|
ReleaseMouse();
|
2007-07-05 00:23:52 +02:00
|
|
|
SetCursor(wxNullCursor);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (evt.LeftDown() || (HasCapture() && evt.LeftIsDown())) {
|
2011-10-17 19:52:49 +02:00
|
|
|
int newx = mid(0, evt.GetX(), GetClientSize().x - 1);
|
|
|
|
int newy = mid(0, evt.GetY(), GetClientSize().y - 1);
|
2010-06-11 04:25:23 +02:00
|
|
|
SetXY(newx, newy);
|
2011-10-17 19:52:49 +02:00
|
|
|
wxCommandEvent evt2(EVT_SPECTRUM_CHANGE, GetId());
|
2006-01-16 22:02:54 +01:00
|
|
|
AddPendingEvent(evt2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
#ifdef WIN32
|
|
|
|
#define STATIC_BORDER_FLAG wxSTATIC_BORDER
|
|
|
|
#else
|
|
|
|
#define STATIC_BORDER_FLAG wxSIMPLE_BORDER
|
|
|
|
#endif
|
|
|
|
|
|
|
|
ColorPickerRecent::ColorPickerRecent(wxWindow *parent, int cols, int rows, int cellsize)
|
|
|
|
: wxControl(parent, -1, wxDefaultPosition, wxDefaultSize, STATIC_BORDER_FLAG)
|
|
|
|
, rows(rows)
|
|
|
|
, cols(cols)
|
|
|
|
, cellsize(cellsize)
|
2008-07-16 03:29:36 +02:00
|
|
|
, background_valid(false)
|
2006-01-16 22:02:54 +01:00
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
LoadFromString();
|
2006-07-07 00:16:27 +02:00
|
|
|
SetClientSize(cols*cellsize, rows*cellsize);
|
|
|
|
SetMinSize(GetSize());
|
|
|
|
SetMaxSize(GetSize());
|
2007-07-05 00:23:52 +02:00
|
|
|
SetCursor(*wxCROSS_CURSOR);
|
2011-10-17 19:52:49 +02:00
|
|
|
|
|
|
|
Bind(wxEVT_PAINT, &ColorPickerRecent::OnPaint, this);
|
|
|
|
Bind(wxEVT_LEFT_DOWN, &ColorPickerRecent::OnClick, this);
|
|
|
|
Bind(wxEVT_SIZE, &ColorPickerRecent::OnSize, this);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void ColorPickerRecent::LoadFromString(const wxString &recent_string)
|
|
|
|
{
|
|
|
|
colors.clear();
|
2011-09-28 21:43:11 +02:00
|
|
|
wxStringTokenizer toker(recent_string, " ", false);
|
2006-01-16 22:02:54 +01:00
|
|
|
while (toker.HasMoreTokens()) {
|
|
|
|
AssColor color;
|
2007-01-18 07:45:55 +01:00
|
|
|
color.Parse(toker.NextToken());
|
2010-08-03 04:16:26 +02:00
|
|
|
color.a = 0; // opaque
|
2006-01-16 22:02:54 +01:00
|
|
|
colors.push_back(color.GetWXColor());
|
|
|
|
}
|
|
|
|
while ((int)colors.size() < rows*cols) {
|
|
|
|
colors.push_back(*wxBLACK);
|
|
|
|
}
|
2011-10-17 19:52:49 +02:00
|
|
|
|
2008-07-16 03:29:36 +02:00
|
|
|
background_valid = false;
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
wxString ColorPickerRecent::StoreToString()
|
|
|
|
{
|
|
|
|
wxString res;
|
|
|
|
for (int i = 0; i < rows*cols; i++) {
|
2011-10-17 19:52:49 +02:00
|
|
|
res << AssColor(colors[i]).GetASSFormatted(false, false, false) << " ";
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
2011-10-17 19:52:49 +02:00
|
|
|
return res.Trim(true);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void ColorPickerRecent::AddColor(wxColour color)
|
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
colors.erase(remove(colors.begin(), colors.end(), color), colors.end());
|
2006-01-16 22:02:54 +01:00
|
|
|
colors.insert(colors.begin(), color);
|
2011-10-17 19:52:49 +02:00
|
|
|
|
2008-07-16 03:29:36 +02:00
|
|
|
background_valid = false;
|
2011-10-17 19:52:49 +02:00
|
|
|
|
2006-01-16 22:02:54 +01:00
|
|
|
Refresh(false);
|
|
|
|
}
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
wxDEFINE_EVENT(EVT_RECENT_SELECT, wxCommandEvent);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
void ColorPickerRecent::OnClick(wxMouseEvent &evt)
|
|
|
|
{
|
|
|
|
wxSize cs = GetClientSize();
|
2011-10-17 19:52:49 +02:00
|
|
|
int cx = evt.GetX() * cols / cs.x;
|
|
|
|
int cy = evt.GetY() * rows / cs.y;
|
2006-07-07 00:16:27 +02:00
|
|
|
if (cx < 0 || cx > cols || cy < 0 || cy > rows) return;
|
2011-10-17 19:52:49 +02:00
|
|
|
int i = cols*cy + cx;
|
|
|
|
|
2006-01-16 22:02:54 +01:00
|
|
|
if (i >= 0 && i < (int)colors.size()) {
|
2011-10-17 19:52:49 +02:00
|
|
|
wxCommandEvent evnt(EVT_RECENT_SELECT, GetId());
|
|
|
|
evnt.SetString(AssColor(colors[i]).GetASSFormatted(false, false, false));
|
2010-06-11 04:24:59 +02:00
|
|
|
AddPendingEvent(evnt);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ColorPickerRecent::OnPaint(wxPaintEvent &evt)
|
|
|
|
{
|
2008-07-16 03:29:36 +02:00
|
|
|
wxPaintDC pdc(this);
|
|
|
|
PrepareDC(pdc);
|
|
|
|
|
|
|
|
if (!background_valid) {
|
|
|
|
wxSize sz = pdc.GetSize();
|
2011-10-17 19:52:49 +02:00
|
|
|
|
2008-07-16 03:29:36 +02:00
|
|
|
background = wxBitmap(sz.x, sz.y);
|
|
|
|
wxMemoryDC dc(background);
|
2011-10-17 19:52:49 +02:00
|
|
|
|
2008-07-16 03:29:36 +02:00
|
|
|
dc.SetPen(*wxTRANSPARENT_PEN);
|
2011-10-17 19:52:49 +02:00
|
|
|
|
2008-07-16 03:29:36 +02:00
|
|
|
for (int cy = 0; cy < rows; cy++) {
|
|
|
|
for (int cx = 0; cx < cols; cx++) {
|
2011-10-17 19:52:49 +02:00
|
|
|
int x = cx * cellsize;
|
|
|
|
int y = cy * cellsize;
|
|
|
|
|
|
|
|
dc.SetBrush(wxBrush(colors[cy * cols + cx]));
|
2008-07-16 03:29:36 +02:00
|
|
|
dc.DrawRectangle(x, y, x+cellsize, y+cellsize);
|
|
|
|
}
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
2011-10-17 19:52:49 +02:00
|
|
|
|
2008-07-16 03:29:36 +02:00
|
|
|
background_valid = true;
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
2011-10-17 19:52:49 +02:00
|
|
|
|
2008-07-16 03:29:36 +02:00
|
|
|
pdc.DrawBitmap(background, 0, 0, false);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2006-07-07 00:16:27 +02:00
|
|
|
void ColorPickerRecent::OnSize(wxSizeEvent &evt)
|
|
|
|
{
|
2008-07-16 03:29:36 +02:00
|
|
|
background_valid = false;
|
2006-07-07 00:16:27 +02:00
|
|
|
Refresh();
|
|
|
|
}
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
ColorPickerScreenDropper::ColorPickerScreenDropper(wxWindow *parent, int resx, int resy, int magnification)
|
|
|
|
: wxControl(parent, -1, wxDefaultPosition, wxDefaultSize, STATIC_BORDER_FLAG)
|
|
|
|
, resx(resx)
|
|
|
|
, resy(resy)
|
|
|
|
, magnification(magnification)
|
2006-01-16 22:02:54 +01:00
|
|
|
{
|
|
|
|
SetClientSize(resx*magnification, resy*magnification);
|
|
|
|
SetMinSize(GetSize());
|
|
|
|
SetMaxSize(GetSize());
|
2007-07-05 00:23:52 +02:00
|
|
|
SetCursor(*wxCROSS_CURSOR);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
capture = wxBitmap(resx, resy);
|
|
|
|
wxMemoryDC capdc;
|
|
|
|
capdc.SelectObject(capture);
|
|
|
|
capdc.SetPen(*wxTRANSPARENT_PEN);
|
|
|
|
capdc.SetBrush(*wxWHITE_BRUSH);
|
|
|
|
capdc.DrawRectangle(0, 0, resx, resy);
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
Bind(wxEVT_PAINT, &ColorPickerScreenDropper::OnPaint, this);
|
|
|
|
Bind(wxEVT_LEFT_DOWN, &ColorPickerScreenDropper::OnMouse, this);
|
|
|
|
}
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
wxDEFINE_EVENT(EVT_DROPPER_SELECT, wxCommandEvent);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
void ColorPickerScreenDropper::OnMouse(wxMouseEvent &evt)
|
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
int x = evt.GetX() / magnification;
|
|
|
|
int y = evt.GetY() / magnification;
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
if (x >= 0 && y >= 0 && x < resx && y < resy) {
|
|
|
|
wxColour color;
|
2010-08-03 04:16:26 +02:00
|
|
|
#ifdef __WXMAC__
|
2011-10-17 19:52:49 +02:00
|
|
|
// wxMemoryDC::GetPixel() isn't implemented on OS X
|
|
|
|
// Work around it by reading pixel data from the bitmap instead
|
|
|
|
wxAlphaPixelData cappd(capture);
|
|
|
|
wxAlphaPixelData::Iterator cappdi(cappd);
|
|
|
|
cappdi.MoveTo(cappd, x, y);
|
|
|
|
color.Set(cappdi.Red(), cappdi.Green(), cappdi.Blue());
|
2010-08-03 04:16:26 +02:00
|
|
|
#else
|
2011-10-17 19:52:49 +02:00
|
|
|
wxMemoryDC capdc(capture);
|
|
|
|
capdc.GetPixel(x, y, &color);
|
2010-08-03 04:16:26 +02:00
|
|
|
#endif
|
2011-10-17 19:52:49 +02:00
|
|
|
color = wxColour(color.Red(), color.Green(), color.Blue(), wxALPHA_OPAQUE);
|
|
|
|
wxCommandEvent evnt(EVT_DROPPER_SELECT, GetId());
|
|
|
|
evnt.SetString(AssColor(color).GetASSFormatted(false, false, false));
|
|
|
|
AddPendingEvent(evnt);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ColorPickerScreenDropper::OnPaint(wxPaintEvent &evt)
|
|
|
|
{
|
|
|
|
wxPaintDC pdc(this);
|
2011-10-17 19:52:49 +02:00
|
|
|
|
2010-08-03 04:16:26 +02:00
|
|
|
#ifdef __WXMAC__
|
|
|
|
// See OnMouse() above
|
|
|
|
wxAlphaPixelData cappd(capture);
|
|
|
|
wxAlphaPixelData::Iterator cappdi(cappd);
|
|
|
|
#else
|
|
|
|
wxMemoryDC capdc(capture);
|
|
|
|
#endif
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
pdc.SetPen(*wxTRANSPARENT_PEN);
|
|
|
|
|
|
|
|
for (int x = 0; x < resx; x++) {
|
|
|
|
for (int y = 0; y < resy; y++) {
|
|
|
|
wxColour color;
|
2010-08-03 04:16:26 +02:00
|
|
|
#ifdef __WXMAC__
|
|
|
|
cappdi.MoveTo(cappd, x, y);
|
|
|
|
color.Set(cappdi.Red(), cappdi.Green(), cappdi.Blue());
|
|
|
|
#else
|
2006-01-16 22:02:54 +01:00
|
|
|
capdc.GetPixel(x, y, &color);
|
2010-08-03 04:16:26 +02:00
|
|
|
#endif
|
2006-01-16 22:02:54 +01:00
|
|
|
pdc.SetBrush(wxBrush(color));
|
|
|
|
pdc.DrawRectangle(x*magnification, y*magnification, magnification, magnification);
|
|
|
|
}
|
|
|
|
}
|
2007-07-05 00:16:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void ColorPickerScreenDropper::DropFromScreenXY(int x, int y)
|
|
|
|
{
|
2010-08-03 04:16:26 +02:00
|
|
|
wxMemoryDC capdc(capture);
|
2007-07-05 00:16:24 +02:00
|
|
|
wxScreenDC screen;
|
|
|
|
|
2010-08-03 04:16:26 +02:00
|
|
|
#ifdef __WXMAC__
|
|
|
|
wxBitmap screenbmp = screen.GetAsBitmap().GetSubBitmap(wxRect(x-resx/2, y-resy/2, resx, resy));
|
|
|
|
capdc.DrawBitmap(screenbmp, 0, 0);
|
|
|
|
#else
|
2007-07-05 00:16:24 +02:00
|
|
|
screen.StartDrawingOnTop();
|
|
|
|
capdc.Blit(0, 0, resx, resy, &screen, x-resx/2, y-resy/2);
|
|
|
|
screen.EndDrawingOnTop();
|
2010-08-03 04:16:26 +02:00
|
|
|
#endif
|
2007-07-05 00:16:24 +02:00
|
|
|
|
|
|
|
Refresh(false);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2010-06-09 10:14:50 +02:00
|
|
|
wxColour GetColorFromUser(wxWindow *parent, wxColour original, ColorCallback callback, void* userdata)
|
2006-01-16 22:02:54 +01:00
|
|
|
{
|
2010-06-09 10:14:50 +02:00
|
|
|
DialogColorPicker dialog(parent, original, callback, userdata);
|
2011-10-17 19:52:49 +02:00
|
|
|
if (dialog.ShowModal() == wxID_OK)
|
|
|
|
original = dialog.GetColor();
|
|
|
|
if (callback)
|
|
|
|
callback(userdata, original);
|
|
|
|
return original;
|
|
|
|
}
|
|
|
|
|
|
|
|
static wxBitmap *make_rgb_image(int width, int offset) {
|
|
|
|
unsigned char *oslid = (unsigned char *)calloc(width * 256 * 3, 1);
|
|
|
|
unsigned char *slid = oslid + offset;
|
|
|
|
for (int y = 0; y < 256; y++) {
|
|
|
|
for (int x = 0; x < width; x++) {
|
|
|
|
*slid = clip_colorval(y);
|
|
|
|
slid += 3;
|
|
|
|
}
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
2011-10-17 19:52:49 +02:00
|
|
|
wxImage img(width, 256, oslid);
|
|
|
|
return new wxBitmap(img);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2010-06-09 10:14:50 +02:00
|
|
|
DialogColorPicker::DialogColorPicker(wxWindow *parent, wxColour initial_color, ColorCallback callback, void* userdata)
|
2011-10-17 19:52:49 +02:00
|
|
|
: wxDialog(parent, -1, _("Select Colour"))
|
2010-06-09 10:14:50 +02:00
|
|
|
, callback(callback)
|
|
|
|
, callbackUserdata(userdata)
|
2006-01-16 22:02:54 +01:00
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
memset(rgb_spectrum, 0, sizeof rgb_spectrum);
|
|
|
|
hsl_spectrum = 0;
|
|
|
|
hsv_spectrum = 0;
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
// generate spectrum slider bar images
|
2011-10-17 19:52:49 +02:00
|
|
|
rgb_slider[0] = make_rgb_image(slider_width, 0);
|
|
|
|
rgb_slider[1] = make_rgb_image(slider_width, 1);
|
|
|
|
rgb_slider[2] = make_rgb_image(slider_width, 2);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2006-03-22 17:07:49 +01:00
|
|
|
// luminance
|
2011-10-24 22:17:30 +02:00
|
|
|
unsigned char *slid = (unsigned char *)malloc(slider_width*256*3);
|
2006-01-16 22:02:54 +01:00
|
|
|
for (int y = 0; y < 256; y++) {
|
2011-10-24 22:17:30 +02:00
|
|
|
memset(slid + y * slider_width * 3, y, slider_width * 3);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
2011-10-24 22:17:30 +02:00
|
|
|
wxImage sliderimg(slider_width, 256, slid);
|
2006-03-22 17:07:49 +01:00
|
|
|
hsl_slider = new wxBitmap(sliderimg);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-24 22:17:30 +02:00
|
|
|
slid = (unsigned char *)malloc(slider_width*256*3);
|
2006-01-16 22:02:54 +01:00
|
|
|
for (int y = 0; y < 256; y++) {
|
2011-10-24 22:17:30 +02:00
|
|
|
unsigned char rgb[3];
|
|
|
|
hsv_to_rgb(y, 255, 255, rgb, rgb + 1, rgb + 2);
|
2006-01-16 22:02:54 +01:00
|
|
|
for (int x = 0; x < slider_width; x++) {
|
2011-10-24 22:17:30 +02:00
|
|
|
memcpy(slid + y * slider_width * 3 + x * 3, rgb, 3);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
}
|
2011-10-24 22:17:30 +02:00
|
|
|
sliderimg.SetData(slid);
|
2006-01-16 22:02:54 +01:00
|
|
|
hsv_slider = new wxBitmap(sliderimg);
|
|
|
|
|
|
|
|
// Create the controls for the dialog
|
2007-04-09 21:04:11 +02:00
|
|
|
wxSizer *spectrum_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Colour spectrum"));
|
2011-10-17 19:52:49 +02:00
|
|
|
spectrum = new ColorPickerSpectrum(this, ColorPickerSpectrum::HorzVert, wxSize(256, 256));
|
|
|
|
slider = new ColorPickerSpectrum(this, ColorPickerSpectrum::Vert, wxSize(slider_width, 256));
|
|
|
|
wxString modes[] = { _("RGB/R"), _("RGB/G"), _("RGB/B"), _("HSL/L"), _("HSV/H") };
|
|
|
|
colorspace_choice = new wxChoice(this, -1, wxDefaultPosition, wxDefaultSize, 5, modes);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
wxSize colorinput_size(70, -1);
|
|
|
|
wxSize colorinput_labelsize(40, -1);
|
|
|
|
|
2007-04-09 21:04:11 +02:00
|
|
|
wxSizer *rgb_box = new wxStaticBoxSizer(wxHORIZONTAL, this, _("RGB colour"));
|
|
|
|
wxSizer *hsl_box = new wxStaticBoxSizer(wxVERTICAL, this, _("HSL colour"));
|
|
|
|
wxSizer *hsv_box = new wxStaticBoxSizer(wxVERTICAL, this, _("HSV colour"));
|
2011-10-17 19:52:49 +02:00
|
|
|
for (int i = 0; i < 3; ++i) {
|
|
|
|
rgb_input[i] = new wxSpinCtrl(this, -1, "", wxDefaultPosition, colorinput_size, wxSP_ARROW_KEYS, 0, 255);
|
|
|
|
hsl_input[i] = new wxSpinCtrl(this, -1, "", wxDefaultPosition, colorinput_size, wxSP_ARROW_KEYS, 0, 255);
|
|
|
|
hsv_input[i] = new wxSpinCtrl(this, -1, "", wxDefaultPosition, colorinput_size, wxSP_ARROW_KEYS, 0, 255);
|
|
|
|
}
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
ass_input = new wxTextCtrl(this, -1, "", wxDefaultPosition, colorinput_size);
|
|
|
|
html_input = new wxTextCtrl(this, -1, "", wxDefaultPosition, colorinput_size);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
preview_box = new wxStaticBitmap(this, -1, wxBitmap(40, 40, 24), wxDefaultPosition, wxSize(40, 40), STATIC_BORDER_FLAG);
|
|
|
|
recent_box = new ColorPickerRecent(this, 8, 4, 16);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2009-07-25 06:49:59 +02:00
|
|
|
eyedropper_bitmap = GETIMAGE(eyedropper_tool_24);
|
2007-07-05 00:16:24 +02:00
|
|
|
eyedropper_bitmap.SetMask(new wxMask(eyedropper_bitmap, wxColour(255, 0, 255)));
|
2011-10-17 19:52:49 +02:00
|
|
|
screen_dropper_icon = new wxStaticBitmap(this, -1, eyedropper_bitmap, wxDefaultPosition, wxDefaultSize, wxRAISED_BORDER);
|
|
|
|
screen_dropper = new ColorPickerScreenDropper(this, 7, 7, 8);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
// Arrange the controls in a nice way
|
|
|
|
wxSizer *spectop_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
|
|
spectop_sizer->Add(new wxStaticText(this, -1, _("Spectrum mode:")), 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxRIGHT, 5);
|
|
|
|
spectop_sizer->Add(colorspace_choice, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT);
|
|
|
|
spectop_sizer->Add(5, 5, 1, wxEXPAND);
|
|
|
|
spectop_sizer->Add(preview_box, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT);
|
2010-01-20 23:49:26 +01:00
|
|
|
wxSizer *spectrum_sizer = new wxFlexGridSizer(2, 5, 5);
|
2006-01-16 22:02:54 +01:00
|
|
|
spectrum_sizer->Add(spectop_sizer, wxEXPAND);
|
|
|
|
spectrum_sizer->AddStretchSpacer(1);
|
|
|
|
spectrum_sizer->Add(spectrum);
|
|
|
|
spectrum_sizer->Add(slider);
|
|
|
|
spectrum_box->Add(spectrum_sizer, 0, wxALL, 3);
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
wxString rgb_labels[] = { _("Red:"), _("Green:"), _("Blue:") };
|
|
|
|
rgb_box->Add(MakeColorInputSizer(rgb_labels, rgb_input), 1, wxALL|wxEXPAND, 3);
|
|
|
|
|
|
|
|
wxString ass_labels[] = { "ASS:", "HTML:" };
|
|
|
|
wxTextCtrl *ass_ctrls[] = { ass_input, html_input };
|
|
|
|
rgb_box->Add(MakeColorInputSizer(ass_labels, ass_ctrls), 0, wxALL|wxCENTER|wxEXPAND, 3);
|
|
|
|
|
|
|
|
wxString hsl_labels[] = { _("Hue:"), _("Sat.:"), _("Lum.:") };
|
|
|
|
hsl_box->Add(MakeColorInputSizer(hsl_labels, hsl_input), 0, wxALL|wxEXPAND, 3);
|
|
|
|
|
|
|
|
wxString hsv_labels[] = { _("Hue:"), _("Sat.:"), _("Value:") };
|
|
|
|
hsv_box->Add(MakeColorInputSizer(hsv_labels, hsv_input), 0, wxALL|wxEXPAND, 3);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2006-07-07 00:16:27 +02:00
|
|
|
wxSizer *hsx_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
|
|
hsx_sizer->Add(hsl_box);
|
|
|
|
hsx_sizer->AddSpacer(5);
|
|
|
|
hsx_sizer->Add(hsv_box);
|
|
|
|
|
2008-04-21 18:41:46 +02:00
|
|
|
wxSizer *recent_sizer = new wxBoxSizer(wxVERTICAL);
|
|
|
|
recent_sizer->Add(recent_box, 1, wxEXPAND);
|
|
|
|
|
2006-07-07 00:16:27 +02:00
|
|
|
wxSizer *picker_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
|
|
picker_sizer->AddStretchSpacer();
|
2007-07-05 00:16:24 +02:00
|
|
|
picker_sizer->Add(screen_dropper_icon, 0, wxALIGN_CENTER|wxRIGHT, 5);
|
2006-07-07 00:16:27 +02:00
|
|
|
picker_sizer->Add(screen_dropper, 0, wxALIGN_CENTER);
|
|
|
|
picker_sizer->AddStretchSpacer();
|
2008-04-21 18:41:46 +02:00
|
|
|
picker_sizer->Add(recent_sizer, 0, wxALIGN_CENTER);
|
2006-07-07 00:16:27 +02:00
|
|
|
picker_sizer->AddStretchSpacer();
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
wxStdDialogButtonSizer *button_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxHELP);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2006-07-07 00:16:27 +02:00
|
|
|
wxSizer *input_sizer = new wxBoxSizer(wxVERTICAL);
|
|
|
|
input_sizer->Add(rgb_box, 0, wxALIGN_CENTER|wxEXPAND);
|
|
|
|
input_sizer->AddSpacer(5);
|
|
|
|
input_sizer->Add(hsx_sizer, 0, wxALIGN_CENTER|wxEXPAND);
|
|
|
|
input_sizer->AddStretchSpacer(1);
|
|
|
|
input_sizer->Add(picker_sizer, 0, wxALIGN_CENTER|wxEXPAND);
|
|
|
|
input_sizer->AddStretchSpacer(2);
|
|
|
|
input_sizer->Add(button_sizer, 0, wxALIGN_RIGHT|wxALIGN_BOTTOM);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
wxSizer *main_sizer = new wxBoxSizer(wxHORIZONTAL);
|
2008-01-18 18:07:00 +01:00
|
|
|
main_sizer->Add(spectrum_box, 1, wxALL | wxEXPAND, 5);
|
2006-07-07 00:16:27 +02:00
|
|
|
main_sizer->Add(input_sizer, 0, (wxALL&~wxLEFT)|wxEXPAND, 5);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
SetSizerAndFit(main_sizer);
|
|
|
|
|
|
|
|
persist.reset(new PersistLocation(this, "Tool/Colour Picker"));
|
|
|
|
|
|
|
|
using std::tr1::bind;
|
|
|
|
for (int i = 0; i < 3; ++i) {
|
|
|
|
rgb_input[i]->Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, bind(&DialogColorPicker::UpdateFromRGB, this, true));
|
|
|
|
rgb_input[i]->Bind(wxEVT_COMMAND_TEXT_UPDATED, bind(&DialogColorPicker::UpdateFromRGB, this, true));
|
|
|
|
hsl_input[i]->Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, bind(&DialogColorPicker::UpdateFromHSL, this, true));
|
|
|
|
hsl_input[i]->Bind(wxEVT_COMMAND_TEXT_UPDATED, bind(&DialogColorPicker::UpdateFromHSL, this, true));
|
|
|
|
hsv_input[i]->Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, bind(&DialogColorPicker::UpdateFromHSV, this, true));
|
|
|
|
hsv_input[i]->Bind(wxEVT_COMMAND_TEXT_UPDATED, bind(&DialogColorPicker::UpdateFromHSV, this, true));
|
|
|
|
}
|
|
|
|
ass_input->Bind(wxEVT_COMMAND_TEXT_UPDATED, bind(&DialogColorPicker::UpdateFromASS, this));
|
|
|
|
html_input->Bind(wxEVT_COMMAND_TEXT_UPDATED, bind(&DialogColorPicker::UpdateFromHTML, this));
|
|
|
|
|
|
|
|
screen_dropper_icon->Bind(wxEVT_MOTION, &DialogColorPicker::OnDropperMouse, this);
|
|
|
|
screen_dropper_icon->Bind(wxEVT_LEFT_DOWN, &DialogColorPicker::OnDropperMouse, this);
|
|
|
|
screen_dropper_icon->Bind(wxEVT_LEFT_UP, &DialogColorPicker::OnDropperMouse, this);
|
|
|
|
Bind(wxEVT_MOTION, &DialogColorPicker::OnMouse, this);
|
|
|
|
Bind(wxEVT_LEFT_DOWN, &DialogColorPicker::OnMouse, this);
|
|
|
|
Bind(wxEVT_LEFT_UP, &DialogColorPicker::OnMouse, this);
|
|
|
|
|
|
|
|
spectrum->Bind(EVT_SPECTRUM_CHANGE, &DialogColorPicker::OnSpectrumChange, this);
|
|
|
|
slider->Bind(EVT_SPECTRUM_CHANGE, &DialogColorPicker::OnSliderChange, this);
|
|
|
|
recent_box->Bind(EVT_RECENT_SELECT, &DialogColorPicker::OnRecentSelect, this);
|
|
|
|
screen_dropper->Bind(EVT_DROPPER_SELECT, &DialogColorPicker::OnRecentSelect, this);
|
|
|
|
|
|
|
|
colorspace_choice->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &DialogColorPicker::OnChangeMode, this);
|
|
|
|
|
|
|
|
button_sizer->GetHelpButton()->Bind(wxEVT_COMMAND_BUTTON_CLICKED, bind(&HelpButton::OpenPage, _("Colour Picker")));
|
2007-04-09 21:26:32 +02:00
|
|
|
|
2006-01-16 22:02:54 +01:00
|
|
|
// Fill the controls
|
2010-05-21 03:13:36 +02:00
|
|
|
int mode = OPT_GET("Tool/Colour Picker/Mode")->GetInt();
|
2006-03-16 02:26:26 +01:00
|
|
|
if (mode < 0 || mode > 4) mode = 3; // HSL default
|
2006-01-16 22:02:54 +01:00
|
|
|
colorspace_choice->SetSelection(mode);
|
|
|
|
SetColor(initial_color);
|
2010-05-21 03:13:36 +02:00
|
|
|
recent_box->LoadFromString(lagi_wxString(OPT_GET("Tool/Colour Picker/Recent")->GetString()));
|
2011-10-17 19:52:49 +02:00
|
|
|
}
|
2007-07-05 00:16:24 +02:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
template<int N, class Control>
|
|
|
|
wxSizer *DialogColorPicker::MakeColorInputSizer(wxString (&labels)[N], Control *(&inputs)[N])
|
|
|
|
{
|
|
|
|
wxFlexGridSizer * sizer = new wxFlexGridSizer(2, 5, 5);
|
|
|
|
for (int i = 0; i < N; ++i) {
|
|
|
|
sizer->Add(new wxStaticText(this, -1, labels[i], wxDefaultPosition, wxSize(40, -1)), 1, wxALIGN_CENTER_VERTICAL|wxEXPAND);
|
|
|
|
sizer->Add(inputs[i]);
|
|
|
|
}
|
|
|
|
sizer->AddGrowableCol(0,1);
|
|
|
|
return sizer;
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
/// @brief Destructor
|
2006-01-16 22:02:54 +01:00
|
|
|
DialogColorPicker::~DialogColorPicker()
|
|
|
|
{
|
|
|
|
delete rgb_spectrum[0];
|
|
|
|
delete rgb_spectrum[1];
|
|
|
|
delete rgb_spectrum[2];
|
|
|
|
delete hsl_spectrum;
|
|
|
|
delete hsv_spectrum;
|
|
|
|
delete rgb_slider[0];
|
|
|
|
delete rgb_slider[1];
|
|
|
|
delete rgb_slider[2];
|
2006-03-16 02:26:26 +01:00
|
|
|
delete hsl_slider;
|
2006-01-16 22:02:54 +01:00
|
|
|
delete hsv_slider;
|
2009-11-01 08:28:09 +01:00
|
|
|
|
|
|
|
if (screen_dropper_icon->HasCapture()) screen_dropper_icon->ReleaseMouse();
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
/// @brief Sets the currently selected color, and updates all controls
|
2006-01-16 22:02:54 +01:00
|
|
|
void DialogColorPicker::SetColor(wxColour new_color)
|
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
SetRGB(new_color.Red(), new_color.Green(), new_color.Blue());
|
2010-10-16 22:11:48 +02:00
|
|
|
spectrum_dirty = true;
|
2006-01-16 22:02:54 +01:00
|
|
|
UpdateFromRGB();
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
/// @brief Get the currently selected color
|
2006-01-16 22:02:54 +01:00
|
|
|
wxColour DialogColorPicker::GetColor()
|
|
|
|
{
|
|
|
|
recent_box->AddColor(cur_color);
|
2010-05-21 03:13:36 +02:00
|
|
|
OPT_SET("Tool/Colour Picker/Recent")->SetString(STD_STR(recent_box->StoreToString()));
|
2006-01-16 22:02:54 +01:00
|
|
|
return cur_color;
|
|
|
|
}
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
void DialogColorPicker::SetRGB(unsigned char r, unsigned char g, unsigned char b)
|
2006-01-16 22:02:54 +01:00
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
rgb_input[0]->SetValue(r);
|
|
|
|
rgb_input[1]->SetValue(g);
|
|
|
|
rgb_input[2]->SetValue(b);
|
|
|
|
cur_color = wxColour(r, g, b, wxALPHA_OPAQUE);
|
|
|
|
}
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
void DialogColorPicker::SetHSL(unsigned char r, unsigned char g, unsigned char b)
|
|
|
|
{
|
|
|
|
unsigned char h, s, l;
|
2006-01-16 22:02:54 +01:00
|
|
|
rgb_to_hsl(r, g, b, &h, &s, &l);
|
|
|
|
hsl_input[0]->SetValue(h);
|
|
|
|
hsl_input[1]->SetValue(s);
|
|
|
|
hsl_input[2]->SetValue(l);
|
2011-10-17 19:52:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void DialogColorPicker::SetHSV(unsigned char r, unsigned char g, unsigned char b)
|
|
|
|
{
|
|
|
|
unsigned char h, s, v;
|
|
|
|
rgb_to_hsv(r, g, b, &h, &s, &v);
|
|
|
|
hsv_input[0]->SetValue(h);
|
|
|
|
hsv_input[1]->SetValue(s);
|
|
|
|
hsv_input[2]->SetValue(v);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// @brief Use the values entered in the RGB controls to update the other controls
|
|
|
|
void DialogColorPicker::UpdateFromRGB(bool dirty)
|
|
|
|
{
|
|
|
|
unsigned char r, g, b;
|
|
|
|
r = rgb_input[0]->GetValue();
|
|
|
|
g = rgb_input[1]->GetValue();
|
|
|
|
b = rgb_input[2]->GetValue();
|
|
|
|
SetHSL(r, g, b);
|
|
|
|
SetHSV(r, g, b);
|
2008-07-16 03:36:38 +02:00
|
|
|
cur_color = wxColour(r, g, b, wxALPHA_OPAQUE);
|
2011-10-17 19:52:49 +02:00
|
|
|
ass_input->ChangeValue(AssColor(cur_color).GetASSFormatted(false, false, false));
|
|
|
|
html_input->ChangeValue(color_to_html(cur_color));
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
if (dirty)
|
|
|
|
spectrum_dirty = true;
|
|
|
|
UpdateSpectrumDisplay();
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
/// @brief Use the values entered in the HSL controls to update the other controls
|
2011-10-17 19:52:49 +02:00
|
|
|
void DialogColorPicker::UpdateFromHSL(bool dirty)
|
2006-01-16 22:02:54 +01:00
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
unsigned char r, g, b, h, s, l;
|
2006-01-16 22:02:54 +01:00
|
|
|
h = hsl_input[0]->GetValue();
|
|
|
|
s = hsl_input[1]->GetValue();
|
|
|
|
l = hsl_input[2]->GetValue();
|
|
|
|
hsl_to_rgb(h, s, l, &r, &g, &b);
|
2011-10-17 19:52:49 +02:00
|
|
|
SetRGB(r, g, b);
|
|
|
|
SetHSV(r, g, b);
|
|
|
|
|
|
|
|
ass_input->ChangeValue(AssColor(cur_color).GetASSFormatted(false, false, false));
|
|
|
|
html_input->ChangeValue(color_to_html(cur_color));
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
if (dirty)
|
|
|
|
spectrum_dirty = true;
|
|
|
|
UpdateSpectrumDisplay();
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
/// @brief Use the values entered in the HSV controls to update the other controls
|
|
|
|
void DialogColorPicker::UpdateFromHSV(bool dirty)
|
2006-01-16 22:02:54 +01:00
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
unsigned char r, g, b, h, s, v;
|
|
|
|
h = hsv_input[0]->GetValue();
|
|
|
|
s = hsv_input[1]->GetValue();
|
|
|
|
v = hsv_input[2]->GetValue();
|
|
|
|
hsv_to_rgb(h, s, v, &r, &g, &b);
|
|
|
|
SetRGB(r, g, b);
|
|
|
|
SetHSL(r, g, b);
|
|
|
|
ass_input->ChangeValue(AssColor(cur_color).GetASSFormatted(false, false, false));
|
|
|
|
html_input->ChangeValue(color_to_html(cur_color));
|
|
|
|
|
|
|
|
if (dirty)
|
|
|
|
spectrum_dirty = true;
|
2006-01-16 22:02:54 +01:00
|
|
|
UpdateSpectrumDisplay();
|
|
|
|
}
|
|
|
|
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
/// @brief Use the value entered in the ASS hex control to update the other controls
|
2006-01-16 22:02:54 +01:00
|
|
|
void DialogColorPicker::UpdateFromASS()
|
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
unsigned char r, g, b;
|
2006-01-16 22:02:54 +01:00
|
|
|
AssColor ass;
|
2007-01-18 07:45:55 +01:00
|
|
|
ass.Parse(ass_input->GetValue());
|
2006-01-16 22:02:54 +01:00
|
|
|
r = ass.r;
|
|
|
|
g = ass.g;
|
|
|
|
b = ass.b;
|
2011-10-17 19:52:49 +02:00
|
|
|
SetRGB(r, g, b);
|
|
|
|
SetHSL(r, g, b);
|
|
|
|
SetHSV(r, g, b);
|
|
|
|
html_input->ChangeValue(color_to_html(cur_color));
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
spectrum_dirty = true;
|
|
|
|
UpdateSpectrumDisplay();
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
/// @brief Use the value entered in the HTML hex control to update the other controls
|
2006-01-16 22:02:54 +01:00
|
|
|
void DialogColorPicker::UpdateFromHTML()
|
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
unsigned char r, g, b;
|
2006-01-16 22:02:54 +01:00
|
|
|
cur_color = html_to_color(html_input->GetValue());
|
|
|
|
r = cur_color.Red();
|
|
|
|
g = cur_color.Green();
|
|
|
|
b = cur_color.Blue();
|
2011-10-17 19:52:49 +02:00
|
|
|
SetRGB(r, g, b);
|
|
|
|
SetHSL(r, g, b);
|
|
|
|
SetHSV(r, g, b);
|
|
|
|
ass_input->ChangeValue(AssColor(cur_color).GetASSFormatted(false, false, false));
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
spectrum_dirty = true;
|
|
|
|
UpdateSpectrumDisplay();
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void DialogColorPicker::UpdateSpectrumDisplay()
|
|
|
|
{
|
|
|
|
int i = colorspace_choice->GetSelection();
|
|
|
|
switch (i) {
|
|
|
|
case 0:
|
|
|
|
if (spectrum_dirty)
|
2010-06-18 09:14:11 +02:00
|
|
|
spectrum->SetBackground(MakeGBSpectrum(), true);
|
2006-01-16 22:02:54 +01:00
|
|
|
slider->SetBackground(rgb_slider[0]);
|
|
|
|
slider->SetXY(0, rgb_input[0]->GetValue());
|
|
|
|
spectrum->SetXY(rgb_input[2]->GetValue(), rgb_input[1]->GetValue());
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (spectrum_dirty)
|
2010-06-18 09:14:11 +02:00
|
|
|
spectrum->SetBackground(MakeRBSpectrum(), true);
|
2006-01-16 22:02:54 +01:00
|
|
|
slider->SetBackground(rgb_slider[1]);
|
|
|
|
slider->SetXY(0, rgb_input[1]->GetValue());
|
|
|
|
spectrum->SetXY(rgb_input[2]->GetValue(), rgb_input[0]->GetValue());
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if (spectrum_dirty)
|
2010-06-18 09:14:11 +02:00
|
|
|
spectrum->SetBackground(MakeRGSpectrum(), true);
|
2006-01-16 22:02:54 +01:00
|
|
|
slider->SetBackground(rgb_slider[2]);
|
|
|
|
slider->SetXY(0, rgb_input[2]->GetValue());
|
|
|
|
spectrum->SetXY(rgb_input[1]->GetValue(), rgb_input[0]->GetValue());
|
|
|
|
break;
|
2006-03-16 02:26:26 +01:00
|
|
|
case 3:
|
2006-01-16 22:02:54 +01:00
|
|
|
if (spectrum_dirty)
|
2010-06-18 09:14:11 +02:00
|
|
|
spectrum->SetBackground(MakeHSSpectrum(), true);
|
2006-01-16 22:02:54 +01:00
|
|
|
slider->SetBackground(hsl_slider);
|
|
|
|
slider->SetXY(0, hsl_input[2]->GetValue());
|
|
|
|
spectrum->SetXY(hsl_input[1]->GetValue(), hsl_input[0]->GetValue());
|
|
|
|
break;
|
2006-03-16 02:26:26 +01:00
|
|
|
case 4:
|
2006-01-16 22:02:54 +01:00
|
|
|
if (spectrum_dirty)
|
2010-06-18 09:14:11 +02:00
|
|
|
spectrum->SetBackground(MakeSVSpectrum(), true);
|
2006-01-16 22:02:54 +01:00
|
|
|
slider->SetBackground(hsv_slider);
|
|
|
|
slider->SetXY(0, hsv_input[0]->GetValue());
|
|
|
|
spectrum->SetXY(hsv_input[1]->GetValue(), hsv_input[2]->GetValue());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
spectrum_dirty = false;
|
|
|
|
|
2007-01-01 23:56:16 +01:00
|
|
|
wxBitmap tempBmp = preview_box->GetBitmap();
|
|
|
|
{
|
|
|
|
wxMemoryDC previewdc;
|
|
|
|
previewdc.SelectObject(tempBmp);
|
|
|
|
previewdc.SetPen(*wxTRANSPARENT_PEN);
|
|
|
|
previewdc.SetBrush(wxBrush(cur_color));
|
|
|
|
previewdc.DrawRectangle(0, 0, 40, 40);
|
|
|
|
}
|
|
|
|
preview_box->SetBitmap(tempBmp);
|
2006-01-16 22:02:54 +01:00
|
|
|
|
2010-06-09 10:14:50 +02:00
|
|
|
if (callback) callback(callbackUserdata, cur_color);
|
|
|
|
}
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2006-01-16 22:02:54 +01:00
|
|
|
wxBitmap *DialogColorPicker::MakeGBSpectrum()
|
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
delete rgb_spectrum[0];
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
wxImage spectrum_image(256, 256, false);
|
|
|
|
unsigned char *ospec, *spec;
|
|
|
|
|
|
|
|
ospec = spec = (unsigned char *)malloc(256*256*3);
|
|
|
|
for (int g = 0; g < 256; g++) {
|
|
|
|
for (int b = 0; b < 256; b++) {
|
|
|
|
*spec++ = cur_color.Red();
|
|
|
|
*spec++ = g;
|
|
|
|
*spec++ = b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
spectrum_image.SetData(ospec);
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
return rgb_spectrum[0] = new wxBitmap(spectrum_image);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
wxBitmap *DialogColorPicker::MakeRBSpectrum()
|
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
delete rgb_spectrum[1];
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
unsigned char *ospec, *spec;
|
|
|
|
ospec = spec = (unsigned char *)malloc(256*256*3);
|
|
|
|
for (int r = 0; r < 256; r++) {
|
|
|
|
for (int b = 0; b < 256; b++) {
|
|
|
|
*spec++ = r;
|
|
|
|
*spec++ = cur_color.Green();
|
|
|
|
*spec++ = b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
wxImage spectrum_image(256, 256, ospec);
|
|
|
|
return rgb_spectrum[1] = new wxBitmap(spectrum_image);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
wxBitmap *DialogColorPicker::MakeRGSpectrum()
|
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
delete rgb_spectrum[2];
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
unsigned char *ospec, *spec;
|
|
|
|
ospec = spec = (unsigned char *)malloc(256*256*3);
|
|
|
|
for (int r = 0; r < 256; r++) {
|
|
|
|
for (int g = 0; g < 256; g++) {
|
|
|
|
*spec++ = r;
|
|
|
|
*spec++ = g;
|
|
|
|
*spec++ = cur_color.Blue();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
wxImage spectrum_image(256, 256, ospec);
|
|
|
|
return rgb_spectrum[2] = new wxBitmap(spectrum_image);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
wxBitmap *DialogColorPicker::MakeHSSpectrum()
|
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
delete hsl_spectrum;
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
unsigned char *ospec, *spec;
|
|
|
|
ospec = spec = (unsigned char *)malloc(256*256*3);
|
|
|
|
int l = hsl_input[2]->GetValue();
|
|
|
|
|
|
|
|
for (int h = 0; h < 256; h++) {
|
|
|
|
unsigned char maxr, maxg, maxb;
|
|
|
|
hsl_to_rgb(h, 255, l, &maxr, &maxg, &maxb);
|
|
|
|
|
|
|
|
for (int s = 0; s < 256; s++) {
|
|
|
|
*spec++ = maxr * s / 256 + (255-s) * l / 256;
|
|
|
|
*spec++ = maxg * s / 256 + (255-s) * l / 256;
|
|
|
|
*spec++ = maxb * s / 256 + (255-s) * l / 256;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
wxImage spectrum_image(256, 256, ospec);
|
|
|
|
return hsl_spectrum = new wxBitmap(spectrum_image);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
wxBitmap *DialogColorPicker::MakeSVSpectrum()
|
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
delete hsv_spectrum;
|
2006-01-16 22:02:54 +01:00
|
|
|
|
|
|
|
unsigned char *ospec, *spec;
|
|
|
|
ospec = spec = (unsigned char *)malloc(256*256*3);
|
|
|
|
|
|
|
|
int h = hsv_input[0]->GetValue();
|
|
|
|
unsigned char maxr, maxg, maxb;
|
|
|
|
hsv_to_rgb(h, 255, 255, &maxr, &maxg, &maxb);
|
|
|
|
|
|
|
|
for (int v = 0; v < 256; v++) {
|
2011-10-17 19:52:49 +02:00
|
|
|
int rr = (255-maxr) * v / 256;
|
|
|
|
int rg = (255-maxg) * v / 256;
|
|
|
|
int rb = (255-maxb) * v / 256;
|
2006-01-16 22:02:54 +01:00
|
|
|
for (int s = 0; s < 256; s++) {
|
2011-10-17 19:52:49 +02:00
|
|
|
*spec++ = 255 - rr * s / 256 - (255-v);
|
|
|
|
*spec++ = 255 - rg * s / 256 - (255-v);
|
|
|
|
*spec++ = 255 - rb * s / 256 - (255-v);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
wxImage spectrum_image(256, 256, ospec);
|
|
|
|
return hsv_spectrum = new wxBitmap(spectrum_image);
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void DialogColorPicker::OnChangeMode(wxCommandEvent &evt)
|
|
|
|
{
|
2011-10-17 19:52:49 +02:00
|
|
|
spectrum_dirty = true;
|
2010-05-21 03:13:36 +02:00
|
|
|
OPT_SET("Tool/Colour Picker/Mode")->SetInt(colorspace_choice->GetSelection());
|
2006-01-16 22:02:54 +01:00
|
|
|
UpdateSpectrumDisplay();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DialogColorPicker::OnSpectrumChange(wxCommandEvent &evt)
|
|
|
|
{
|
|
|
|
int i = colorspace_choice->GetSelection();
|
|
|
|
switch (i) {
|
|
|
|
case 0:
|
2011-10-17 19:52:49 +02:00
|
|
|
rgb_input[2]->SetValue(spectrum->GetX());
|
|
|
|
rgb_input[1]->SetValue(spectrum->GetY());
|
2006-01-16 22:02:54 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
2011-10-17 19:52:49 +02:00
|
|
|
rgb_input[2]->SetValue(spectrum->GetX());
|
|
|
|
rgb_input[0]->SetValue(spectrum->GetY());
|
2006-01-16 22:02:54 +01:00
|
|
|
break;
|
|
|
|
case 2:
|
2011-10-17 19:52:49 +02:00
|
|
|
rgb_input[1]->SetValue(spectrum->GetX());
|
|
|
|
rgb_input[0]->SetValue(spectrum->GetY());
|
2006-01-16 22:02:54 +01:00
|
|
|
break;
|
2006-03-16 02:26:26 +01:00
|
|
|
case 3:
|
2011-10-17 19:52:49 +02:00
|
|
|
hsl_input[1]->SetValue(spectrum->GetX());
|
|
|
|
hsl_input[0]->SetValue(spectrum->GetY());
|
2006-01-16 22:02:54 +01:00
|
|
|
break;
|
2006-03-16 02:26:26 +01:00
|
|
|
case 4:
|
2011-10-17 19:52:49 +02:00
|
|
|
hsv_input[1]->SetValue(spectrum->GetX());
|
|
|
|
hsv_input[2]->SetValue(spectrum->GetY());
|
2006-01-16 22:02:54 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
switch (i) {
|
|
|
|
case 0: case 1: case 2:
|
|
|
|
UpdateFromRGB(false);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
UpdateFromHSL(false);
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
UpdateFromHSV(false);
|
|
|
|
break;
|
|
|
|
}
|
2006-01-16 22:02:54 +01:00
|
|
|
}
|
|
|
|
|
2011-10-17 19:52:49 +02:00
|
|
|
void DialogColorPicker::OnSliderChange(wxCommandEvent &)
|
2006-01-16 22:02:54 +01:00
|
|
|
{
|
|
|
|
spectrum_dirty = true;
|
|
|
|
int i = colorspace_choice->GetSelection();
|
|
|
|
switch (i) {
|
2011-10-17 19:52:49 +02:00
|
|
|
case 0: case 1: case 2:
|
|
|
|
rgb_input[i]->SetValue(slider->GetY());
|
|
|
|
UpdateFromRGB(false);
|
2006-01-16 22:02:54 +01:00
|
|
|
break;
|
2006-03-16 02:26:26 +01:00
|
|
|
case 3:
|
2011-10-17 19:52:49 +02:00
|
|
|
hsl_input[2]->SetValue(slider->GetY());
|
|
|
|
UpdateFromHSL(false);
|
2006-01-16 22:02:54 +01:00
|
|
|
break;
|
2006-03-16 02:26:26 +01:00
|
|
|
case 4:
|
2011-10-17 19:52:49 +02:00
|
|
|
hsv_input[0]->SetValue(slider->GetY());
|
|
|
|
UpdateFromHSV(false);
|
2006-01-16 22:02:54 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DialogColorPicker::OnRecentSelect(wxCommandEvent &evt)
|
|
|
|
{
|
2007-07-05 00:16:24 +02:00
|
|
|
// The colour picked is stored in the event string
|
|
|
|
// Allows this event handler to be shared by recent and dropper controls
|
|
|
|
// Ugly hack?
|
2006-01-16 22:02:54 +01:00
|
|
|
AssColor color;
|
2007-01-18 07:45:55 +01:00
|
|
|
color.Parse(evt.GetString());
|
2006-01-16 22:02:54 +01:00
|
|
|
SetColor(color.GetWXColor());
|
|
|
|
}
|
|
|
|
|
2007-07-05 00:16:24 +02:00
|
|
|
void DialogColorPicker::OnDropperMouse(wxMouseEvent &evt)
|
|
|
|
{
|
2007-07-05 01:47:20 +02:00
|
|
|
if (evt.LeftDown() && !screen_dropper_icon->HasCapture()) {
|
2007-07-05 00:16:24 +02:00
|
|
|
#ifdef WIN32
|
2011-09-28 21:43:11 +02:00
|
|
|
screen_dropper_icon->SetCursor(wxCursor("eyedropper_cursor"));
|
2007-07-05 00:16:24 +02:00
|
|
|
#else
|
2007-07-05 01:47:20 +02:00
|
|
|
screen_dropper_icon->SetCursor(*wxCROSS_CURSOR);
|
2007-07-05 00:16:24 +02:00
|
|
|
#endif
|
2007-07-05 01:47:20 +02:00
|
|
|
screen_dropper_icon->SetBitmap(wxNullBitmap);
|
2010-01-12 04:19:49 +01:00
|
|
|
screen_dropper_icon->CaptureMouse();
|
|
|
|
eyedropper_grab_point = evt.GetPosition();
|
|
|
|
eyedropper_is_grabbed = false;
|
2007-07-05 00:16:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (evt.LeftUp()) {
|
|
|
|
wxPoint ptdiff = evt.GetPosition() - eyedropper_grab_point;
|
2011-10-17 19:52:49 +02:00
|
|
|
bool release_now = eyedropper_is_grabbed || abs(ptdiff.x) + abs(ptdiff.y) > 7;
|
2007-07-05 01:47:20 +02:00
|
|
|
if (release_now) {
|
|
|
|
screen_dropper_icon->ReleaseMouse();
|
|
|
|
eyedropper_is_grabbed = false;
|
|
|
|
screen_dropper_icon->SetCursor(wxNullCursor);
|
|
|
|
screen_dropper_icon->SetBitmap(eyedropper_bitmap);
|
|
|
|
} else {
|
|
|
|
eyedropper_is_grabbed = true;
|
|
|
|
}
|
2007-07-05 00:16:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (screen_dropper_icon->HasCapture()) {
|
|
|
|
wxPoint scrpos = screen_dropper_icon->ClientToScreen(evt.GetPosition());
|
|
|
|
screen_dropper->DropFromScreenXY(scrpos.x, scrpos.y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-12 04:19:49 +01:00
|
|
|
/// @brief Hack to redirect events to the screen dropper icon
|
|
|
|
void DialogColorPicker::OnMouse(wxMouseEvent &evt)
|
|
|
|
{
|
|
|
|
if (screen_dropper_icon->HasCapture()) {
|
|
|
|
wxPoint dropper_pos = screen_dropper_icon->ScreenToClient(ClientToScreen(evt.GetPosition()));
|
|
|
|
evt.m_x = dropper_pos.x;
|
|
|
|
evt.m_y = dropper_pos.y;
|
|
|
|
screen_dropper_icon->GetEventHandler()->ProcessEvent(evt);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
evt.Skip();
|
|
|
|
}
|