aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2023-01-19 13:06:36 +0100
committerLoic Guegan <manzerbredes@mailbox.org>2023-01-19 13:06:36 +0100
commita84b210ca397194ad360175cf89451f319121e6c (patch)
treef44e9396fd5bf0abfd731d5bf897811e95384c32
parent5e18d43a6ba4fd378178418de6b2ca7a67d64c21 (diff)
Integrate CMI
-rw-r--r--.gitmodules3
-rw-r--r--CMakeLists.txt4
-rw-r--r--examples/wxWidgets/CMakeLists.txt2
-rw-r--r--examples/wxWidgets/MyHalfMove.cpp122
-rw-r--r--examples/wxWidgets/MyHalfMove.hpp27
-rw-r--r--examples/wxWidgets/main.cpp23
m---------libs/chess-move-interface0
-rw-r--r--src/CGEHalfMove.cpp43
-rw-r--r--src/CGEHalfMove.hpp41
-rw-r--r--src/CGEditor.cpp79
-rw-r--r--src/CGEditor.hpp7
-rw-r--r--src/Types.hpp12
-rw-r--r--src/components/Component.hpp1
-rw-r--r--src/components/MoveTable.cpp100
-rw-r--r--src/components/MoveTable.hpp15
15 files changed, 193 insertions, 286 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..704f939
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "libs/chess-move-interface"]
+ path = libs/chess-move-interface
+ url = git@gitlab.com:manzerbredes/chess-move-interface.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8576f39..5388b1f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,6 +18,10 @@ include_directories(src)
file(GLOB_RECURSE SRC_CPP_FILES src/*.cpp)
add_library(cgeditor SHARED ${SRC_CPP_FILES})
+# ChessMoveInterface
+add_subdirectory(libs/chess-move-interface)
+include_directories(${CMI_INCLUDE_DIR})
+
# Examples
set(COMPILE_EXAMPLES FALSE CACHE BOOL "Compiling included examples")
if(COMPILE_EXAMPLES)
diff --git a/examples/wxWidgets/CMakeLists.txt b/examples/wxWidgets/CMakeLists.txt
index af76025..61c1396 100644
--- a/examples/wxWidgets/CMakeLists.txt
+++ b/examples/wxWidgets/CMakeLists.txt
@@ -4,3 +4,5 @@ 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})
+target_link_libraries(wxwidgets_example ChessMoveInterface)
+
diff --git a/examples/wxWidgets/MyHalfMove.cpp b/examples/wxWidgets/MyHalfMove.cpp
index 0e08113..510ff70 100644
--- a/examples/wxWidgets/MyHalfMove.cpp
+++ b/examples/wxWidgets/MyHalfMove.cpp
@@ -1,114 +1,6 @@
#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::MyHalfMove(std::string move){SetSAN(move); }
MyHalfMove *BuildExampleGame() {
MyHalfMove *m = new MyHalfMove("e4");
@@ -128,7 +20,7 @@ MyHalfMove *BuildExampleGame() {
m2 = new MyHalfMove("Bc4");
m->SetMainline(m2);
- m->comment="Italian Opening";
+ m->SetComment("Italian Opening");
m = m2;
m2 = new MyHalfMove("Bc5");
@@ -136,7 +28,7 @@ MyHalfMove *BuildExampleGame() {
m = m2;
m2 = new MyHalfMove("c3");
- m2->comment="Giuoco Pianissimo";
+ m2->SetComment("Giuoco Pianissimo");
m->SetMainline(m2);
m = m2;
@@ -158,7 +50,7 @@ MyHalfMove *BuildExampleGame() {
{
MyHalfMove *var = new MyHalfMove("Re1");
- var->comment="Also possible";
+ var->SetComment("Also possible");
m->AddVariation(var);
MyHalfMove *var2 = new MyHalfMove("a6");
@@ -185,8 +77,8 @@ MyHalfMove *BuildExampleGame() {
m2 = new MyHalfMove("a6");
m->SetMainline(m2);
- m->comment="Test for a very long comment, to see how line breaks are handle by the framework.";
- m->comment+="Test for a very long comment, to see how line breaks are handle by the framework.";
+ m->SetComment("Test for a very long comment, to see how line breaks are handle by the framework.");
+ m->SetComment(m->GetComment()+"Test for a very long comment, to see how line breaks are handle by the framework.");
m = m2;
m2 = new MyHalfMove("Bb3");
@@ -198,7 +90,7 @@ MyHalfMove *BuildExampleGame() {
m = m2;
m2 = new MyHalfMove("Re1");
- m2->nag="!!";
+ m2->SetNAG(3);
m->SetMainline(m2);
m = m2;
diff --git a/examples/wxWidgets/MyHalfMove.hpp b/examples/wxWidgets/MyHalfMove.hpp
index dfb8860..84cc5e6 100644
--- a/examples/wxWidgets/MyHalfMove.hpp
+++ b/examples/wxWidgets/MyHalfMove.hpp
@@ -1,5 +1,6 @@
+#pragma once
+
#include "CGEditor.hpp"
-#include <vector>
/**
* @brief Create your custom half move class
@@ -8,32 +9,10 @@
* 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;
+class MyHalfMove : public CMI::HalfMove {
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
diff --git a/examples/wxWidgets/main.cpp b/examples/wxWidgets/main.cpp
index 7d2f59e..303d014 100644
--- a/examples/wxWidgets/main.cpp
+++ b/examples/wxWidgets/main.cpp
@@ -38,7 +38,7 @@ private:
CGEditor::status.CanvasWidth = sz.GetWidth();
CGEditor::status.CanvasHeight = sz.GetHeight();
CGEditor::status.UseMoveIcons =
- true; // Piece image should be drawn before the move ?
+ false; // Piece image should be drawn before the move ?
const wxPoint pt = wxGetMousePosition();
CGEditor::status.MouseX = pt.x - this->GetScreenPosition().x;
@@ -90,7 +90,7 @@ private:
e.y + (e.height - sz.GetHeight()) / 2));
}
- /**
+ /**
* @brief CGEditor is going to call this method with the elements to draw on
* the canvas
*
@@ -161,22 +161,27 @@ private:
str = "Comment Selected";
else if (e.type == cgeditor::Event::Type::Promote) {
str = "Promote";
- static_cast<MyHalfMove *>(e.move)->MyHalfMove::Promote();
+ e.move->Promote();
+ SyncCache();
} 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);
+ 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 = NULL;
+ CGEditor::status.Moves = nullptr;
}
} else if (e.type == cgeditor::Event::Type::SetAsMainline) {
str = "Set as main line";
- static_cast<MyHalfMove *>(e.move)->MyHalfMove::SetAsMainline();
+ e.move->SetAsMainline();
+ SyncCache();
} else if (e.type == cgeditor::Event::Type::Goto) {
str = "Goto move";
}
- std::cout << "Event received: " << str << std::endl << std::flush;
+ 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
diff --git a/libs/chess-move-interface b/libs/chess-move-interface
new file mode 160000
+Subproject 720c394c50e7cb79e6403c408b40dfe8d994230
diff --git a/src/CGEHalfMove.cpp b/src/CGEHalfMove.cpp
deleted file mode 100644
index f26f19e..0000000
--- a/src/CGEHalfMove.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-#include "CGEHalfMove.hpp"
-
-namespace cgeditor {
-
-CGEHalfMove::CGEHalfMove()
- : MainLine(NULL), IsBlack(false), Number(1), Parent(NULL) {}
-
-CGEHalfMove::CGEHalfMove(CGEHalfMove *parent) {
- CGEHalfMove();
- Parent = parent;
- Parent->MainLine = this;
- if (parent->IsBlack) {
- Number = parent->Number + 1;
- IsBlack = false;
- } else {
- Number = parent->Number;
- IsBlack = true;
- }
-}
-
-CGEHalfMove::CGEHalfMove(const std::string &move)
- : MainLine(NULL), IsBlack(false), Number(0), Parent(NULL) {
- this->move = move;
-}
-
-void CGEHalfMove::RemoveChild(CGEHalfMove *m) {
- std::uint32_t i = 0;
- bool found = false;
- for (i; i < variations.size(); i++) {
- if (variations[i] == m) {
- found = true;
- break;
- }
- }
- if (found) {
- variations.erase(variations.begin() + i);
- }
- if (MainLine == m) {
- MainLine = NULL;
- }
-}
-
-} // namespace cgeditor \ No newline at end of file
diff --git a/src/CGEHalfMove.hpp b/src/CGEHalfMove.hpp
deleted file mode 100644
index 681aee1..0000000
--- a/src/CGEHalfMove.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#pragma once
-
-#include <string>
-#include <vector>
-
-namespace cgeditor {
-
-/**
- * @brief Move (mainlines and variations) displayed in the editor
- *
- */
-class CGEHalfMove {
-
-public:
- CGEHalfMove();
- CGEHalfMove(CGEHalfMove *parent);
- CGEHalfMove(const std::string &move);
-
- /// @brief CUrrent move number
- std::uint16_t Number;
- /// @brief Current move value
- std::string move;
- /// @brief Current NAG
- std::string nag;
- /// @brief Comment linked to the move
- std::string comment;
-
- CGEHalfMove *MainLine;
- CGEHalfMove *Parent;
- bool IsBlack;
- /// @brief Says if variations of that move must be drawn
- bool Folded = false;
- /// @brief Says if this move must be drawn
- bool Hide = false;
- /// @brief Variations of the move
- std::vector<CGEHalfMove *> variations;
-
- /// @brief Remove a move from the MainLine and/or variations
- void RemoveChild(CGEHalfMove *m);
-};
-} // namespace cgeditor \ No newline at end of file
diff --git a/src/CGEditor.cpp b/src/CGEditor.cpp
index e55a578..fadbdc8 100644
--- a/src/CGEditor.cpp
+++ b/src/CGEditor.cpp
@@ -8,6 +8,58 @@ CGEditor::CGEditor() {
MT = new MoveTable(&status);
MA = new Margin(&status);
ME = new Menu(&status);
+ // Default Standard NagTable: https://en.wikipedia.org/wiki/Numeric_Annotation_Glyphs
+ status.NagTable[0]="";
+ status.NagTable[1]="!";
+ status.NagTable[2]="?";
+ status.NagTable[3]="!!";
+ status.NagTable[4]="??";
+ status.NagTable[5]="!?";
+ status.NagTable[6]="?!";
+ status.NagTable[7]="□";
+ status.NagTable[10]="=";
+ status.NagTable[13]="∞";
+ status.NagTable[14]="⩲";
+ status.NagTable[15]="⩱";
+ status.NagTable[16]="±";
+ status.NagTable[17]="∓";
+ status.NagTable[18]="+-";
+ status.NagTable[19]="-+";
+ status.NagTable[22]="⨀";
+ status.NagTable[23]="⨀";
+ status.NagTable[26]="○";
+ status.NagTable[27]="○";
+ status.NagTable[32]="⟳";
+ status.NagTable[33]="⟳";
+ status.NagTable[36]="↑";
+ status.NagTable[37]="↑";
+ status.NagTable[40]="→";
+ status.NagTable[41]="→";
+ status.NagTable[44]="⯹";
+ status.NagTable[45]="⯹";
+ status.NagTable[132]="⇆";
+ status.NagTable[133]="⇆";
+ status.NagTable[138]="⨁";
+ status.NagTable[139]="⨁";
+ // Default Non-Standard NagTable: https://en.wikipedia.org/wiki/Numeric_Annotation_Glyphs
+ status.NagTable[140]="∆";
+ status.NagTable[141]="∇";
+ status.NagTable[142]="⌓";
+ status.NagTable[143]="<=";
+ status.NagTable[144]="==";
+ status.NagTable[145]="RR";
+ status.NagTable[146]="N";
+ status.NagTable[220]="⬒";
+ status.NagTable[221]="⬓";
+ status.NagTable[238]="○";
+ status.NagTable[239]="⇔";
+ status.NagTable[240]="⇗";
+ status.NagTable[241]="⊞";
+ status.NagTable[242]="⟫";
+ status.NagTable[243]="⟪";
+ status.NagTable[244]="✕";
+ status.NagTable[245]="⊥";
+ status.NagTable[254]="∟";
}
CGEditor::~CGEditor() {
@@ -86,6 +138,15 @@ void CGEditor::CallDrawElement(Element e) {
DrawElement(e);
}
+void CGEditor::SyncCache(){
+ MA->SyncCache();
+ MT->SyncCache();
+ MA->SyncCache();
+ SBV->SyncCache();
+ SBH->SyncCache();
+ ME->SyncCache();
+}
+
void CGEditor::DrawComponent(Component *c) {
for (Element &e : c->GetElements()) {
CallDrawElement(e);
@@ -103,4 +164,20 @@ bool CGEditor::ProcessEvents(){
return processed;
}
-} // namespace cgeditor \ No newline at end of file
+std::string CGEditor::GetNAGSymbol(const std::uint8_t id) const{
+ for(auto const& pair: status.NagTable){
+ if(pair.first == id)
+ return pair.second;
+ }
+ return "";
+}
+
+std::uint8_t CGEditor::GetNAGId(const std::string& symbol) const{
+ for(auto const& pair: status.NagTable){
+ if(pair.second == symbol)
+ return pair.first;
+ }
+ return 0;
+}
+
+} // namespace cgeditor
diff --git a/src/CGEditor.hpp b/src/CGEditor.hpp
index e113325..2ac81a3 100644
--- a/src/CGEditor.hpp
+++ b/src/CGEditor.hpp
@@ -27,11 +27,16 @@ protected:
void Draw();
/// @brief Process the events generated during the drawing
bool ProcessEvents();
+ /// @brief Synchronize the editor cache (must be called when game was modified from outside the editor)
+ void SyncCache();
/// @brief Draw an element on the canvas
virtual void DrawElement(const Element &) = 0;
/// @brief Handle event that occured during editor drawing
virtual void HandleEvent(const Event &) = 0;
-
+ /// @brief Convert NAG id to symbol using the NagTable
+ std::string GetNAGSymbol(const std::uint8_t) const;
+ /// @brief Convert NAG symbol to id using the NagTable
+ std::uint8_t GetNAGId(const std::string&) const;
public:
CGEditor();
~CGEditor();
diff --git a/src/Types.hpp b/src/Types.hpp
index 402bf12..83c79f0 100644
--- a/src/Types.hpp
+++ b/src/Types.hpp
@@ -1,7 +1,8 @@
#pragma once
-#include "CGEHalfMove.hpp"
+#include "CMI.hpp"
#include <string>
+#include <unordered_map>
namespace cgeditor {
@@ -54,7 +55,7 @@ typedef struct Event {
enum Type { CommentSelected, Promote, Delete, SetAsMainline, Goto, None };
Type type = None;
/// @brief Move related to the event
- CGEHalfMove *move = NULL;
+ CMI::HalfMove *move = nullptr;
} Event;
/**
@@ -92,10 +93,11 @@ typedef struct Status {
double MoveTableMaxX = 0, MoveTableMaxY = 0;
/// @brief User should set it to true when mouse is dragging
bool IsDrag = false;
- CGEHalfMove *Moves = NULL;
- CGEHalfMove *CurrentMove = NULL;
- CGEHalfMove *SelectedMove = NULL;
+ CMI::HalfMove *Moves = nullptr;
+ CMI::HalfMove *CurrentMove = nullptr;
+ CMI::HalfMove *SelectedMove = nullptr;
std::vector<Event> Events;
+ std::unordered_map<std::uint8_t, std::string> NagTable;
} Status;
} // namespace cgeditor \ No newline at end of file
diff --git a/src/components/Component.hpp b/src/components/Component.hpp
index 204ee47..564660a 100644
--- a/src/components/Component.hpp
+++ b/src/components/Component.hpp
@@ -14,6 +14,7 @@ public:
Component(Status *s) : status(s){};
std::vector<Element> GetElements() { return (this->elements); }
virtual void Refresh() = 0;
+ virtual void SyncCache() {};
};
} // namespace cgeditor \ No newline at end of file
diff --git a/src/components/MoveTable.cpp b/src/components/MoveTable.cpp
index b08bf9e..653356a 100644
--- a/src/components/MoveTable.cpp
+++ b/src/components/MoveTable.cpp
@@ -1,5 +1,4 @@
#include "MoveTable.hpp"
-#include <iostream>
namespace cgeditor {
@@ -11,8 +10,8 @@ void MoveTable::Refresh() {
elements.clear();
VariationMargins.clear();
CurrentMove = -1; // No current move by default
- if (status->Moves != NULL) {
- UpdateMoves(status->Moves, 0, 0, status->Moves->IsBlack);
+ if (status->Moves != nullptr) {
+ UpdateMoves(status->Moves, 0, 0, status->Moves->IsBlack());
// We only set the type after the call to UpdateMoves()
// This way only a single move will be the current move
if (CurrentMove >= 0) {
@@ -46,19 +45,19 @@ bool MoveTable::IsMouseOver(const Element &e) const {
status->MouseY - status->ScrollY));
}
-std::uint32_t MoveTable::UpdateMoves(CGEHalfMove *m, std::uint32_t line,
+std::uint32_t MoveTable::UpdateMoves(CMI::HalfMove *m, std::uint32_t line,
std::uint32_t indent, bool only_black) {
//---------- Check black or white ----------
char indent_black = 0;
- if (m->IsBlack) {
+ if (m->IsBlack()) {
indent_black++;
}
//---------- Create temporary move surrounding area ----------
Element move_bound;
move_bound.prop = Property::Move;
- if (m->IsBlack) {
+ if (m->IsBlack()) {
move_bound.prop |= Property::Black;
}
move_bound.x = status->MarginBarWidth +
@@ -67,7 +66,7 @@ std::uint32_t MoveTable::UpdateMoves(CGEHalfMove *m, std::uint32_t line,
move_bound.y = status->MoveHeight * line;
move_bound.width = status->MoveWidth;
move_bound.height = status->MoveHeight;
- move_bound.text = m->move;
+ move_bound.text = m->GetSAN();
move_bound.ShouldApplyScroll = true;
bool isMouseOver = IsMouseOver(move_bound);
@@ -102,12 +101,12 @@ std::uint32_t MoveTable::UpdateMoves(CGEHalfMove *m, std::uint32_t line,
// Move
Element e;
e.prop = move_bound.prop | Property::Text;
- e.text = m->move;
- if (m->move.size() > 0) {
- char c = m->move[0];
+ e.text = m->GetSAN();
+ if (m->GetSAN().size() > 0) {
+ char c = m->GetSAN()[0];
if (!(c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e' ||
c == 'f' || c == 'g' || c == 'h' || c == 'O' || c == '0')) {
- e.text = m->move.substr(1, m->move.size());
+ e.text = m->GetSAN().substr(1, m->GetSAN().size());
if (c == 'N') {
img.prop |= Property::Knight;
} else if (c == 'B') {
@@ -137,9 +136,9 @@ std::uint32_t MoveTable::UpdateMoves(CGEHalfMove *m, std::uint32_t line,
}
//---------- NAG ----------
- if(m->nag.size()>0){
+ if(m->GetNAG()>0){
Element nag;
- nag.text = m->nag;
+ nag.text = status->NagTable[m->GetNAG()];
nag.x = move_bound.x + status->MoveWidth - status->NagWidth - status->NagRightMargin;
nag.y = status->MoveHeight * line;
nag.width = status->NagWidth;
@@ -150,15 +149,15 @@ std::uint32_t MoveTable::UpdateMoves(CGEHalfMove *m, std::uint32_t line,
}
//---------- Move number in marge or for variation ----------
- if (indent == 0 && (!m->IsBlack || only_black)) {
- DRAW_NB(0, status->MoveHeight * line, m->Number);
- } else if (indent > 0 && (!m->IsBlack || only_black)) {
+ if (indent == 0 && (!m->IsBlack() || only_black)) {
+ DRAW_NB(0, status->MoveHeight * line, m->GetNumber());
+ } else if (indent > 0 && (!m->IsBlack() || only_black)) {
if (only_black) {
DRAW_NB_VAR((move_bound.x - status->MoveWidth) - status->MarginBarWidth,
- status->MoveHeight * line, m->Number);
+ status->MoveHeight * line, m->GetNumber());
} else {
DRAW_NB_VAR(move_bound.x - ((indent + 1) / 2 * status->MarginBarWidth),
- status->MoveHeight * line, m->Number);
+ status->MoveHeight * line, m->GetNumber());
}
}
@@ -176,35 +175,50 @@ std::uint32_t MoveTable::UpdateMoves(CGEHalfMove *m, std::uint32_t line,
}
//---------- Comments ----------
- if (m->comment.size() > 0) {
+ if (m->GetComment().size() > 0) {
line = DrawComment(m, line, indent, move_bound, indent_black);
}
//---------- Variations ----------
- if (m->variations.size() > 0) {
+ if (m->GetVariations().size() > 0) {
line = DrawVariations(m, line, indent, move_bound, indent_black);
}
//---------- Mainline ----------
- if (m->MainLine != NULL) {
- only_black = (m->MainLine->IsBlack &&
- (m->comment.size() > 0 || m->variations.size()));
- if (m->IsBlack) {
- line = UpdateMoves(m->MainLine, line + 1, indent, only_black);
+ if (m->GetMainline() != nullptr) {
+ only_black = (m->GetMainline()->IsBlack() &&
+ (m->GetComment().size() > 0 || m->GetVariations().size()));
+ if (m->IsBlack()) {
+ line = UpdateMoves(m->GetMainline(), line + 1, indent, only_black);
} else {
- line = UpdateMoves(m->MainLine, line, indent, only_black);
+ line = UpdateMoves(m->GetMainline(), line, indent, only_black);
}
}
return (line);
}
-std::uint32_t MoveTable::DrawComment(CGEHalfMove *m, std::uint32_t line,
+void MoveTable::SyncCache(){
+ if(status->Moves != nullptr){
+ std::vector<CMI::HalfMove*> toDelete;
+ for (auto const& entry : MovesStates){
+ if(!status->Moves->Contains(entry.first))
+ toDelete.push_back(entry.first);
+ }
+ for(auto key: toDelete){
+ MovesStates.erase(key);
+ }
+ }
+ else
+ MovesStates.clear();
+}
+
+std::uint32_t MoveTable::DrawComment(CMI::HalfMove *m, std::uint32_t line,
std::uint32_t indent,
const Element &move_bound,
const char &indent_black) {
// Show three dots
- if (!m->IsBlack) {
+ if (!m->IsBlack()) {
DRAW_DOTS(status->MarginBarWidth + status->MoveWidth * (indent + 1) +
((indent + 1) / 2 * status->MarginBarWidth),
status->MoveHeight * line);
@@ -212,7 +226,7 @@ std::uint32_t MoveTable::DrawComment(CGEHalfMove *m, std::uint32_t line,
line++; // Goto the right line
/// ----- Compute comment bounding box values:
- int nchar=m->comment.size();
+ int nchar=m->GetComment().size();
int nline=ceil((double)nchar/(double)status->CommentCharPerLine);
std::uint16_t nrow=ceil(((nline*status->CommentCharHeight)+2*status->CommentPadding)/status->MoveHeight);
int width=status->CommentCharPerLine*status->CommentCharWidth+2*status->CommentPadding;
@@ -249,7 +263,7 @@ std::uint32_t MoveTable::DrawComment(CGEHalfMove *m, std::uint32_t line,
l.height=status->CommentCharHeight;
l.ShouldApplyScroll = true;
for(int i=0;i<nline;i++){
- l.text=m->comment.substr(i*status->CommentCharPerLine,status->CommentCharPerLine);
+ l.text=m->GetComment().substr(i*status->CommentCharPerLine,status->CommentCharPerLine);
// Remove leading space:
if(l.text.size()>2 && l.text[0]==' '){
l.text=l.text.substr(1,l.text.size());
@@ -264,18 +278,18 @@ std::uint32_t MoveTable::DrawComment(CGEHalfMove *m, std::uint32_t line,
}
line += nrow; // Skip right amount of lines
// ----- Since we already increment line for black later on:
- if (m->IsBlack || m->variations.size() > 0) {
+ if (m->IsBlack() || m->GetVariations().size() > 0) {
line--;
}
return (line);
}
-std::uint32_t MoveTable::DrawVariations(CGEHalfMove *m, std::uint32_t line,
+std::uint32_t MoveTable::DrawVariations(CMI::HalfMove *m, std::uint32_t line,
std::uint32_t indent,
const Element &move_bound,
const char &indent_black) {
// Show three dots next to move if white turn
- if ((m->variations.size() == 0) && !m->IsBlack) {
+ if ((m->GetVariations().size() == 0) && !m->IsBlack()) {
DRAW_DOTS(status->MarginBarWidth + status->MoveWidth * (indent + 1),
status->MoveHeight * line);
}
@@ -284,22 +298,22 @@ std::uint32_t MoveTable::DrawVariations(CGEHalfMove *m, std::uint32_t line,
Element e;
e.prop = Property::Rectangle | Property::Button;
e.x = move_bound.x + status->MoveWidth;
- if (!m->IsBlack)
+ if (!m->IsBlack())
e.x += status->MoveWidth;
e.y = move_bound.y + std::ceil(status->MoveHeight / 4);
e.width = std::ceil(status->MoveHeight / 2);
e.height = e.width;
e.ShouldApplyScroll = true;
if (status->LeftClick && IsMouseOver(e)) {
- m->Folded = !m->Folded;
+ MovesStates[m].IsFolded=!MovesStates[m].IsFolded;
}
- if (!m->Folded) {
+ if (!MovesStates[m].IsFolded) {
e.prop |= Property::On;
}
elements.push_back(e);
}
- if (!m->Folded) {
- for (CGEHalfMove *v : m->variations) {
+ if (!MovesStates[m].IsFolded) {
+ for (CMI::HalfMove *v : m->GetVariations()) {
// For each variation show show/hide button
{
Element e;
@@ -313,22 +327,22 @@ std::uint32_t MoveTable::DrawVariations(CGEHalfMove *m, std::uint32_t line,
e.height = e.width;
e.ShouldApplyScroll = true;
if (status->LeftClick && IsMouseOver(e)) {
- v->Hide = !v->Hide;
+ MovesStates[v].IsHidden = !MovesStates[v].IsHidden;
}
- if (!v->Hide) {
+ if (!MovesStates[v].IsHidden) {
e.prop |= Property::On;
}
elements.push_back(e);
}
- if (!v->Hide) {
- line = UpdateMoves(v, line + 1, indent + 1, v->IsBlack);
+ if (!MovesStates[v].IsHidden) {
+ line = UpdateMoves(v, line + 1, indent + 1, v->IsBlack());
} else {
line++;
}
}
}
// New line after variation
- if (m->MainLine != NULL && m->MainLine->IsBlack) {
+ if (m->GetMainline() != nullptr && m->GetMainline()->IsBlack()) {
line++;
}
return (line);
diff --git a/src/components/MoveTable.hpp b/src/components/MoveTable.hpp
index 28ebd12..e357287 100644
--- a/src/components/MoveTable.hpp
+++ b/src/components/MoveTable.hpp
@@ -1,5 +1,6 @@
#include "Component.hpp"
#include <cmath>
+#include <unordered_map>
#define IS_VISIBLE(e) \
(((e.x + status->ScrollX) >= 0 && \
@@ -46,19 +47,25 @@
namespace cgeditor {
class MoveTable : public Component {
- std::uint32_t UpdateMoves(CGEHalfMove *, std::uint32_t, std::uint32_t,bool only_black);
+ typedef struct MoveState {
+ bool IsFolded=false;
+ bool IsHidden=false;
+ } MoveState;
+ std::uint32_t UpdateMoves(CMI::HalfMove *, std::uint32_t, std::uint32_t,bool only_black);
std::int32_t CurrentMove;
std::vector<Element> VariationMargins;
+ /// @brief Must be kept consistent:
+ std::unordered_map<CMI::HalfMove*,MoveState> MovesStates;
bool IsMouseOver(const Element &e) const;
- std::uint32_t DrawComment(CGEHalfMove *m, std::uint32_t line, std::uint32_t indent,
+ std::uint32_t DrawComment(CMI::HalfMove *m, std::uint32_t line, std::uint32_t indent,
const Element &move_bound, const char &indent_black);
- std::uint32_t DrawVariations(CGEHalfMove *m, std::uint32_t line, std::uint32_t indent,
+ std::uint32_t DrawVariations(CMI::HalfMove *m, std::uint32_t line, std::uint32_t indent,
const Element &move_bound,
const char &indent_black);
-
public:
MoveTable(Status *s);
void Refresh();
std::vector<Element> GetVariationsMarging() { return (VariationMargins); }
+ void SyncCache();
};
} // namespace cgeditor \ No newline at end of file