Code: Select all
//ModernButton.h
#pragma once
#include <wx/wx.h>
class ModernButton : public wxWindow {
public:
enum class Type {
primary,
danger
};
ModernButton(
Type type,
wxWindow* parent,
wxWindowID id,
const wxString& label = wxEmptyString,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
const wxString& name = wxASCII_STR(wxPanelNameStr)) : m_type(type),
m_text(label),
m_focus(false),
m_hover(false),
wxWindow(parent, id, pos, size, style, name) {
Bind(wxEVT_MOTION, &ModernButton::mouse_moved, this);
Bind(wxEVT_LEAVE_WINDOW, &ModernButton::mouse_left_window, this);
Bind(wxEVT_LEFT_DOWN, &ModernButton::mouse_left_down, this);
Bind(wxEVT_SET_FOCUS, &ModernButton::set_focus, this);
Bind(wxEVT_KILL_FOCUS, &ModernButton::kill_focus, this);
Bind(wxEVT_CHAR_HOOK, &ModernButton::process_enter, this);
Bind(wxEVT_PAINT, &ModernButton::paint_event, this);
SetCursor(wxCursor(wxCURSOR_HAND));
}
private:
bool m_hover;
bool m_focus;
wxString m_text;
Type m_type;
void paint_event(wxPaintEvent&) {
wxPaintDC dc(this);
render(dc);
}
void paint_now() {
wxClientDC dc(this);
render(dc);
}
void render(wxDC& dc) {
wxColour color = wxColour(255, 255, 255);
wxColour background_color;
wxColour background_color_hover;
wxColour border_color;
switch(m_type) {
case Type::primary: {
background_color = wxColour(0, 123, 255);
background_color_hover = wxColour(0, 105, 217);
border_color = wxColour(63, 72, 204);
} break;
case Type::danger: {
background_color = wxColour(235, 0, 0);
background_color_hover = wxColour(225, 0, 0);
border_color = wxColour(200, 0, 0);
} break;
}
if(m_hover || m_focus) {
dc.SetBrush(wxBrush(background_color_hover));
} else {
dc.SetBrush(wxBrush(background_color));
}
auto text_size = dc.GetTextExtent(m_text);
int text_width = text_size.GetWidth();
int text_height = text_size.GetHeight() - 2;
auto button_width = GetSize().GetWidth();
auto button_height = GetSize().GetHeight();
dc.SetPen(wxPen(border_color));
dc.DrawRectangle(0, 0, button_width, button_height);
dc.SetTextForeground(color);
dc.DrawText(m_text, (button_width - text_width) / 2, (button_height - text_height) / 2);
}
void mouse_moved(wxMouseEvent&) {
if(!m_hover) {
m_hover = true;
paint_now();
}
}
void mouse_left_window(wxMouseEvent&) {
if(m_hover) {
m_hover = false;
paint_now();
}
}
void mouse_left_down(wxMouseEvent&) {
wxCommandEvent event(wxEVT_BUTTON, wxID_ANY);
event.SetEventObject(this);
AddPendingEvent(event);
}
void set_focus(wxFocusEvent&) {
if(!m_focus) {
m_focus = true;
paint_now();
}
}
void kill_focus(wxFocusEvent&) {
if(m_focus) {
m_focus = false;
paint_now();
}
}
void process_enter(wxKeyEvent& e) {
if(m_focus && e.GetKeyCode() == WXK_RETURN) {
wxCommandEvent event(wxEVT_LEFT_DOWN, wxID_ANY);
wxPostEvent(GetEventHandler(), event);
}
e.Skip();
}
};
Code: Select all
//NOTE: you need to declare button size
auto button = new ModernButton(ModernButton::Type::primary, this, wxID_ANY, "wxWidgets", wxDefaultPosition, wxSize(90, 24));
Any critics are welcome. Thanks