Debug and improve focus and scrollbars code

This commit is contained in:
Loic Guegan 2023-06-07 18:42:50 +02:00
parent 3594a12bb4
commit 7d753ae2d8
4 changed files with 107 additions and 32 deletions

View file

@ -8,6 +8,7 @@ CGEditor::CGEditor() {
MT = new MoveTable(&status);
MA = new Margin(&status);
ME = new Menu(&status);
TF=nullptr;
// Default Standard NagTable: https://en.wikipedia.org/wiki/Numeric_Annotation_Glyphs
status.NagTable[0]="";
status.NagTable[1]="!";
@ -81,6 +82,14 @@ void CGEditor::Draw() {
MA->Refresh();
MT->Refresh();
MA->DrawMargin(MT->GetVariationsMarging());
// Check if we need to focus on a specific move:
if(TF!=nullptr){
double X,Y;
MT->GetMoveXY(TF,X,Y);
SBH->Focus(X+status.MoveWidth);
SBV->Focus(Y+status.MoveHeight);
TF=nullptr;
}
SBV->Refresh();
SBH->Refresh();
ME->Refresh();
@ -181,9 +190,6 @@ std::uint8_t CGEditor::GetNAGId(const std::string& symbol) const{
}
void CGEditor::FocusOnMove(CMI::HalfMove* move){
double X,Y;
MT->GetMoveXY(move,X,Y);
SBH->Focus(X+status.MoveWidth);
SBV->Focus(Y+status.MoveHeight);
TF=move;
}
} // namespace cgeditor

View file

@ -19,6 +19,8 @@ class CGEditor {
MoveTable *MT;
Margin *MA;
Menu *ME;
/// @brief To Focus (TF) move to focus on the next draw (nullptr if not used)
CMI::HalfMove *TF;
protected:
Status status;

View file

@ -1,5 +1,5 @@
#include "Scrollbar.hpp"
#include <iostream>
namespace cgeditor {
Scrollbar::Scrollbar(Status *s, bool IsHorizontal) : Component(s) {
this->IsHorizontal = IsHorizontal;
@ -16,9 +16,8 @@ Scrollbar::Scrollbar(Status *s, bool IsHorizontal) : Component(s) {
DragX = 0;
DragY = 0;
CanvasWidth = 0;
CanvasHeight = 0;
Trigger = false;
ShouldApplyFocus = false;
}
void Scrollbar::Refresh() {
@ -33,23 +32,15 @@ void Scrollbar::Refresh() {
bg.height = status->CanvasHeight - status->ScrollbarWidth;
bar.x = bg.x;
}
// Init default width and height
bar.width = bg.width;
bar.height = bg.height;
// Check if resize, in this case, reset everything (avoid bugs).
// Not that this will be executed during first draw also but it is fine:
if((CanvasWidth != status->CanvasWidth) || (CanvasWidth != status->CanvasWidth)){
status->ScrollX=0;
status->ScrollY=0;
bar.x=bg.x;
bar.y=bg.y;
}
// Compute move table canvas
double MTCanvasHeight = status->CanvasHeight - status->ScrollbarWidth;
double MTCanvasWidth = status->CanvasWidth - status->ScrollbarWidth;
// Configure scrollbar width and height and determined if a scroll must be applied:
bool shouldScroll = false;
if (!IsHorizontal && status->MoveTableMaxY > MTCanvasHeight) {
bar.height =
@ -62,8 +53,60 @@ void Scrollbar::Refresh() {
shouldScroll = true;
}
// Ensure current scroll is valid (moves deletions, canvas resize etc...)
// If not, we correct it now
if(IsHorizontal){
// Check if we should not scroll but still an offset is applied to coordinates:
if(!shouldScroll && status->ScrollX>0){
status->ScrollX=0;
bar.x=bg.x;
}
// Else if we should scroll:
else if(shouldScroll){
double maxScroll=status->MoveTableMaxX-MTCanvasWidth;
// Check if we over scroll:
if((maxScroll+status->ScrollX)<0){
status->ScrollX=-maxScroll;
bar.x=bg.width-bar.width;
}
// If not sensure that scroll bar is at the correct location:
else {
// We add negative sign because ScrollY is negative:
double percent = (-status->ScrollX) / maxScroll;
bar.x=(bg.width - bar.width)*percent;
}
}
else {
status->ScrollX=0;
bar.x=0;
}
} else {
// Here same as previously but for vertical bar!
if(!shouldScroll && status->ScrollY>0){
status->ScrollY=0;
bar.y=bg.y;
}
else if(shouldScroll){
double maxScroll=status->MoveTableMaxY-MTCanvasHeight;
if((maxScroll+status->ScrollY)<0){
status->ScrollY=-maxScroll;
bar.y=bg.height-bar.height;
} else {
double percent = (-status->ScrollY) / maxScroll;
bar.y=(bg.height - bar.height)*percent;
}
} else {
status->ScrollY=0;
bar.y=0;
}
}
// Handle user scroll events:
if (shouldScroll) {
if (IsHorizontal && status->EventHScroll != 0) {
if(ShouldApplyFocus){
ApplyFocus();
}
else if (IsHorizontal && status->EventHScroll != 0) {
double percent = status->EventHScroll / status->MoveTableMaxX;
double maxScroll = bg.width - bar.width;
bar.x += maxScroll * percent;
@ -119,21 +162,20 @@ void Scrollbar::Refresh() {
elements.push_back(bg);
elements.push_back(bar);
// Update cache:
CanvasWidth = status->CanvasWidth;
CanvasHeight = status->CanvasHeight;
ShouldApplyFocus=false;
}
void Scrollbar::Focus(double XorY){
void Scrollbar::ApplyFocus(){
double MTCanvasHeight = status->CanvasHeight - status->ScrollbarWidth;
double MTCanvasWidth = status->CanvasWidth - status->ScrollbarWidth;
// Check horizontal or vertical and if should scroll
if(IsHorizontal && status->MoveTableMaxX > MTCanvasWidth){
// First normalize:
XorY-=MTCanvasWidth; // Do not scroll on first page
XorY=std::max(0.0,XorY); // Ensure focus is greater than 0
XorY=std::min(XorY,(status->MoveTableMaxX-MTCanvasWidth)); // Ensure focus is than scroll max
FocusX-=MTCanvasWidth; // Do not scroll on first page
FocusX=std::max(0.0,FocusX); // Ensure focus is greater than 0
FocusX=std::min(FocusX,(status->MoveTableMaxX-MTCanvasWidth)); // Ensure focus is than scroll max
// Then compute percent and apply scroll
double percent = XorY / (status->MoveTableMaxX-MTCanvasWidth);
double percent = FocusX / (status->MoveTableMaxX-MTCanvasWidth);
status->ScrollX =
-(status->MoveTableMaxX - MTCanvasWidth) * percent;
// Do not forget to update scrollbar:
@ -144,11 +186,11 @@ void Scrollbar::Focus(double XorY){
}
else if(status->MoveTableMaxY > MTCanvasHeight){
// First normalize:
XorY-=MTCanvasHeight; // Do not scroll on first page
XorY=std::max(0.0,XorY); // Ensure focus is greater than 0
XorY=std::min(XorY,(status->MoveTableMaxY-MTCanvasHeight)); // Ensure focus is than scroll max
FocusY-=MTCanvasHeight; // Do not scroll on first page
FocusY=std::max(0.0,FocusY); // Ensure focus is greater than 0
FocusY=std::min(FocusY,(status->MoveTableMaxY-MTCanvasHeight)); // Ensure focus is than scroll max
// Then compute percent and apply scroll
double percent = XorY / (status->MoveTableMaxY-MTCanvasHeight);
double percent = FocusY / (status->MoveTableMaxY-MTCanvasHeight);
status->ScrollY =
-(status->MoveTableMaxY - MTCanvasHeight) * percent;
// Do not forget to update scrollbar:
@ -159,4 +201,23 @@ void Scrollbar::Focus(double XorY){
}
}
void Scrollbar::Focus(double XorY){
if(IsHorizontal)
FocusX=XorY;
else
FocusY=XorY;
ShouldApplyFocus=true;
}
void Scrollbar::Reset(){
if(IsHorizontal){
status->ScrollX=0;
bar.x=bg.x;
}else{
status->ScrollY=0;
bar.y=bg.y;
}
}
} // namespace cgeditor

View file

@ -8,13 +8,19 @@ class Scrollbar : public Component {
bool IsHorizontal;
Element bg,bar;
double DragY,DragX;
double FocusX,FocusY;
/// @brief Should focus be applied on the next draw
bool ShouldApplyFocus;
/// @brief Use to detect scrollbar drags
bool Trigger;
/// @brief Canvas size cache used to reset on resize
double CanvasWidth, CanvasHeight;
/// @brief Goto a given graphical coordinate (if possible using current scroll range)
void ApplyFocus();
public:
Scrollbar(Status* s,bool IsHorizontal);
void Refresh();
/// @brief Goto a given graphical coordinate (if possible using current scroll range)
/// @brief Focus on a coordinate on the next draw
void Focus(double XorY);
/// @brief Undo all scroll operations, go back to the origin
void Reset();
};
} // namespace cgeditor