aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2022-02-12 19:13:34 +0100
committerLoic Guegan <manzerbredes@mailbox.org>2022-02-12 19:13:34 +0100
commita359219e33fdf3afb5ddfbb084563054a947b106 (patch)
tree91dab9c21321f73152993183cd6e8cf4a04017f8 /examples
Create project
Diffstat (limited to 'examples')
-rw-r--r--examples/wxWidgets/CMakeLists.txt6
-rw-r--r--examples/wxWidgets/MyHalfMove.cpp223
-rw-r--r--examples/wxWidgets/MyHalfMove.hpp40
-rw-r--r--examples/wxWidgets/demo.gifbin0 -> 423585 bytes
-rw-r--r--examples/wxWidgets/main.cpp197
5 files changed, 466 insertions, 0 deletions
diff --git a/examples/wxWidgets/CMakeLists.txt b/examples/wxWidgets/CMakeLists.txt
new file mode 100644
index 0000000..af76025
--- /dev/null
+++ b/examples/wxWidgets/CMakeLists.txt
@@ -0,0 +1,6 @@
+
+find_package(wxWidgets COMPONENTS core base REQUIRED)
+
+include(${wxWidgets_USE_FILE})
+add_executable(wxwidgets_example main.cpp MyHalfMove.cpp)
+target_link_libraries(wxwidgets_example cgeditor ${wxWidgets_LIBRARIES})
diff --git a/examples/wxWidgets/MyHalfMove.cpp b/examples/wxWidgets/MyHalfMove.cpp
new file mode 100644
index 0000000..6560006
--- /dev/null
+++ b/examples/wxWidgets/MyHalfMove.cpp
@@ -0,0 +1,223 @@
+#include "MyHalfMove.hpp"
+
+MyHalfMove::MyHalfMove(std::string move) { this->move = move; }
+MyHalfMove::~MyHalfMove() {}
+
+void MyHalfMove::AddVariation(MyHalfMove *m) {
+ m->IsBlack = this->IsBlack;
+ m->Number = this->Number;
+ MyHalfMove::variations.push_back(m);
+ cgeditor::CGEHalfMove::variations.push_back(m);
+ m->SetParent(this);
+}
+
+void MyHalfMove::SetMainline(MyHalfMove *m) {
+ if (!this->IsBlack) {
+ m->IsBlack = true;
+ m->Number = this->Number;
+ } else {
+ m->IsBlack = false;
+ m->Number = this->Number + 1;
+ }
+ MyHalfMove::mainline = m;
+ cgeditor::CGEHalfMove::MainLine = m;
+ if (m != NULL) {
+ m->SetParent(this);
+ }
+}
+void MyHalfMove::SetParent(MyHalfMove *m) {
+ MyHalfMove::parent = m;
+ CGEHalfMove::Parent = m;
+}
+void MyHalfMove::RemoveChild(MyHalfMove *m) {
+ std::uint32_t i = 0;
+ bool found = false;
+ for (i; i < MyHalfMove::variations.size(); i++) {
+ if (MyHalfMove::variations[i] == m) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ MyHalfMove::variations.erase(MyHalfMove::variations.begin() + i);
+ }
+ if (MyHalfMove::MainLine == m) {
+ MyHalfMove::MainLine = NULL;
+ }
+ cgeditor::CGEHalfMove::RemoveChild((CGEHalfMove *)m);
+}
+
+MyHalfMove *MyHalfMove::GetParent() { return (parent); }
+
+MyHalfMove *MyHalfMove::GetRoot() {
+ MyHalfMove *m = this;
+ MyHalfMove *p = MyHalfMove::parent;
+ while (p != NULL) {
+ if (p->mainline != m) {
+ return (m);
+ }
+ m = p;
+ p = m->MyHalfMove::parent;
+ }
+ return (m);
+}
+
+void MyHalfMove::SetAsMainline() {
+ MyHalfMove *root = GetRoot();
+ MyHalfMove *lastRoot;
+ do {
+ lastRoot = root;
+ root->MyHalfMove::Promote();
+ root = GetRoot();
+ } while (root != lastRoot);
+
+ // std::cout << IsVariation() << std::endl << std::flush;
+}
+
+void MyHalfMove::Promote() {
+ if (MyHalfMove::parent != NULL) {
+ MyHalfMove *p = MyHalfMove::parent;
+ if (p->MyHalfMove::mainline != this) {
+ if (MyHalfMove::parent->MyHalfMove::parent != NULL) {
+ MyHalfMove *pp = MyHalfMove::parent->MyHalfMove::parent;
+ if (pp->MyHalfMove::mainline == p) {
+ pp->MyHalfMove::SetMainline(this);
+ } else {
+ pp->AddVariation(this);
+ pp->MyHalfMove::RemoveChild(p);
+ }
+ }
+ if (p->MyHalfMove::mainline == this) {
+ p->MyHalfMove::SetMainline(NULL);
+ } else {
+ p->MyHalfMove::RemoveChild(this);
+ }
+ this->AddVariation(p);
+ }
+ }
+}
+
+bool MyHalfMove::IsVariation() {
+ MyHalfMove *m = this;
+ MyHalfMove *p = MyHalfMove::parent;
+ while (p != NULL) {
+ if (p->mainline != m) {
+ return (true);
+ }
+ m = p;
+ p = m->MyHalfMove::parent;
+ }
+ return (false);
+}
+
+MyHalfMove *BuildExampleGame() {
+ MyHalfMove *m = new MyHalfMove("e4");
+ MyHalfMove *toDisplay = m;
+
+ MyHalfMove *m2 = new MyHalfMove("e5");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("Nf3");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("Nc6");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("Bc4");
+ m->SetMainline(m2);
+ m->SetComment("Italian Opening");
+ m = m2;
+
+ m2 = new MyHalfMove("Bc5");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("c3");
+ m2->SetComment("Giuoco Pianissimo");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("Nf6");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("o-o");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("d6");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("Nd2");
+ m->SetMainline(m2);
+ m = m2;
+
+ {
+ MyHalfMove *var = new MyHalfMove("Re1");
+ var->SetComment("Also possible");
+ m->AddVariation(var);
+
+ MyHalfMove *var2 = new MyHalfMove("a6");
+ var->SetMainline(var2);
+ var = var2;
+
+ {
+ MyHalfMove *subvar = new MyHalfMove("Bg4");
+ var->AddVariation(subvar);
+
+ MyHalfMove *subvar2 = new MyHalfMove("Bb3");
+ subvar->SetMainline(subvar2);
+ subvar = subvar2;
+ }
+
+ var2 = new MyHalfMove("Bb3");
+ var->SetMainline(var2);
+ var = var2;
+
+ var2 = new MyHalfMove("Ba7");
+ var->SetMainline(var2);
+ var = var2;
+ }
+
+ m2 = new MyHalfMove("a6");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("Bb3");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("Ba7");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("Re1");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("o-o");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("Nf1");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("h6");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("Ng3");
+ m->SetMainline(m2);
+ m = m2;
+
+ m2 = new MyHalfMove("Nd7");
+ m->SetMainline(m2);
+ m = m2;
+
+ return (toDisplay);
+} \ No newline at end of file
diff --git a/examples/wxWidgets/MyHalfMove.hpp b/examples/wxWidgets/MyHalfMove.hpp
new file mode 100644
index 0000000..dfb8860
--- /dev/null
+++ b/examples/wxWidgets/MyHalfMove.hpp
@@ -0,0 +1,40 @@
+#include "CGEditor.hpp"
+#include <vector>
+
+/**
+ * @brief Create your custom half move class
+ *
+ * The implementation of the class should give you
+ * an overview of how to keep your move sync with the one of CGEditor
+ *
+ */
+class MyHalfMove : public cgeditor::CGEHalfMove {
+ MyHalfMove *parent = NULL;
+ MyHalfMove *mainline = NULL;
+ std::vector<MyHalfMove *> variations;
+
+public:
+ MyHalfMove(std::string move);
+ ~MyHalfMove();
+ /// @brief Add variation to current move
+ void AddVariation(MyHalfMove *m);
+ /// @brief Remove the specified child from mainline and/or variations
+ void RemoveChild(MyHalfMove *m);
+ /// @brief Set value of the mailine
+ void SetMainline(MyHalfMove *m);
+ /// @brief Set this move as mainline
+ void SetAsMainline();
+ /// @brief Promote the current move and submove
+ void Promote();
+ /// @brief Check if current half move is within a variation
+ bool IsVariation();
+ /// @brief Get the root of a variation
+ MyHalfMove* GetRoot();
+ /// @brief Get parent of the current move
+ MyHalfMove* GetParent();
+ /// @brief Set parent of the current move
+ void SetParent(MyHalfMove *m);
+};
+
+/// @brief Build the example game to use in the editor
+MyHalfMove *BuildExampleGame(); \ No newline at end of file
diff --git a/examples/wxWidgets/demo.gif b/examples/wxWidgets/demo.gif
new file mode 100644
index 0000000..165b439
--- /dev/null
+++ b/examples/wxWidgets/demo.gif
Binary files differ
diff --git a/examples/wxWidgets/main.cpp b/examples/wxWidgets/main.cpp
new file mode 100644
index 0000000..20e6d3f
--- /dev/null
+++ b/examples/wxWidgets/main.cpp
@@ -0,0 +1,197 @@
+#include <wx/wxprec.h>
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+#include "CGEditor.hpp"
+#include "MyHalfMove.hpp"
+
+/**
+ * @brief CGEditor Window
+ *
+ */
+class MyFrame : public wxFrame, public cgeditor::CGEditor {
+ wxPaintDC *dc;
+ bool NeedRedraw = false;
+
+public:
+ MyFrame()
+ : wxFrame(NULL, wxID_ANY, "Hello World CGEditor"), CGEditor(), dc(NULL) {
+ CreateStatusBar();
+ SetStatusText("CGEditor");
+ // Create a game
+ CGEditor::status.Moves = BuildExampleGame();
+ }
+
+private:
+ void OnExit(wxCommandEvent &event) { Close(true); }
+
+ void OnPaint(wxPaintEvent &event) {
+ wxPaintDC current_dc(this);
+ dc = &current_dc;
+
+ // Refresh canvas size
+ wxSize sz = GetClientSize();
+ CGEditor::status.CanvasWidth = sz.GetWidth();
+ CGEditor::status.CanvasHeight = sz.GetHeight();
+ CGEditor::status.UseMoveImages =
+ 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();
+ }
+
+ // Should another draw of CGEditor be made?
+ if (NeedRedraw) {
+ Refresh();
+ NeedRedraw = false;
+ }
+ }
+
+ /**
+ * @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);
+ }
+ 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(*wxYELLOW_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.UseMoveImages) {
+ 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";
+ static_cast<MyHalfMove *>(e.move)->MyHalfMove::Promote();
+ NeedRedraw = true;
+ } else if (e.type == cgeditor::Event::Type::Delete) {
+ str = "Delete";
+ if (e.move->Parent != NULL) {
+ static_cast<MyHalfMove *>(e.move)->GetParent()->MyHalfMove::RemoveChild(
+ (MyHalfMove *)e.move);
+ } else {
+ CGEditor::status.Moves = NULL;
+ }
+ NeedRedraw = true;
+ } else if (e.type == cgeditor::Event::Type::SetAsMainline) {
+ str = "Set as main line";
+ static_cast<MyHalfMove *>(e.move)->MyHalfMove::SetAsMainline();
+ NeedRedraw = true;
+ } else if (e.type == cgeditor::Event::Type::Goto) {
+ str = "Goto move";
+ }
+ std::cout << "Event received: " << str << std::endl << std::flush;
+ }
+
+ // wxWidgets specific
+ DECLARE_EVENT_TABLE()
+};
+
+wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
+EVT_PAINT(MyFrame::OnPaint)
+EVT_MOUSE_EVENTS(MyFrame::MouseEvent)
+wxEND_EVENT_TABLE()
+
+class MyApp : public wxApp {
+public:
+ virtual bool OnInit() {
+ MyFrame *frame = new MyFrame();
+ frame->Show(true);
+ return true;
+ }
+};
+wxIMPLEMENT_APP(MyApp);