From 7399fb3428aea2a258604ee64b1182bf4e263cfe Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Sat, 24 Oct 2015 11:45:57 +0200 Subject: [PATCH 1/9] Optimize wxGenericColourDialog Variable to hold the size of the custom colour box doesn't need to be a member variable since it's used only locally in wxGenericColourDialog::CalculateMeasurements. --- include/wx/generic/colrdlgg.h | 3 --- src/generic/colrdlgg.cpp | 11 +++++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/include/wx/generic/colrdlgg.h b/include/wx/generic/colrdlgg.h index 4399baa436..91eb2309e4 100644 --- a/include/wx/generic/colrdlgg.h +++ b/include/wx/generic/colrdlgg.h @@ -77,9 +77,6 @@ protected: // Size of each colour rectangle wxPoint m_smallRectangleSize; - // For single customizable colour - wxPoint m_customRectangleSize; - // Grid spacing (between rectangles) int m_gridSpacing; diff --git a/src/generic/colrdlgg.cpp b/src/generic/colrdlgg.cpp index be1dc18577..fe2c5615db 100644 --- a/src/generic/colrdlgg.cpp +++ b/src/generic/colrdlgg.cpp @@ -204,10 +204,11 @@ void wxGenericColourDialog::OnPaint(wxPaintEvent& WXUNUSED(event)) void wxGenericColourDialog::CalculateMeasurements() { + // For single customizable colour + const wxSize customRectangleSize(40, 40); + m_smallRectangleSize.x = 18; m_smallRectangleSize.y = 14; - m_customRectangleSize.x = 40; - m_customRectangleSize.y = 40; m_gridSpacing = 6; m_sectionSpacing = 15; @@ -224,8 +225,7 @@ void wxGenericColourDialog::CalculateMeasurements() m_singleCustomColourRect.x = m_customColoursRect.width + m_customColoursRect.x + m_sectionSpacing; m_singleCustomColourRect.y = 80; - m_singleCustomColourRect.width = m_customRectangleSize.x; - m_singleCustomColourRect.height = m_customRectangleSize.y; + m_singleCustomColourRect.SetSize(customRectangleSize); m_okButtonX = 10; m_customButtonX = m_singleCustomColourRect.x ; @@ -447,8 +447,7 @@ void wxGenericColourDialog::PaintCustomColour(wxDC& dc) wxBrush *brush = new wxBrush(m_colourData.m_dataColour); dc.SetBrush(*brush); - dc.DrawRectangle( m_singleCustomColourRect.x, m_singleCustomColourRect.y, - m_customRectangleSize.x, m_customRectangleSize.y); + dc.DrawRectangle(m_singleCustomColourRect); dc.SetBrush(wxNullBrush); delete brush; From 3dc013920b7921a69ae291c4bad6c946000871f3 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Sat, 24 Oct 2015 11:57:30 +0200 Subject: [PATCH 2/9] Fix type of member variable in wxGenericColourDialog Variable to hold the size should be of type wxSize, not wxPoint. --- include/wx/generic/colrdlgg.h | 2 +- src/generic/colrdlgg.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/wx/generic/colrdlgg.h b/include/wx/generic/colrdlgg.h index 91eb2309e4..9de93ab7ff 100644 --- a/include/wx/generic/colrdlgg.h +++ b/include/wx/generic/colrdlgg.h @@ -75,7 +75,7 @@ protected: wxRect m_singleCustomColourRect; // Size of each colour rectangle - wxPoint m_smallRectangleSize; + wxSize m_smallRectangleSize; // Grid spacing (between rectangles) int m_gridSpacing; diff --git a/src/generic/colrdlgg.cpp b/src/generic/colrdlgg.cpp index fe2c5615db..f2a1ab96fe 100644 --- a/src/generic/colrdlgg.cpp +++ b/src/generic/colrdlgg.cpp @@ -207,8 +207,7 @@ void wxGenericColourDialog::CalculateMeasurements() // For single customizable colour const wxSize customRectangleSize(40, 40); - m_smallRectangleSize.x = 18; - m_smallRectangleSize.y = 14; + m_smallRectangleSize.Set(18, 14); m_gridSpacing = 6; m_sectionSpacing = 15; From 809a07a65d9c38fed0d6c35b6addc160a9a197ac Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Tue, 27 Oct 2015 10:02:51 +0100 Subject: [PATCH 3/9] Add opacity control feature to wxColourData. Added internal flag (with corresponding accessors) which purpose is to enable/disable modifying the opacity of the colours in colour dialogs. --- include/wx/colourdata.h | 5 +++++ src/common/colourdata.cpp | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/wx/colourdata.h b/include/wx/colourdata.h index dfaab13f26..d05a9a37b4 100644 --- a/include/wx/colourdata.h +++ b/include/wx/colourdata.h @@ -26,6 +26,8 @@ public: void SetChooseFull(bool flag) { m_chooseFull = flag; } bool GetChooseFull() const { return m_chooseFull; } + void SetChooseAlpha(bool flag) { m_chooseAlpha = flag; } + bool GetChooseAlpha() const { return m_chooseAlpha; } void SetColour(const wxColour& colour) { m_dataColour = colour; } const wxColour& GetColour() const { return m_dataColour; } wxColour& GetColour() { return m_dataColour; } @@ -45,6 +47,9 @@ public: wxColour m_custColours[NUM_CUSTOM]; bool m_chooseFull; +protected: + bool m_chooseAlpha; + wxDECLARE_DYNAMIC_CLASS(wxColourData); }; diff --git a/src/common/colourdata.cpp b/src/common/colourdata.cpp index 1748076863..3ad774195f 100644 --- a/src/common/colourdata.cpp +++ b/src/common/colourdata.cpp @@ -25,6 +25,7 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxColourData, wxObject); wxColourData::wxColourData() { m_chooseFull = false; + m_chooseAlpha = false; m_dataColour.Set(0,0,0); // m_custColours are wxNullColours initially } @@ -61,6 +62,7 @@ wxColourData& wxColourData::operator=(const wxColourData& data) m_dataColour = data.m_dataColour; m_chooseFull = data.m_chooseFull; + m_chooseAlpha = data.m_chooseAlpha; return *this; } @@ -85,6 +87,9 @@ wxString wxColourData::ToString() const str += clr.GetAsString(wxC2S_HTML_SYNTAX); } + str.Append(wxCOL_DATA_SEP); + str.Append(m_chooseAlpha ? '1' : '0'); + return str; } @@ -102,6 +107,14 @@ bool wxColourData::FromString(const wxString& str) else success = m_custColours[i].Set(token); } + + if ( success ) + { + token = tokenizer.GetNextToken(); + m_chooseAlpha = token == wxS("1"); + success = m_chooseAlpha || token == wxS("0"); + } + return success; } From 880ad7f6f8741d76de98da157cb5e92a1873513d Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Thu, 29 Oct 2015 09:28:04 +0100 Subject: [PATCH 4/9] Add alpha channel support to wxGenericColourDialog. Added opacity slider and custom colours (with alpha) previews (implemented with wxStaticBitmap controls). This feature is controlled by wxColourData::GetChooseAlpha(). --- include/wx/generic/colrdlgg.h | 35 +++-- src/generic/colrdlgg.cpp | 247 ++++++++++++++++++++++++++++++---- 2 files changed, 246 insertions(+), 36 deletions(-) diff --git a/include/wx/generic/colrdlgg.h b/include/wx/generic/colrdlgg.h index 9de93ab7ff..086ce5b25b 100644 --- a/include/wx/generic/colrdlgg.h +++ b/include/wx/generic/colrdlgg.h @@ -14,18 +14,18 @@ #include "wx/gdicmn.h" #include "wx/dialog.h" -#define wxID_ADD_CUSTOM 3000 - #if wxUSE_SLIDER - - #define wxID_RED_SLIDER 3001 - #define wxID_GREEN_SLIDER 3002 - #define wxID_BLUE_SLIDER 3003 - class WXDLLIMPEXP_FWD_CORE wxSlider; - #endif // wxUSE_SLIDER +// Preview with opacity is possible only +// if wxGCDC and wxStaticBitmap are available. +#define wxCLRDLGG_USE_PREVIEW_WITH_ALPHA (wxUSE_GRAPHICS_CONTEXT && wxUSE_STATBMP) + +#if wxCLRDLGG_USE_PREVIEW_WITH_ALPHA +class wxStaticBitmap; +#endif // wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + class WXDLLIMPEXP_CORE wxGenericColourDialog : public wxDialog { public: @@ -43,13 +43,18 @@ public: // Internal functions void OnMouseEvent(wxMouseEvent& event); void OnPaint(wxPaintEvent& event); +#if wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + void OnCustomColourMouseClick(wxMouseEvent& event); +#endif // wxCLRDLGG_USE_PREVIEW_WITH_ALPHA virtual void CalculateMeasurements(); virtual void CreateWidgets(); virtual void InitializeColours(); virtual void PaintBasicColours(wxDC& dc); - virtual void PaintCustomColours(wxDC& dc); +#if !wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + virtual void PaintCustomColours(wxDC& dc, int clrIndex = -1); +#endif // !wxCLRDLGG_USE_PREVIEW_WITH_ALPHA virtual void PaintCustomColour(wxDC& dc); virtual void PaintHighlight(wxDC& dc, bool draw); @@ -62,10 +67,15 @@ public: void OnRedSlider(wxCommandEvent& event); void OnGreenSlider(wxCommandEvent& event); void OnBlueSlider(wxCommandEvent& event); + void OnAlphaSlider(wxCommandEvent& event); #endif // wxUSE_SLIDER void OnCloseWindow(wxCloseEvent& event); +#if wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + void DoPreviewBitmap(wxBitmap& bmp, const wxColour& colour); +#endif // wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + protected: wxColourData m_colourData; @@ -97,7 +107,14 @@ protected: wxSlider *m_redSlider; wxSlider *m_greenSlider; wxSlider *m_blueSlider; + wxSlider *m_alphaSlider; #endif // wxUSE_SLIDER +#if wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + // Bitmap to preview selected colour (with alpha channel) + wxStaticBitmap *m_customColourBmp; + // Bitmaps to preview custom colours (with alpha channel) + wxStaticBitmap *m_customColoursBmp[16]; +#endif // wxCLRDLGG_USE_PREVIEW_WITH_ALPHA int m_buttonY; diff --git a/src/generic/colrdlgg.cpp b/src/generic/colrdlgg.cpp index f2a1ab96fe..ab5cb71e98 100644 --- a/src/generic/colrdlgg.cpp +++ b/src/generic/colrdlgg.cpp @@ -37,6 +37,19 @@ #include "wx/colourdata.h" #include "wx/generic/colrdlgg.h" +#if wxCLRDLGG_USE_PREVIEW_WITH_ALPHA +#include "wx/statbmp.h" +#include "wx/dcmemory.h" +#include "wx/dcgraph.h" +#endif // wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + +#define wxID_ADD_CUSTOM 3000 +#if wxUSE_SLIDER + #define wxID_RED_SLIDER 3001 + #define wxID_GREEN_SLIDER 3002 + #define wxID_BLUE_SLIDER 3003 +#endif // wxUSE_SLIDER + wxIMPLEMENT_DYNAMIC_CLASS(wxGenericColourDialog, wxDialog); wxBEGIN_EVENT_TABLE(wxGenericColourDialog, wxDialog) @@ -164,7 +177,7 @@ int wxGenericColourDialog::ShowModal() // Internal functions void wxGenericColourDialog::OnMouseEvent(wxMouseEvent& event) { - if (event.ButtonDown(1)) + if (event.ButtonDown(wxMOUSE_BTN_LEFT)) { int x = (int)event.GetX(); int y = (int)event.GetY(); @@ -177,6 +190,8 @@ void wxGenericColourDialog::OnMouseEvent(wxMouseEvent& event) int ptr = (int)(selX + selY*8); OnBasicColourClick(ptr); } + // wxStaticBitmap (used to ARGB preview) events are handled in the dedicated handler. +#if !wxCLRDLGG_USE_PREVIEW_WITH_ALPHA else if ((x >= m_customColoursRect.x && x <= (m_customColoursRect.x + m_customColoursRect.width)) && (y >= m_customColoursRect.y && y <= (m_customColoursRect.y + m_customColoursRect.height))) { @@ -185,6 +200,7 @@ void wxGenericColourDialog::OnMouseEvent(wxMouseEvent& event) int ptr = (int)(selX + selY*8); OnCustomColourClick(ptr); } +#endif else event.Skip(); } @@ -192,13 +208,34 @@ void wxGenericColourDialog::OnMouseEvent(wxMouseEvent& event) event.Skip(); } +#if wxCLRDLGG_USE_PREVIEW_WITH_ALPHA +void wxGenericColourDialog::OnCustomColourMouseClick(wxMouseEvent& event) +{ + // Find index of custom colour + // and call the handler. + for (int i = 0; i < WXSIZEOF(m_customColoursBmp); i++) + { + if ( m_customColoursBmp[i]->GetId() == event.GetId() ) + { + OnCustomColourClick(i); + return; + } + } + + event.Skip(); +} +#endif // wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + void wxGenericColourDialog::OnPaint(wxPaintEvent& WXUNUSED(event)) { wxPaintDC dc(this); PaintBasicColours(dc); - PaintCustomColours(dc); + // wxStaticBitmap controls are updated on their own. +#if !wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + PaintCustomColours(dc, -1); PaintCustomColour(dc); +#endif // !wxCLRDLGG_USE_PREVIEW_WITH_ALPHA PaintHighlight(dc, true); } @@ -235,6 +272,33 @@ void wxGenericColourDialog::CreateWidgets() { wxBeginBusyCursor(); +#if wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + // Bitmap to preview selected colour (with alpha channel) + wxBitmap customColourBmp(m_singleCustomColourRect.GetSize(), 32); + customColourBmp.UseAlpha(); + DoPreviewBitmap(customColourBmp, m_colourData.GetColour()); + m_customColourBmp = new wxStaticBitmap(this, wxID_ANY, customColourBmp, + m_singleCustomColourRect.GetLeftTop(), + m_singleCustomColourRect.GetSize(), + wxBORDER_SUNKEN); + + // 16 bitmaps to preview custom colours (with alpha channel) + for (int i = 0; i < WXSIZEOF(m_customColoursBmp); i++) + { + int x = ((i % 8)*(m_smallRectangleSize.x+m_gridSpacing)) + m_customColoursRect.x; + int y = ((i / 8)*(m_smallRectangleSize.y+m_gridSpacing)) + m_customColoursRect.y; + + wxBitmap bmp(m_smallRectangleSize, 32); + bmp.UseAlpha(); + DoPreviewBitmap(bmp, m_customColours[i]); + m_customColoursBmp[i] = new wxStaticBitmap(this, wxID_ANY, bmp, + wxPoint(x, y), m_smallRectangleSize); + m_customColoursBmp[i]->Bind(wxEVT_LEFT_DOWN, + &wxGenericColourDialog::OnCustomColourMouseClick, this); + + } +#endif // wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL ); const int sliderHeight = 160; @@ -249,6 +313,16 @@ void wxGenericColourDialog::CreateWidgets() wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE); m_blueSlider = new wxSlider(this, wxID_BLUE_SLIDER, m_colourData.m_dataColour.Blue(), 0, 255, wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE); + if ( m_colourData.GetChooseAlpha() ) + { + m_alphaSlider = new wxSlider(this, wxID_ANY, m_colourData.m_dataColour.Alpha(), 0, 255, + wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE); + m_alphaSlider->Bind(wxEVT_SLIDER, &wxGenericColourDialog::OnAlphaSlider, this); + } + else + { + m_alphaSlider = NULL; + } wxBoxSizer *sliderSizer = new wxBoxSizer( wxHORIZONTAL ); @@ -260,6 +334,10 @@ void wxGenericColourDialog::CreateWidgets() sliderSizer->Add(m_redSlider, sliderFlags); sliderSizer->Add(m_greenSlider, sliderFlags); sliderSizer->Add(m_blueSlider, sliderFlags); + if ( m_colourData.GetChooseAlpha() ) + { + sliderSizer->Add(m_alphaSlider, sliderFlags); + } topSizer->Add(sliderSizer, wxSizerFlags().Centre().DoubleBorder()); #else @@ -370,28 +448,37 @@ void wxGenericColourDialog::PaintBasicColours(wxDC& dc) } } -void wxGenericColourDialog::PaintCustomColours(wxDC& dc) +#if !wxCLRDLGG_USE_PREVIEW_WITH_ALPHA +void wxGenericColourDialog::PaintCustomColours(wxDC& dc, int clrIndex) { - int i; - for (i = 0; i < 2; i++) - { - int j; - for (j = 0; j < 8; j++) + int idxStart; + int idxEnd; + // For clrIndex == -1 redraw all custom colours + if ( clrIndex < 0 || clrIndex >= WXSIZEOF(m_customColours) ) { - int ptr = i*8 + j; - - int x = (j*(m_smallRectangleSize.x+m_gridSpacing)) + m_customColoursRect.x; - int y = (i*(m_smallRectangleSize.y+m_gridSpacing)) + m_customColoursRect.y; - - dc.SetPen(*wxBLACK_PEN); - - wxBrush brush(m_customColours[ptr]); - dc.SetBrush(brush); - - dc.DrawRectangle( x, y, m_smallRectangleSize.x, m_smallRectangleSize.y); + idxStart = 0; + idxEnd = WXSIZEOF(m_customColours) - 1; + } + else + { + idxStart = clrIndex; + idxEnd = clrIndex; + } + + for (int i = idxStart; i <= idxEnd; i++) + { + int x = ((i % 8)*(m_smallRectangleSize.x+m_gridSpacing)) + m_customColoursRect.x; + int y = ((i / 8)*(m_smallRectangleSize.y+m_gridSpacing)) + m_customColoursRect.y; + + dc.SetPen(*wxBLACK_PEN); + + wxBrush brush(m_customColours[i]); + dc.SetBrush(brush); + + dc.DrawRectangle(x, y, m_smallRectangleSize.x, m_smallRectangleSize.y); } - } } +#endif // !wxCLRDLGG_USE_PREVIEW_WITH_ALPHA void wxGenericColourDialog::PaintHighlight(wxDC& dc, bool draw) { @@ -441,6 +528,14 @@ void wxGenericColourDialog::PaintHighlight(wxDC& dc, bool draw) void wxGenericColourDialog::PaintCustomColour(wxDC& dc) { +#if wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + wxUnusedVar(dc); + + wxBitmap bmp(m_singleCustomColourRect.GetSize(), 32); + bmp.UseAlpha(); + DoPreviewBitmap(bmp, m_colourData.GetColour()); + m_customColourBmp->SetBitmap(bmp); +#else dc.SetPen(*wxBLACK_PEN); wxBrush *brush = new wxBrush(m_colourData.m_dataColour); @@ -450,6 +545,7 @@ void wxGenericColourDialog::PaintCustomColour(wxDC& dc) dc.SetBrush(wxNullBrush); delete brush; +#endif // wxCLRDLGG_USE_PREVIEW_WITH_ALPHA/!wxCLRDLGG_USE_PREVIEW_WITH_ALPHA } void wxGenericColourDialog::OnBasicColourClick(int which) @@ -464,11 +560,16 @@ void wxGenericColourDialog::OnBasicColourClick(int which) m_redSlider->SetValue( m_standardColours[m_colourSelection].Red() ); m_greenSlider->SetValue( m_standardColours[m_colourSelection].Green() ); m_blueSlider->SetValue( m_standardColours[m_colourSelection].Blue() ); + if ( m_colourData.GetChooseAlpha() ) + { + m_alphaSlider->SetValue( m_standardColours[m_colourSelection].Alpha() ); + } #endif // wxUSE_SLIDER m_colourData.m_dataColour.Set(m_standardColours[m_colourSelection].Red(), m_standardColours[m_colourSelection].Green(), - m_standardColours[m_colourSelection].Blue()); + m_standardColours[m_colourSelection].Blue(), + m_standardColours[m_colourSelection].Alpha()); PaintCustomColour(dc); PaintHighlight(dc, true); @@ -485,11 +586,16 @@ void wxGenericColourDialog::OnCustomColourClick(int which) m_redSlider->SetValue( m_customColours[m_colourSelection].Red() ); m_greenSlider->SetValue( m_customColours[m_colourSelection].Green() ); m_blueSlider->SetValue( m_customColours[m_colourSelection].Blue() ); + if ( m_colourData.GetChooseAlpha() ) + { + m_alphaSlider->SetValue( m_customColours[m_colourSelection].Alpha() ); + } #endif // wxUSE_SLIDER m_colourData.m_dataColour.Set(m_customColours[m_colourSelection].Red(), m_customColours[m_colourSelection].Green(), - m_customColours[m_colourSelection].Blue()); + m_customColours[m_colourSelection].Blue(), + m_customColours[m_colourSelection].Alpha()); PaintCustomColour(dc); PaintHighlight(dc, true); @@ -521,11 +627,19 @@ void wxGenericColourDialog::OnAddCustom(wxCommandEvent& WXUNUSED(event)) m_customColours[m_colourSelection].Set(m_colourData.m_dataColour.Red(), m_colourData.m_dataColour.Green(), - m_colourData.m_dataColour.Blue()); + m_colourData.m_dataColour.Blue(), + m_colourData.m_dataColour.Alpha()); m_colourData.SetCustomColour(m_colourSelection, m_customColours[m_colourSelection]); - PaintCustomColours(dc); +#if wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + wxBitmap bmp(m_smallRectangleSize, 32); + bmp.UseAlpha(); + DoPreviewBitmap(bmp, m_customColours[m_colourSelection]); + m_customColoursBmp[m_colourSelection]->SetBitmap(bmp); +#else + PaintCustomColours(dc, m_colourSelection); +#endif // wxCLRDLGG_USE_PREVIEW_WITH_ALPHA/!wxCLRDLGG_USE_PREVIEW_WITH_ALPHA } #if wxUSE_SLIDER @@ -536,7 +650,8 @@ void wxGenericColourDialog::OnRedSlider(wxCommandEvent& WXUNUSED(event)) return; wxClientDC dc(this); - m_colourData.m_dataColour.Set((unsigned char)m_redSlider->GetValue(), m_colourData.m_dataColour.Green(), m_colourData.m_dataColour.Blue()); + m_colourData.m_dataColour.Set((unsigned char)m_redSlider->GetValue(), m_colourData.m_dataColour.Green(), m_colourData.m_dataColour.Blue(), + m_colourData.m_dataColour.Alpha()); PaintCustomColour(dc); } @@ -546,7 +661,8 @@ void wxGenericColourDialog::OnGreenSlider(wxCommandEvent& WXUNUSED(event)) return; wxClientDC dc(this); - m_colourData.m_dataColour.Set(m_colourData.m_dataColour.Red(), (unsigned char)m_greenSlider->GetValue(), m_colourData.m_dataColour.Blue()); + m_colourData.m_dataColour.Set(m_colourData.m_dataColour.Red(), (unsigned char)m_greenSlider->GetValue(), m_colourData.m_dataColour.Blue(), + m_colourData.m_dataColour.Alpha()); PaintCustomColour(dc); } @@ -556,10 +672,87 @@ void wxGenericColourDialog::OnBlueSlider(wxCommandEvent& WXUNUSED(event)) return; wxClientDC dc(this); - m_colourData.m_dataColour.Set(m_colourData.m_dataColour.Red(), m_colourData.m_dataColour.Green(), (unsigned char)m_blueSlider->GetValue()); + m_colourData.m_dataColour.Set(m_colourData.m_dataColour.Red(), m_colourData.m_dataColour.Green(), (unsigned char)m_blueSlider->GetValue(), + m_colourData.m_dataColour.Alpha()); PaintCustomColour(dc); } +void wxGenericColourDialog::OnAlphaSlider(wxCommandEvent& WXUNUSED(event)) +{ + wxColour c(m_colourData.GetColour().Red(), m_colourData.GetColour().Green(), m_colourData.GetColour().Blue(), + (unsigned char)m_alphaSlider->GetValue()); + m_colourData.SetColour(c); + + wxClientDC dc(this); + PaintCustomColour(dc); +} + #endif // wxUSE_SLIDER +#if wxCLRDLGG_USE_PREVIEW_WITH_ALPHA +void wxGenericColourDialog::DoPreviewBitmap(wxBitmap& bmp, const wxColour& colour) +{ + if ( bmp.HasAlpha() && colour.Alpha() != wxALPHA_OPAQUE ) + { + // For real ARGB draw a chessboard grid + // with actual ARGB fields and reference RGB fields. + const int w = bmp.GetWidth(); + const int h = bmp.GetHeight(); + + // Calculate field size: 4 fields per row/column, + // with size in range [2..10] + int dx = wxMax(wxMin(w / 4, 10), 2); + int dy = wxMax(wxMin(h / 4, 10), 2); + // We want a square field + dx = wxMax(dx, dy); + dy = dx; + + // Prepare opaque colour + wxColour colourRGB(colour.Red(), colour.Green(), colour.Blue(), wxALPHA_OPAQUE); + + { + wxBrush brushARGB(colour); + wxBrush brushRGB(colourRGB); + + wxMemoryDC mdc(bmp); + { + wxGCDC gdc(mdc); + + gdc.SetPen(*wxTRANSPARENT_PEN); + + for (int x = 0, ix = 0; x < w; x += dx, ix++) + { + for (int y = 0, iy = 0; y < h; y += dy, iy++) + { + if ( (ix+iy) % 2 == 0 ) + { + gdc.SetBrush(brushARGB); + } + else + { + gdc.SetBrush(brushRGB); + } + gdc.DrawRectangle(x, y, dx, dy); + } + } + + // Draw a frame + gdc.SetPen(*wxBLACK_PEN); + gdc.SetBrush(*wxTRANSPARENT_BRUSH); + gdc.DrawRectangle(0, 0, w, h); + } + } + } + else + { + wxMemoryDC mdc(bmp); + // Fill with custom colour + wxBrush brush(colour); + mdc.SetPen(*wxBLACK_PEN); + mdc.SetBrush(brush); + mdc.DrawRectangle(wxPoint(0, 0), bmp.GetSize()); + } +} +#endif // wxCLRDLGG_USE_PREVIEW_WITH_ALPHA + #endif // wxUSE_COLOURDLG From fa7c2de28d9f4c50aabdc9f91b3881d3db255f04 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Thu, 29 Oct 2015 09:28:56 +0100 Subject: [PATCH 5/9] Add slider labels in wxGenericColourDialog. --- src/generic/colrdlgg.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/generic/colrdlgg.cpp b/src/generic/colrdlgg.cpp index ab5cb71e98..cc5e7dd941 100644 --- a/src/generic/colrdlgg.cpp +++ b/src/generic/colrdlgg.cpp @@ -328,15 +328,30 @@ void wxGenericColourDialog::CreateWidgets() sliderSizer->Add(sliderX, sliderHeight ); + const wxSizerFlags sliderLabelFlags = wxSizerFlags().Right().Border(); + const wxSizerFlags onesliderFlags = wxSizerFlags().CenterHorizontal(); const wxSizerFlags sliderFlags = wxSizerFlags().CentreVertical().DoubleBorder(); - sliderSizer->Add(m_redSlider, sliderFlags); - sliderSizer->Add(m_greenSlider, sliderFlags); - sliderSizer->Add(m_blueSlider, sliderFlags); + wxBoxSizer *redSliderSizer = new wxBoxSizer(wxVERTICAL); + redSliderSizer->Add(new wxStaticText(this, wxID_ANY, _("Red:")), sliderLabelFlags); + redSliderSizer->Add(m_redSlider, onesliderFlags); + wxBoxSizer *greenSliderSizer = new wxBoxSizer(wxVERTICAL); + greenSliderSizer->Add(new wxStaticText(this, wxID_ANY, _("Green:")), sliderLabelFlags); + greenSliderSizer->Add(m_greenSlider, onesliderFlags); + wxBoxSizer *blueSliderSizer = new wxBoxSizer(wxVERTICAL); + blueSliderSizer->Add(new wxStaticText(this, wxID_ANY, _("Blue:")), sliderLabelFlags); + blueSliderSizer->Add(m_blueSlider, onesliderFlags); + + sliderSizer->Add(redSliderSizer, sliderFlags); + sliderSizer->Add(greenSliderSizer, sliderFlags); + sliderSizer->Add(blueSliderSizer, sliderFlags); if ( m_colourData.GetChooseAlpha() ) - { - sliderSizer->Add(m_alphaSlider, sliderFlags); + { + wxBoxSizer *alphaSliderSizer = new wxBoxSizer(wxVERTICAL); + alphaSliderSizer->Add(new wxStaticText(this, wxID_ANY, _("Opacity:")), sliderLabelFlags); + alphaSliderSizer->Add(m_alphaSlider, onesliderFlags); + sliderSizer->Add(alphaSliderSizer, sliderFlags); } topSizer->Add(sliderSizer, wxSizerFlags().Centre().DoubleBorder()); From 8fee6a9a2bd35cb3044463dd3cb2badb93cded67 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Thu, 29 Oct 2015 09:29:46 +0100 Subject: [PATCH 6/9] Modify dialogs sample to present also generic colour dialog with alpha support. Added separate submenu and menu items to show generic colour dialogs with opacity control enabled/disabled. --- samples/dialogs/dialogs.cpp | 9 +++++++-- samples/dialogs/dialogs.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index ec3f4ab0bc..b31c00629c 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -221,6 +221,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) #if USE_COLOURDLG_GENERIC EVT_MENU(DIALOGS_CHOOSE_COLOUR_GENERIC, MyFrame::ChooseColourGeneric) + EVT_MENU(DIALOGS_CHOOSE_COLOUR_GENERIC_ALPHA, MyFrame::ChooseColourGeneric) #endif // USE_COLOURDLG_GENERIC #if wxUSE_PROGRESSDLG @@ -400,7 +401,10 @@ bool MyApp::OnInit() #endif // USE_COLOURDLG_GENERIC || USE_FONTDLG_GENERIC #if USE_COLOURDLG_GENERIC - choices_menu->Append(DIALOGS_CHOOSE_COLOUR_GENERIC, wxT("&Choose colour (generic)")); + wxMenu *colourGeneric_menu = new wxMenu; + colourGeneric_menu->Append(DIALOGS_CHOOSE_COLOUR_GENERIC, wxT("&No opacity")); + colourGeneric_menu->Append(DIALOGS_CHOOSE_COLOUR_GENERIC_ALPHA, wxT("&With opacity")); + choices_menu->Append(wxID_ANY, wxT("&Choose colour (generic)"), colourGeneric_menu); #endif // USE_COLOURDLG_GENERIC #if USE_FONTDLG_GENERIC @@ -741,12 +745,13 @@ void MyFrame::GetColour(wxCommandEvent& WXUNUSED(event)) #if USE_COLOURDLG_GENERIC -void MyFrame::ChooseColourGeneric(wxCommandEvent& WXUNUSED(event)) +void MyFrame::ChooseColourGeneric(wxCommandEvent& event) { m_clrData.SetColour(m_canvas->GetBackgroundColour()); //FIXME:TODO:This has no effect... m_clrData.SetChooseFull(true); + m_clrData.SetChooseAlpha(event.GetId() == DIALOGS_CHOOSE_COLOUR_GENERIC_ALPHA); for (int i = 0; i < 16; i++) { diff --git a/samples/dialogs/dialogs.h b/samples/dialogs/dialogs.h index bf174f8dbf..3d8647399b 100644 --- a/samples/dialogs/dialogs.h +++ b/samples/dialogs/dialogs.h @@ -536,6 +536,7 @@ enum DIALOGS_CHOOSE_COLOUR = wxID_HIGHEST, DIALOGS_GET_COLOUR, DIALOGS_CHOOSE_COLOUR_GENERIC, + DIALOGS_CHOOSE_COLOUR_GENERIC_ALPHA, DIALOGS_CHOOSE_FONT, DIALOGS_CHOOSE_FONT_GENERIC, DIALOGS_MESSAGE_BOX, From 02c03096b6298a8a27810cb5825428dd210c9d58 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Mon, 2 Nov 2015 21:12:35 +0100 Subject: [PATCH 7/9] Fix initialization of custom colours for generic colour dialogs in dialogs sample. Use number of custom colours taken from wxColourData instead of using explicit numeric value. --- samples/dialogs/dialogs.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index b31c00629c..dfa711bf41 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -753,14 +753,10 @@ void MyFrame::ChooseColourGeneric(wxCommandEvent& event) m_clrData.SetChooseFull(true); m_clrData.SetChooseAlpha(event.GetId() == DIALOGS_CHOOSE_COLOUR_GENERIC_ALPHA); - for (int i = 0; i < 16; i++) + for (int i = 0; i < wxColourData::NUM_CUSTOM; i++) { - wxColour colour( - (unsigned char)(i*16), - (unsigned char)(i*16), - (unsigned char)(i*16) - ); - m_clrData.SetCustomColour(i, colour); + unsigned char n = i*(256/wxColourData::NUM_CUSTOM); + m_clrData.SetCustomColour(i, wxColour(n, n, n)); } wxGenericColourDialog *dialog = new wxGenericColourDialog(this, &m_clrData); From 9409b7eb808de92598fc6d9b8187b9bb5aeff026 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Mon, 2 Nov 2015 21:13:28 +0100 Subject: [PATCH 8/9] Don't use directly wxColourData data members in wxGenericColourDialog. wxColourData data members are public for backwards compatibility only and shouldn't be used directly. --- src/generic/colrdlgg.cpp | 47 ++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/src/generic/colrdlgg.cpp b/src/generic/colrdlgg.cpp index cc5e7dd941..f503201059 100644 --- a/src/generic/colrdlgg.cpp +++ b/src/generic/colrdlgg.cpp @@ -307,15 +307,16 @@ void wxGenericColourDialog::CreateWidgets() #if wxUSE_SLIDER const int sliderX = m_singleCustomColourRect.x + m_singleCustomColourRect.width + m_sectionSpacing; - m_redSlider = new wxSlider(this, wxID_RED_SLIDER, m_colourData.m_dataColour.Red(), 0, 255, + wxColour c = m_colourData.GetColour(); + m_redSlider = new wxSlider(this, wxID_RED_SLIDER, c.Red(), 0, 255, wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE); - m_greenSlider = new wxSlider(this, wxID_GREEN_SLIDER, m_colourData.m_dataColour.Green(), 0, 255, + m_greenSlider = new wxSlider(this, wxID_GREEN_SLIDER, c.Green(), 0, 255, wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE); - m_blueSlider = new wxSlider(this, wxID_BLUE_SLIDER, m_colourData.m_dataColour.Blue(), 0, 255, + m_blueSlider = new wxSlider(this, wxID_BLUE_SLIDER, c.Blue(), 0, 255, wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE); if ( m_colourData.GetChooseAlpha() ) { - m_alphaSlider = new wxSlider(this, wxID_ANY, m_colourData.m_dataColour.Alpha(), 0, 255, + m_alphaSlider = new wxSlider(this, wxID_ANY, c.Alpha(), 0, 255, wxDefaultPosition, wxSize(wxDefaultCoord, sliderHeight), wxSL_VERTICAL|wxSL_LABELS|wxSL_INVERSE); m_alphaSlider->Bind(wxEVT_SLIDER, &wxGenericColourDialog::OnAlphaSlider, this); } @@ -431,13 +432,13 @@ void wxGenericColourDialog::InitializeColours(void) } } } - m_colourData.m_dataColour.Set( curr.Red(), curr.Green(), curr.Blue() ); + m_colourData.SetColour(curr); } else { m_whichKind = 1; m_colourSelection = 0; - m_colourData.m_dataColour.Set( 0, 0, 0 ); + m_colourData.SetColour(wxColour(0, 0, 0)); } } @@ -553,7 +554,7 @@ void wxGenericColourDialog::PaintCustomColour(wxDC& dc) #else dc.SetPen(*wxBLACK_PEN); - wxBrush *brush = new wxBrush(m_colourData.m_dataColour); + wxBrush *brush = new wxBrush(m_colourData.GetColour()); dc.SetBrush(*brush); dc.DrawRectangle(m_singleCustomColourRect); @@ -581,10 +582,7 @@ void wxGenericColourDialog::OnBasicColourClick(int which) } #endif // wxUSE_SLIDER - m_colourData.m_dataColour.Set(m_standardColours[m_colourSelection].Red(), - m_standardColours[m_colourSelection].Green(), - m_standardColours[m_colourSelection].Blue(), - m_standardColours[m_colourSelection].Alpha()); + m_colourData.SetColour(m_standardColours[m_colourSelection]); PaintCustomColour(dc); PaintHighlight(dc, true); @@ -607,10 +605,7 @@ void wxGenericColourDialog::OnCustomColourClick(int which) } #endif // wxUSE_SLIDER - m_colourData.m_dataColour.Set(m_customColours[m_colourSelection].Red(), - m_customColours[m_colourSelection].Green(), - m_customColours[m_colourSelection].Blue(), - m_customColours[m_colourSelection].Alpha()); + m_colourData.SetColour(m_customColours[m_colourSelection]); PaintCustomColour(dc); PaintHighlight(dc, true); @@ -640,10 +635,7 @@ void wxGenericColourDialog::OnAddCustom(wxCommandEvent& WXUNUSED(event)) PaintHighlight(dc, true); } - m_customColours[m_colourSelection].Set(m_colourData.m_dataColour.Red(), - m_colourData.m_dataColour.Green(), - m_colourData.m_dataColour.Blue(), - m_colourData.m_dataColour.Alpha()); + m_customColours[m_colourSelection] = m_colourData.GetColour(); m_colourData.SetCustomColour(m_colourSelection, m_customColours[m_colourSelection]); @@ -665,8 +657,8 @@ void wxGenericColourDialog::OnRedSlider(wxCommandEvent& WXUNUSED(event)) return; wxClientDC dc(this); - m_colourData.m_dataColour.Set((unsigned char)m_redSlider->GetValue(), m_colourData.m_dataColour.Green(), m_colourData.m_dataColour.Blue(), - m_colourData.m_dataColour.Alpha()); + wxColour c = m_colourData.GetColour(); + m_colourData.SetColour(wxColour((unsigned char)m_redSlider->GetValue(), c.Green(), c.Blue(), c.Alpha())); PaintCustomColour(dc); } @@ -676,8 +668,8 @@ void wxGenericColourDialog::OnGreenSlider(wxCommandEvent& WXUNUSED(event)) return; wxClientDC dc(this); - m_colourData.m_dataColour.Set(m_colourData.m_dataColour.Red(), (unsigned char)m_greenSlider->GetValue(), m_colourData.m_dataColour.Blue(), - m_colourData.m_dataColour.Alpha()); + wxColour c = m_colourData.GetColour(); + m_colourData.SetColour(wxColour(c.Red(), (unsigned char)m_greenSlider->GetValue(), c.Blue(), c.Alpha())); PaintCustomColour(dc); } @@ -687,16 +679,15 @@ void wxGenericColourDialog::OnBlueSlider(wxCommandEvent& WXUNUSED(event)) return; wxClientDC dc(this); - m_colourData.m_dataColour.Set(m_colourData.m_dataColour.Red(), m_colourData.m_dataColour.Green(), (unsigned char)m_blueSlider->GetValue(), - m_colourData.m_dataColour.Alpha()); + wxColour c = m_colourData.GetColour(); + m_colourData.SetColour(wxColour(c.Red(), c.Green(), (unsigned char)m_blueSlider->GetValue(), c.Alpha())); PaintCustomColour(dc); } void wxGenericColourDialog::OnAlphaSlider(wxCommandEvent& WXUNUSED(event)) { - wxColour c(m_colourData.GetColour().Red(), m_colourData.GetColour().Green(), m_colourData.GetColour().Blue(), - (unsigned char)m_alphaSlider->GetValue()); - m_colourData.SetColour(c); + wxColour c = m_colourData.GetColour(); + m_colourData.SetColour(wxColour(c.Red(), c.Green(), c.Blue(), (unsigned char)m_alphaSlider->GetValue())); wxClientDC dc(this); PaintCustomColour(dc); From 8aad22b3e299bcf3ed3cc222c35af7b3b432caeb Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Mon, 2 Nov 2015 21:14:10 +0100 Subject: [PATCH 9/9] Update documentation regarding alpha support in wxGenericColourDialog. --- docs/doxygen/overviews/commondialogs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/doxygen/overviews/commondialogs.h b/docs/doxygen/overviews/commondialogs.h index bd05480a1d..4cdf52abd2 100644 --- a/docs/doxygen/overviews/commondialogs.h +++ b/docs/doxygen/overviews/commondialogs.h @@ -48,11 +48,11 @@ controls to select a precise colour, and add it to the custom colour palette. Under non-MS Windows platforms, the colour selector is a simulation of most of the features of the MS Windows selector. Two palettes of 48 standard and 16 -custom colours are presented, with the right-hand area containing three sliders -for the user to select a colour from red, green and blue components. This +custom colours are presented, with the right-hand area containing three or four sliders +for the user to select a colour from red, green, blue and opacity (optionally) components. This colour may be added to the custom colour palette, and will replace either the currently selected custom colour, or the first one in the palette if none is -selected. The RGB colour sliders are not optional in the generic colour +selected. The RGB or ARGB colour sliders are not optional in the generic colour selector. The generic colour selector is also available under MS Windows; use the name wxGenericColourDialog.