windows 10 pro office 2019 pro office 365 pro windows 10 home windows 10 enterprise office 2019 home and business office 2016 pro windows 10 education visio 2019 microsoft project 2019 microsoft project 2016 visio professional 2016 windows server 2012 windows server 2016 windows server 2019 Betriebssysteme office software windows server https://softhier.com/ instagram takipçi instagram beğeni instagram görüntüleme instagram otomatik beğeni facebook beğeni facebook sayfa beğenisi facebook takipçi twitter takipçi twitter beğeni twitter retweet youtube izlenme youtube abone instagram

Binding event to a custom wxButton

Asked By: Anonymous

I’m writing an app in C++ wxWidgets. I’m trying to create a custom button class, although there are two problems:

  1. I binded a wxEVT_COMMAND_BUTTON_CLICKED to the button to execute a function when it’s clicked, but it doesn’t seem to get called
  2. There’s an awful grey border around it, that I’m not being able to remove (not even with wxBORDER_NONE)

My custom buttons

Code:

gridButton.h

#pragma once
#include "wx/wx.h"

enum gbSTYLE {
    NUM,
    OP,
    EXTRA
};

class gridButton : public wxWindow
{
    bool pressed;
    bool hovered;
    wxString text;

    static const int width = 50, height = 50;
    
    wxFont* gbFont = new wxFont(20, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, 
        wxFONTWEIGHT_LIGHT, false, "Lato");
    // RICORDATI DI CANCELLARE font_Button DALLA CLASSE MAIN QUANDO HAI FINITO

    wxBrush* background;
    wxColour* textColor;

    wxBrush* hoveredBackground;
    wxColour* hoveredTextColor;

    wxBrush* pressedBackground;
    wxColour* pressedTextColor;

public:
    gridButton(wxFrame* parent, wxWindowID id, wxString text, gbSTYLE style);
    ~gridButton();

    void applyStyle(gbSTYLE style);

    void paintEvent(wxPaintEvent& evt);
    void paintNow();
    void render(wxDC& dc);

    void mouseMoved(wxMouseEvent& evt);
    void mouseDown(wxMouseEvent& evt);
    void mouseWheelMoved(wxMouseEvent& evt);
    void mouseReleased(wxMouseEvent& evt);
    void rightClick(wxMouseEvent& evt);
    void mouseLeftWindow(wxMouseEvent& evt);
    void mouseEnterWindow(wxMouseEvent& evt);
    void keyPressed(wxKeyEvent& evt);
    void keyReleased(wxKeyEvent& evt);

    DECLARE_EVENT_TABLE()
};

gridButton.cpp

#include "gridButton.h"


BEGIN_EVENT_TABLE(gridButton, wxWindow)

    EVT_MOTION(gridButton::mouseMoved)
    EVT_LEFT_DOWN(gridButton::mouseDown)
    EVT_LEFT_UP(gridButton::mouseReleased)
    EVT_RIGHT_DOWN(gridButton::rightClick)
    EVT_ENTER_WINDOW(gridButton::mouseEnterWindow)
    EVT_LEAVE_WINDOW(gridButton::mouseLeftWindow)
    EVT_KEY_DOWN(gridButton::keyPressed)
    EVT_KEY_UP(gridButton::keyReleased)
    EVT_MOUSEWHEEL(gridButton::mouseWheelMoved)

    EVT_PAINT(gridButton::paintEvent)

END_EVENT_TABLE()



// funzione costruttrice (wxFULL_REPAINT_ON_RESIZE per evitare un glitch grafico quando si ridimensiona la finestra)
gridButton::gridButton(wxFrame* parent, wxWindowID id, wxString text, gbSTYLE style)
    : wxWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE) 
{
    SetMinSize(wxSize(width, height));
    this->text = text;
    
    hovered = false;
    pressed = false;

    applyStyle(style);
}

// funzione distruttrice
gridButton::~gridButton()
{
    delete gbFont;

    delete background;
    delete textColor;

    delete hoveredBackground;
    delete hoveredTextColor;

    delete pressedBackground;
    delete pressedTextColor;
}

void gridButton::applyStyle(gbSTYLE style)
{
    switch (style)
    {
    default:
        background = new wxBrush(wxColour(255, 255, 255), wxBRUSHSTYLE_SOLID);
        textColor = new wxColour(25, 25, 25);

        hoveredBackground = new wxBrush(wxColour(125, 125, 125), wxBRUSHSTYLE_SOLID);
        hoveredTextColor = new wxColour(185, 185, 185);

        pressedBackground = new wxBrush(wxColour(25, 25, 25), wxBRUSHSTYLE_SOLID);
        pressedTextColor = new wxColour(200, 200, 200);
        break;

    case NUM:
        background = new wxBrush(wxColour(98, 101, 138), wxBRUSHSTYLE_SOLID);
        textColor = new wxColour(190, 197, 200);

        hoveredBackground = new wxBrush(wxColour(66, 69, 96), wxBRUSHSTYLE_SOLID);
        hoveredTextColor = new wxColour(36, 38, 52);

        pressedBackground = new wxBrush(wxColour(16, 17, 23), wxBRUSHSTYLE_SOLID);
        pressedTextColor = new wxColour(128, 134, 192);
        break;
    }
}


//chiamato da EVT_PAINT ogni frame
void gridButton::paintEvent(wxPaintEvent& evt)
{
    wxPaintDC dc(this);
    render(dc);
}
//eseguire un render quando si vuole
void gridButton::paintNow()
{
    wxClientDC dc(this);
    render(dc);
}

//renderizzazione, qui si mette la grafica
void gridButton::render(wxDC& dc)
{
    int w = this->GetSize().GetWidth();
    int h = this->GetSize().GetHeight();

    if (pressed) {
        dc.SetBrush(*pressedBackground);
        dc.SetTextForeground(*pressedTextColor);
    }
    else if (hovered) {
        dc.SetBrush(*hoveredBackground);
        dc.SetTextForeground(*hoveredTextColor);
    }
    else {
        dc.SetBrush(*background);
        dc.SetTextForeground(*textColor);
    }

    dc.DrawRectangle(0, 0, w, h);

    dc.SetFont(*gbFont);
    wxSize textSize = GetTextExtent(text);
    dc.DrawText(text, w / 2 - (textSize.GetWidth()), h / 2 - (textSize.GetHeight()));
}

void gridButton::mouseDown(wxMouseEvent& evt)
{
    pressed = true;
    paintNow();
}
void gridButton::mouseReleased(wxMouseEvent& evt)
{
    pressed = false;
    paintNow();
}
void gridButton::mouseEnterWindow(wxMouseEvent& evt)
{
    hovered = true;
    paintNow();
}
void gridButton::mouseLeftWindow(wxMouseEvent& evt)
{
    hovered = false;
    pressed = false;
    paintNow();
}

// eventi inutilizzati
void gridButton::mouseMoved(wxMouseEvent& evt) {}
void gridButton::mouseWheelMoved(wxMouseEvent& evt) {}
void gridButton::rightClick(wxMouseEvent& evt) {}
void gridButton::keyPressed(wxKeyEvent& evt) {}
void gridButton::keyReleased(wxKeyEvent& evt) {}

This is how I layout the grid (it looks bad right now because I’m still working on the buttons themselves):

#include "main.h"


void Main::AddButtons()
{
    int w = 5, h = 4;
    MainGrid = new wxGridSizer(w, h, 0, 0);


        gridButton* test = new gridButton(this, wxID_ANY, "(", NUM);
        MainGrid->Add(test, 0, wxEXPAND);

    AddOpButton(4);

    for (int i = 0; i < 2; i++) MainGrid->AddSpacer(1);

    for (int i = 7; i < 10; i++) AddNumButton(i);
    AddOpButton(3);
    for (int i = 4; i < 7; i++) AddNumButton(i);
    AddOpButton(2);
    for (int i = 1; i < 4; i++) AddNumButton(i);
    AddOpButton(1);
    MainGrid->AddSpacer(1);
    AddNumButton(0);
    
    //dot
    wxButton* dot = new wxButton(this, wxID_ANY, ".");
    dot->SetFont(*font_Button);
    dot->SetBackgroundColour(wxColour(200, 200, 200));
    dot->SetForegroundColour(wxColour(125, 125, 125));
    dot->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &Main::OnDotClicked, this);
    MainGrid->Add(dot, 0, wxEXPAND);

    AddOpButton(0);

    MainSizer->Add(MainGrid, 10, wxEXPAND);
}

void Main::AddNumButton(int n)
{
    gridButton* btn = new gridButton(this, BUTTON_NUM + n, wxString(std::to_string(n)), NUM);
    btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &Main::OnNumClicked, this);

    MainGrid->Add(btn, 0, wxEXPAND);
}

void Main::AddOpButton(int n)
{
    std::string s(1, ops[n]);

    gridButton* btn = new gridButton(this, BUTTON_OP + n, wxString(s), OP);
    btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &Main::OnOpClicked, this);

    MainGrid->Add(btn, 0, wxEXPAND);
}

The events it should trigger:

void Main::OnNumClicked(wxCommandEvent& evt)
{
    int id = evt.GetId() - BUTTON_NUM;
    DoNumClick(id);
    evt.Skip();
}

void Main::DoNumClick(int id)
{
    char c = '0' + id;
    char exp[EXPBUFFER];
    strcpy(exp, MainText->GetValue());


    if (strlen(exp) == 1 && exp[0] == '0')
    {
        exp[0] = c;
        MainText->SetLabel(exp);
    }
    else
        MainText->AppendText(std::to_string(id));
}

I’m new to wxWidgets and any help is appreciated.


Solution

Answered By: Anonymous

I think the extra grey border is just the extra pixels that are leftover from the grid. To get rid of the leftover pixels, you can use a flex grid sizer instead and make all the rows and columns flexible.

void Main::AddButtons()
{
    MainGrid = new wxFlexGridSizer(w, h, 0, 0);

    for ( int i = 0 ; i < w ; ++ i)
    {
        MainGrid->AddGrowableRow(i);
    }
    for ( int j = 0 ; j < h ; ++j )
    {
        MainGrid->AddGrowableCol(j);
    }
...

To get rid of the rectangle around the buttons themselves, instead of drawing a rectangle, you can set a background brush and call the Clear() method. The Clear() method completely paints the window with the background brush.

void gridButton::render(wxDC& dc)
{
    int w = this->GetSize().GetWidth();
    int h = this->GetSize().GetHeight();

    if (pressed) {
        dc.SetBackground(*pressedBackground);

        dc.SetTextForeground(*pressedTextColor);
    }
    else if (hovered) {
        dc.SetBackground(*hoveredBackground);
        dc.SetTextForeground(*hoveredTextColor);
    }
    else {
        dc.SetBackground(*background);
        dc.SetTextForeground(*textColor);
    }

    dc.Clear();

The border you were seeing before was do to the edges of the rectangles being drawn with the default pen.

I have one small recommendation. I would store the colors instead of the brushes themselves. Each brush is a gdi object and on windows there’s a limit to the number of gdi objects available.

For example, if you have stored the pressedBackgroundColor, you can create a brush on the stack like this:

    if (pressed) {
        wxBrush temp(*pressedBackgroundColor));
        dc.SetBackground(temp);

or you can let the brush be created implicitly like this:

    if (pressed) {
        dc.SetBackground(*pressedBackgroundColor);

This is admittedly a slight deoptimization since brushes have to be created in each call to the render method. So feel free to ignore this if you aren’t concerned about the gdi limit on windows.


To answer the first question. You’ll need to manually generate the button press for your custom button. The easiest way to do this is in the mouseReleased method. To generate the button event, the method needs do something like this:

void gridButton::mouseReleased(wxMouseEvent& evt)
{
    pressed = false;
    paintNow();

    // Create a button event and send it for processing.
    wxCommandEvent event(wxEVT_BUTTON);
    event.SetId(GetId());
    event.SetEventObject(this);
    // Set any other data needed here.

    ProcessWindowEvent(event);
}

In order to avoid confusion with native buttons, you can also create your own event types with the wxDECLARE_EVENT and wxDEFINE_EVENT macros. There is more detail in the documentation.

techinplanet staff


Windows 10 Kaufen Windows 10 Pro Office 2019 Kaufen Office 365 Lizenz Windows 10 Home Lizenz Office 2019 Home Business Kaufen windows office 365 satın al follower kaufen instagram follower kaufen porno
Alanya escort Manavgat escort Fethiye escort Kemer escort Didim escort http://www.kadinescort.net Gaziantep escort Denizli escort Adana escort Hatay escort Aydın escort İzmir escort Ankara escort Antalya escort Bursa escort İstanbul escort Kocaeli escort Konya escort Muğla escort Malatya escort Kayseri escort Mersin escort Samsun escort Sinop escort Tekirdağ escort Eskişehir escort Yalova escort Rize escort Amasya escort Balıkesir escort Çanakkale escort Bolu escort Erzincan escort Şırnak escort Van escort Yozgat escort Zonguldak escort Afyon escort Adıyaman escort Bilecik escort Aksaray escort Ağri escort Bitlis escort Siirt escort Çorum escort Burdur escort Diyarbakir escort Edirne escort Düzce escort Erzurum escort Kırklareli escort Giresun escort Kilis escort Kars escort Karabük escort Kırıkkale escort Mardin escort Kırşehir escort Maraş escort Manisa escort Muş escort Kastamonu escort Ordu escort Nevşehir escort Sakarya escort Osmaniye escort Şanliurfa escort Sivas escort Trabzon escort Tokat escort Ardahan escort Bartın escort Karaman escort Batman escort Bayburt escort Bingöl escort Elaziğ escort Gümüşhane escort Hakkari escort Isparta escort Uşak escort Igdır escort