Could anyone explain the difference between these two methods?
Why I'm asking. I've got custom button with overloaded OnPaint function.
.h file
Code: Select all
#pragma once
#include <memory>
#include <wx/wx.h>
#include "wxCustomControl.h"
class wxCustomButtonDrawerInterface;
class wxCustomButton: public wxCustomControl
{
public:
wxCustomButton(wxWindow* parent, wxWindowID id, std::unique_ptr<wxCustomButtonDrawerInterface>&& drawer, const wxSize& size = wxDefaultSize);
virtual ~wxCustomButton();
bool Enable(bool enable /* = true */) override;
void SetLabel(const wxString& rsLabel) override;
protected:
void DrawInternal(wxDC& dc, wxWindow* drawer) override;
void DrawBackground(wxDC& dc, const wxRect& rect) override;
wxSize DoGetBestSize() const override;
public:
void OnSize(wxSizeEvent& event);
void OnMouseEnter(wxMouseEvent& event);
void OnMouseLeave(wxMouseEvent& event);
void OnMouseDown(wxMouseEvent& event);
void OnMouseUp(wxMouseEvent& event);
void OnMouseCaptureLost(wxMouseCaptureLostEvent& event);
void OnButton(wxMouseEvent& event);
protected:
virtual void OnButtonPressed();
private:
bool m_pressed;
bool m_hovered;
private:
std::unique_ptr<wxCustomButtonDrawerInterface> m_drawer;
};
Code: Select all
#include "stdafx.h"
#include "wxCustomButton.h"
#include "wxUtils.h"
#include "wxCustomButtonDrawerInterface.h"
#include "wxDrawUtils.h"
namespace {
wxCursor handCursor = wxCursor(wxCURSOR_HAND);
}
wxCustomButton::wxCustomButton(wxWindow* parent, wxWindowID id, std::unique_ptr<wxCustomButtonDrawerInterface>&& drawer, const wxSize& size)
: wxCustomControl(parent, id, wxDefaultPosition, size)
, m_pressed(false)
, m_hovered(false)
, m_drawer(std::move(drawer))
{
m_drawer->SetParent(this);
Bind(wxEVT_SIZE, &wxCustomButton::OnSize, this);
Bind(wxEVT_MOUSE_CAPTURE_LOST, &wxCustomButton::OnMouseCaptureLost, this);
Bind(wxEVT_ENTER_WINDOW, &wxCustomButton::OnMouseEnter, this);
Bind(wxEVT_LEAVE_WINDOW, &wxCustomButton::OnMouseLeave, this);
Bind(wxEVT_LEFT_DOWN, &wxCustomButton::OnMouseDown, this);
Bind(wxEVT_LEFT_UP, &wxCustomButton::OnMouseUp, this);
SetCursor(handCursor);
}
wxCustomButton::~wxCustomButton()
{}
bool wxCustomButton::Enable(bool enable /* = true */)
{
auto result = wxWindowBase::Enable(enable);
if (result)
{
Refresh();
Update();
}
return result;
}
void wxCustomButton::SetLabel(const wxString& rsLabel)
{
wxCustomControl::SetLabel(rsLabel);
Refresh();
}
void wxCustomButton::DrawInternal(wxDC& dc, wxWindow* drawer)
{
wxRect rect = GetControlRect(drawer);
auto state = ButtonState::Default;
if (IsEnabled())
{
if (m_pressed)
{
state = ButtonState::Pressed;
}
else if (m_hovered)
{
state = ButtonState::Hovered;
}
}
else
{
state = ButtonState::Disabled;
}
m_drawer->Draw(dc, rect, state);
}
void wxCustomButton::DrawBackground(wxDC& dc, const wxRect& rect)
{}
wxSize wxCustomButton::DoGetBestSize() const
{
auto size = m_drawer->CalculateBestSize();
if (size == wxDefaultSize)
{
size = wxButton::GetDefaultSize();
}
return size;
}
void wxCustomButton::OnSize(wxSizeEvent& event)
{
Layout();
}
void wxCustomButton::OnMouseEnter(wxMouseEvent&)
{
m_hovered = true;
Refresh();
}
void wxCustomButton::OnMouseLeave(wxMouseEvent&)
{
m_hovered = false;
m_pressed = false;
Refresh();
}
void wxCustomButton::OnMouseDown(wxMouseEvent&)
{
if (!m_pressed)
{
m_pressed = true;
Refresh();
Update();
}
}
void wxCustomButton::OnMouseUp(wxMouseEvent&)
{
if (m_pressed)
{
m_pressed = false;
Refresh();
Update();
OnButtonPressed();
}
}
void wxCustomButton::OnMouseCaptureLost(wxMouseCaptureLostEvent& event)
{
m_pressed = false;
m_hovered = false;
if (HasCapture())
{
ReleaseMouse();
}
Refresh();
}
void wxCustomButton::OnButtonPressed()
{
auto event = new wxCommandEvent(wxEVT_BUTTON, GetId());
wxQueueEvent(this, event);
}
void wxCustomButton::OnButton(wxMouseEvent& event)
{
m_pressed = true;
Refresh();
Update();
OnButtonPressed();
m_pressed = false;
}
Inside of wxEVT_BUTTON handler some checks are executed and message dialog box is shown in case of error. The problem is in following:
When I create dialog like
Code: Select all
wxDialog dlg(m_parent, wxID_ANY, APP_TITLE_MSG);
dlg.ShowModal();
When I show error message as
Code: Select all
wxMessageDialog dlg(m_parent, APP_TITLE_MSG, PASSWORD_REQUIRED, wxOK | wxICON_ERROR);
dlg.ShowModal();
So the main question is why the behavior differs and how to make it work with wxDialog.
I think, that in case of wxDialog dialog is shown before wxCustomButton::DrawInternal is called. Thus IsEnabled() returns false (because IsEnabled() checks if parent is enabled as well) and button is painted as disabled. How to fix my code to make it work properly with wxDialog?
P.S. wxWidgets 3.1.1; OS: Windows 8.1
P.P.S. The whole code (with entire inheritance model) is too complex so some classes (that I believe doesn't needed here) isn't present here.
Thanks.