feat: add board editor
Closes #458
Opening an early draft PR to let people know I'm working on this.
Functionality that should definitely be part of this PR IMO:
- [x] Move around pieces freely on the board.
- [x] Add a bottom bar to add pieces similar to the old app and lichess.org, selecting a piece in this bar and then tapping a square will add a piece to that square, selecting the bin will remove tapped pieces from the board.
- [x] Button to flip the board
- [x] Buttons for castling rights and for side to play
- [x] Buttons to open position in analysis screen
Functionality that we could add later:
- [x] Drag-and-drop pieces from the bottom bar (see above) onto the board - I'm not sure if this needs adjustments in flutter-chessground as well...? Edit: yes, most definitely
- [x] Discard pieces by dragging them off-screen
- [ ] Load a specific opening as starting position
- [ ] Add button to challenge from built position
- [x] Export position as FEN
@veloce Feedback would be welcome, if you find the time :)
Okay, so after playing around a bit already, it looks to me like most of the board editor logic needs to be added directly to flutter-chessground. Not sure about the "piece-menu" for adding pieces (see above). But if we want to support adding pieces by dragging them from the menu to the board, we probably have to implement this in chessground as well...?
Quick feedback: if we have to modify chessground to support this, the changes should be the simplest and the lightest possible.
Like we should only add "generic" (optional) handlers. Something like:
class BoardEditorOptions {
/// Enable board editor mode
final bool enable;
/// Callback to add or remove a piece on this square id.
final void Function(SquareId squareId)? onTogglePiece;
final void Function(SquareId squareId)? onRemovePiece;
...
}
This is already a significant change because we have to implement the "board editor" logic in the pointer event listener handlers.
Don't know if we can handle drag to board feature like that, but I'd say it is not mandatory to support this so we can figure it out later.
Anyway, changes in chessground shouldn't be more than that.
Quick feedback: if we have to modify chessground to support this, the changes should be the simplest and the lightest possible.
Like we should only add "generic" (optional) handlers. Something like:
class BoardEditorOptions { /// Enable board editor mode final bool enable; /// Callback to add or remove a piece on this square id. final void Function(SquareId squareId)? onTogglePiece; final void Function(SquareId squareId)? onRemovePiece; ... }This is already a significant change because we have to implement the "board editor" logic in the pointer event listener handlers.
Don't know if we can handle drag to board feature like that, but I'd say it is not mandatory to support this so we can figure it out later.
Anyway, changes in chessground shouldn't be more than that.
Thanks for the quick reply! However, after playing around with the code a bit yesterday, I'm not a 100% sure if it's really the best idea to modify the Board class for this:
-
The
Boardhas a lot of parameters and logic related to them which are not relevant in board editor mode, such as drawing shapes, premoves, highlighting squares, thesideToMovevariable, ... I tried to add aeditorModeflag (similar to theBoardEditorSettingsyou described above), and it quickly got messy, with a lof ofif (!editorMode)at various places. -
Even if we get this to work, we still have to take care of disabling some rules, like castling. Currently, the
Boarddoes not modify itself, but rather calls theonMovecallback, which then will call something likeposition.playUnchecked()- There's currently no way to disable castling for this method, so we'd need to modifydartchessas well probably. If we had a dedicatedBoardEditorwidget that could simply modify the position by itself when a move is played, we wouldn't have these problems.
So maybe adding a separate BoardEditor widget makes sense? Or do you think we'd have too much code duplication in this case?
@veloce I added a quick proof of concept implementing a basic board editor (minus adding new pieces) by adding a new BoardEditor widget: https://github.com/lichess-org/flutter-chessground/pull/40
Yeah totally, a separate BoardEditor is the way to go. Thanks for tackling this!
Now there is still the question of the chessground API. I haven't had much time to think about it, but I still think the chessground package should only expose a lightweight API that would allows package users to build a full-fledged board editor.
Meaning we shouldn't build the full-fledged board editor inside chessground, but rather provide ways to do it through the BoardEditor widget and its callbacks.
The reason behind this is that we don't want to maintain a full-fledged editor in an external package. Because there is no limit in terms of what a board editor can be in terms of feature, the majority of the UI should be implemented in the app and chessground should just take care of what is going on inside the board.
Thanks for taking a look, I really appreciate the quick feedback!
Yeah I agree with that, the BoardEditor widget in the chessground PR really should be minimal, with the rest (e.g. the piece menu) being implemented by library consumers. I think the draft in the PR is a good start, the only things it's missing are (off the top of my head) addPiece() and removePiece() methods, and also callbacks like clickedSquare and draggedOntoSquare. Probably also a getter that calculates the current FEN.
I'd suggest that I add the missing API described above and clean up and document the code a bit more (maybe reduce some more duplication). Then when I mark it as "Ready To Review", you can take a closer look and we can continue the discussion over at flutter-chessground.
@tom-anders I think you can start working on this using a local chessground plugin based on current main, if you don't mind?
I'll publish the 4.0.0 version later when I had the chance to test this.
@tom-anders I think you can start working on this using a local chessground plugin based on current
main, if you don't mind?I'll publish the 4.0.0 version later when I had the chance to test this.
Sure!
@veloce There are a lot of API breaks to be fixed when updating to the main branch, so I'll think for now I'll stick with a commit before those breaks. Let me know when the API breaks are fixed in the mobile repo (or even if you just have a branch ready that I can rebase onto).
Okay, so here's what I got so far. The code is not cleaned up yet, but I think it has all the basic feature we need. Right now, I'm mainly looking for design feedback:
- Menu/Button structure
- Which colors do we want to use for the piece menu? Same as lichess.org/editor? Or stick with material color palette?
- I think we want to at least have the same icons as lichess.org/editor, namely the pointer and the trash icon. I found them here: https://github.com/lichess-org/lila/tree/8dec1e4c8223483b29e95638ceed56365dbd4a66/public/images/icons What's the process for adding new lichess icons to the app?
@veloce There are a lot of API breaks to be fixed when updating to the main branch, so I'll think for now I'll stick with a commit before those breaks. Let me know when the API breaks are fixed in the
mobilerepo (or even if you just have a branch ready that I can rebase onto).
I'm ok if you fix the API breaks in this PR. These are only name changes so it should be straightforward to fix.
Thanks for your work @tom-anders , it looks great already!
Here's my feedback:
- I think we should use the material color palette for the piece menu, trying to find a contrasting color that looks good
- I don't understand the bottom left button; is it to reverse the board? then we should use the existing button from the TV screen
- I don't think we need the same trash and pointer icons as lichess website.
- I agree they don't look that good right now but we can improve that I think:
- You can try the Cupertino hand icon: https://api.flutter.dev/flutter/cupertino/CupertinoIcons/hand_draw-constant.html
- and delete: https://api.flutter.dev/flutter/cupertino/CupertinoIcons/delete-constant.html
- which kind of look better
- Not sure the settings button is the best placed here at the top right:
- it's not a real settings button, it is more the settings of the position; a real settings button would be for settings controlling the editor itself
- I'd try to find another icon more appropriate
- and put it in the bottom bar instead
Thanks for the feedback, ready for code review now!
* I think we should use the material color palette for the piece menu, trying to find a contrasting color that looks good
Yeah I'm using plain Color.grey, Color.green, Color.blue and Color.red for now. I saw on Discord that someone wanted to help with the app's design, so maybe they can take a look at what colors we should use?
* I don't understand the bottom left button; is it to reverse the board? then we should use the existing button from the TV screen
Yep, wrong icon, fixed now
* I don't think we need the same trash and pointer icons as lichess website. * I agree they don't look that good right now but we can improve that I think: * You can try the Cupertino hand icon: https://api.flutter.dev/flutter/cupertino/CupertinoIcons/hand_draw-constant.html * and delete: https://api.flutter.dev/flutter/cupertino/CupertinoIcons/delete-constant.html * which kind of look better
Done, I scaled down the icons a bit so that they match the piece size.
* Not sure the settings button is the best placed here at the top right: * it's not a real settings button, it is more the settings of the position; a real settings button would be for settings controlling the editor itself * I'd try to find another icon more appropriate * and put it in the bottom bar instead
It uses the "menu" icon now and has been moved to the bottom bar.
Yeah I'm using plain Color.grey, Color.green, Color.blue and Color.red for now.
That is not the material color palette I meant, sorry for the confusion. What you want to use is the ColorScheme.
I just published chessground 4.0.0 to pub.dev @tom-anders .
I think you want to update your PR with that version. There are other breaking changes, sorry for that, but it should not be too hard to fix them. Here's a summary:
- dartchess
Squareis now an extension type so we gain convenient methods at no cost - chessground now uses all the dartchess types, including
Square. There is no more need forchessground_compat.dart - importing
dartchessandchessgroundwith prefixes is no more useful and should be avoided.
Nice work!
Uses chessground 4.0.0 now, fixing all API breaks. Also rebased against main
Thanks again for the quick and valuable feedback! Implementing this was really fun
Hey @tom-anders great work on this again.
- Would it make sense to have a "clear board" option similar to how web has one? If there was a menu that would be easy but if you are trying to avoid a menu, perhaps holding down the trash-can?
- Out of curiosity, how seamless easy would it be to have an option if you're in the analysis board tool to have it become editable? On web, that option exists. Technically you can just grab the fen/pgn and then load position and choose board editor option but just curious if you could simply but easily enter board editor mode directly from analysis board without much configuration
1. Would it make sense to have a "clear board" option similar to how web has one? If there was a menu that would be easy but if you are trying to avoid a menu, perhaps holding down the trash-can?
Yeah, what's still missing is a "Load Position" menu, where you can set the board to a specific opening or endgame position. We could also have a "Clear Board" entry in that list (I think the old app does as well).
2. Out of curiosity, how seamless easy would it be to have an option if you're in the analysis board tool to have it become editable? On web, that option exists. Technically you can just grab the fen/pgn and then load position and choose board editor option but just curious if you could simply but easily enter board editor mode directly from analysis board without much configuration
Yeah sounds useful, shouldn't be too hard to implement.
I'll open Github issues for both of these features, I think these are "Good first issue" candidates