cgeditor/examples/wxWidgets/main.cpp
2023-06-05 13:48:29 +02:00

238 lines
7.2 KiB
C++

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include "CGEditor.hpp"
#include "MyHalfMove.hpp"
/**
* @brief CGEditor Window
*
*/
class EditorPanel : public wxPanel, public cgeditor::CGEditor {
wxPaintDC *dc;
/// @brief Used to test focus:
CMI::HalfMove *toFocus;
public:
EditorPanel(wxWindow *parent)
: wxPanel(parent), CGEditor(), dc(NULL) {
// Create a game
CGEditor::status.Moves = BuildExampleGame();
// Set move to focus to the last move (downest move in the window!):
toFocus= CGEditor::status.Moves;
while(toFocus->GetMainline()!=nullptr){
toFocus=toFocus->GetMainline();
}
}
void OnExit(wxCommandEvent &event) {
(void)event; // Disable unused variable warning
Close(true); }
void OnPaint(wxPaintEvent &event) {
(void)event; // Disable unused variable warning
wxPaintDC current_dc(this);
dc = &current_dc;
// Just in case you want to fetch font sizes to configure comment text:
//wxSize fontsize=dc->GetTextExtent("a");
//wxLogDebug("width=%d, height=%d",fontsize.x,fontsize.y);
// Refresh canvas size
wxSize sz = GetClientSize();
CGEditor::status.CanvasWidth = sz.GetWidth();
CGEditor::status.CanvasHeight = sz.GetHeight();
CGEditor::status.UseMoveIcons =
false; // Piece image should be drawn before the move ?
const wxPoint pt = wxGetMousePosition();
CGEditor::status.MouseX = pt.x - this->GetScreenPosition().x;
CGEditor::status.MouseY = pt.y - this->GetScreenPosition().y;
CGEditor::Draw();
}
/**
* @brief We refresh CGEditor status according to events
*
* @param event
*/
void MouseEvent(wxMouseEvent &event) {
if (event.Dragging()) {
CGEditor::status.LeftClick = false;
CGEditor::status.IsDrag = true;
Refresh();
} else if (event.LeftDown()) {
CGEditor::status.LeftClick = true;
Refresh();
} else if (event.RightDown()) {
CGEditor::status.RightClick = true;
Refresh();
} else if (event.GetWheelRotation() != 0) {
if (event.GetWheelRotation() < 0) {
CGEditor::status.EventVScroll = 50;
} else {
CGEditor::status.EventVScroll = -50;
}
Refresh();
}
// Now handle generated events from last user inputs
Update();
if(ProcessEvents()){
Refresh();
}
}
void KeyboardEvent(wxKeyEvent& event){
switch ( event.GetKeyCode() )
{
case WXK_DOWN:
CGEditor::FocusOnMove(toFocus);
Refresh();
if(toFocus->GetParent()!=nullptr){
toFocus=toFocus->GetParent(); // Get previous move (not that it can be on the same line!)
}
break;
}
}
/**
* @brief Convenient fonction to center text
*
* @param e Element to center
* @return wxPoint The centered version of e according to wdWidget API
*/
wxPoint Middle(cgeditor::Element e) {
wxSize sz = dc->GetTextExtent(e.text);
return (wxPoint(e.x + (e.width - sz.GetWidth()) / 2,
e.y + (e.height - sz.GetHeight()) / 2));
}
/**
* @brief CGEditor is going to call this method with the elements to draw on
* the canvas
*
* @param e Element to draw
*/
void DrawElement(const cgeditor::Element &e) {
dc->SetPen(wxNullPen);
dc->SetBrush(*wxRED_BRUSH);
if (e.prop & cgeditor::Property::Rectangle) {
if (e.prop & cgeditor::Property::Scrollbarbg) {
dc->SetBrush(*wxCYAN_BRUSH);
} else if (e.prop & cgeditor::Property::Scrollbar) {
dc->SetBrush(*wxBLUE_BRUSH);
} else if (e.prop & cgeditor::Property::Margin) {
dc->SetBrush(*wxLIGHT_GREY_BRUSH);
} else if (e.prop & cgeditor::Property::Button) {
dc->SetBrush(*wxBLACK_BRUSH);
} else if (e.prop & cgeditor::Property::Comment) {
dc->SetBrush(*wxYELLOW_BRUSH);
}
wxRect recToDraw(e.x, e.y, e.width, e.height);
dc->DrawRectangle(recToDraw);
} else if (e.prop & cgeditor::Property::Text ||
e.prop & cgeditor::Property::Image) {
if (e.prop & cgeditor::Property::Image) {
// Draw your pieces images instead
dc->SetBrush(*wxRED_BRUSH);
wxRect recToDraw(e.x, e.y, e.width, e.height);
dc->DrawRectangle(recToDraw);
dc->DrawText(wxString(e.text), Middle(e));
} else if (e.prop & cgeditor::Property::Comment) {
wxRect recToDraw(e.x, e.y, e.width, e.height);
dc->SetBrush(*wxBLUE_BRUSH);
dc->DrawRectangle(recToDraw);
dc->DrawText(wxString(e.text), wxPoint(e.x, e.y));
} else if (e.prop & cgeditor::Property::Menuitem) {
wxRect recToDraw(e.x, e.y, e.width, e.height);
dc->SetBrush(*wxLIGHT_GREY_BRUSH);
dc->DrawRectangle(recToDraw);
dc->DrawText(wxString(e.text), wxPoint(e.x, Middle(e).y));
} else {
if (e.prop & cgeditor::Property::Move) {
if (e.prop & cgeditor::Property::Current) {
wxRect recToDraw(e.x, e.y, e.width, e.height);
dc->SetBrush(*wxLIGHT_GREY_BRUSH);
dc->DrawRectangle(recToDraw);
}
if (CGEditor::status.UseMoveIcons) {
dc->DrawText(wxString(e.text), wxPoint(e.x, Middle(e).y));
} else {
dc->DrawText(wxString(e.text), Middle(e));
}
} else {
dc->DrawText(wxString(e.text), Middle(e));
}
}
}
}
/**
* @brief CGEditor events that occurs during last draw
*
* @param e event to handle
*/
void HandleEvent(const cgeditor::Event &e) {
std::string str;
if (e.type == cgeditor::Event::Type::CommentSelected)
str = "Comment Selected";
else if (e.type == cgeditor::Event::Type::Promote) {
str = "Promote";
e.move->Promote();
SyncCache();
} else if (e.type == cgeditor::Event::Type::Delete) {
str = "Delete";
if (e.move->GetParent() != nullptr) {
static_cast<MyHalfMove *>((e.move)->GetParent())->RemoveChild(static_cast<MyHalfMove *>(e.move));
delete static_cast<MyHalfMove *>(e.move);
SyncCache(); // Do not forget to sync the cache
} else {
CGEditor::status.Moves = nullptr;
}
} else if (e.type == cgeditor::Event::Type::SetAsMainline) {
str = "Set as main line";
e.move->SetAsMainline();
SyncCache();
} else if (e.type == cgeditor::Event::Type::Goto) {
str = "Goto move";
}
wxLogDebug("Event received: %s", str);
if(CGEditor::status.Moves != nullptr && !CGEditor::status.Moves->IsConsistent())
wxLogError("ERROR!! The tree of moves is not consistent anymore! Something wrong happends");
}
// wxWidgets specific
DECLARE_EVENT_TABLE()
};
wxBEGIN_EVENT_TABLE(EditorPanel, wxPanel)
EVT_PAINT(EditorPanel::OnPaint)
EVT_MOUSE_EVENTS(EditorPanel::MouseEvent)
EVT_KEY_DOWN(EditorPanel::KeyboardEvent)
wxEND_EVENT_TABLE()
class MainWindow: public wxFrame
{
wxPanel* editorPane;
public:
MainWindow(const wxString& title):wxFrame(NULL, wxID_ANY, title){
CreateStatusBar();
SetStatusText("CGEditor");
editorPane = new EditorPanel(this);
}
};
class MyApp : public wxApp {
public:
virtual bool OnInit() {
MainWindow *frame = new MainWindow("Hello World CGEditor");
frame->Show(true);
return true;
}
};
wxIMPLEMENT_APP(MyApp);