diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CGEHalfMove.cpp | 43 | ||||
| -rw-r--r-- | src/CGEHalfMove.hpp | 41 | ||||
| -rw-r--r-- | src/CGEditor.cpp | 79 | ||||
| -rw-r--r-- | src/CGEditor.hpp | 7 | ||||
| -rw-r--r-- | src/Types.hpp | 12 | ||||
| -rw-r--r-- | src/components/Component.hpp | 1 | ||||
| -rw-r--r-- | src/components/MoveTable.cpp | 100 | ||||
| -rw-r--r-- | src/components/MoveTable.hpp | 15 |
8 files changed, 160 insertions, 138 deletions
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 |
