croupier: Improve the UI for the Play Phase
Now shows only a single person's cards. Shows them sorted by suit.
And also sorted by value. The comparator can be changed based on the game.
Missing:
- width is set to 0 when the full flex is empty since you can't set min-width
- sky is set to 0.0.41 because later on drag and drop starts to break.
- sky_viewer is still not working. It seems that it's not allowed to draw.
Change-Id: I11eac0c3f36f5ddf25b1002ab36aa0bd0e56f1e8
diff --git a/lib/components/card_collection.dart b/lib/components/card_collection.dart
index 6456bb9..7d649f4 100644
--- a/lib/components/card_collection.dart
+++ b/lib/components/card_collection.dart
@@ -8,7 +8,7 @@
import 'package:sky/widgets.dart';
import 'package:sky/theme/colors.dart' as colors;
-enum Orientation { vert, horz, fan, show1 }
+enum Orientation { vert, horz, fan, show1, suit }
enum DropType {
none,
card,
@@ -23,12 +23,13 @@
Function parentCallback;
bool dragChildren;
DropType acceptType;
+ Function comparator;
String status = 'bar';
CardCollectionComponent(
this.cards, this.faceUp, this.orientation, this.parentCallback,
- {this.dragChildren: false, this.acceptType: DropType.none});
+ {this.dragChildren: false, this.acceptType: DropType.none, this.comparator: null});
void syncConstructorArguments(CardCollectionComponent other) {
cards = other.cards;
@@ -37,6 +38,7 @@
parentCallback = other.parentCallback;
dragChildren = other.dragChildren;
acceptType = other.acceptType;
+ comparator = other.comparator;
}
bool _handleWillAccept(dynamic data) {
@@ -61,25 +63,100 @@
});
}
- List<Widget> flexCards(List<Widget> cardWidgets) {
+ List<logic_card.Card> get _sortedCards {
+ assert(this.comparator != null);
+ List<logic_card.Card> cs = new List<logic_card.Card>();
+ cs.addAll(this.cards);
+ cs.sort(comparator);
+ return cs;
+ }
+
+ List<Widget> flexChildren(List<Widget> children) {
List<Widget> flexWidgets = new List<Widget>();
- cardWidgets.forEach(
- (cardWidget) => flexWidgets.add(new Flexible(child: cardWidget)));
+ children.forEach(
+ (child) => flexWidgets.add(new Flexible(child: child)));
return flexWidgets;
}
+ // returns null if it's up to the container (like a Flex) to figure this out.
+ double get desiredHeight {
+ switch (this.orientation) {
+ case Orientation.vert:
+ return null;
+ case Orientation.horz:
+ case Orientation.fan:
+ case Orientation.show1:
+ return 60.0;
+ case Orientation.suit:
+ return 240.0;
+ default:
+ assert(false);
+ return null;
+ }
+ }
+
+ // returns null if it's up to the container (like a Flex) to figure this out.
+ double get desiredWidth {
+ switch (this.orientation) {
+ case Orientation.vert:
+ case Orientation.show1:
+ return 60.0;
+ case Orientation.horz:
+ case Orientation.fan:
+ case Orientation.suit:
+ return null;
+ default:
+ assert(false);
+ return null;
+ }
+ }
+
Widget wrapCards(List<Widget> cardWidgets) {
switch (this.orientation) {
case Orientation.vert:
- return new Flex(flexCards(cardWidgets),
+ return new Flex(flexChildren(cardWidgets),
direction: FlexDirection.vertical);
case Orientation.horz:
- return new Flex(flexCards(cardWidgets));
+ return new Flex(flexChildren(cardWidgets));
case Orientation.fan:
// unimplemented, so we'll fall through to show1, for now.
// Probably a Stack + Positioned
case Orientation.show1:
return new Stack(cardWidgets);
+ case Orientation.suit:
+ if (cards.length == 0) {
+ return new Stack(cardWidgets);
+ }
+ List<Widget> cs = new List<Widget>();
+ List<Widget> ds = new List<Widget>();
+ List<Widget> hs = new List<Widget>();
+ List<Widget> ss = new List<Widget>();
+
+ List<logic_card.Card> theCards =
+ this.comparator != null ? this._sortedCards : this.cards;
+ for (int i = 0; i < theCards.length; i++) {
+ // Group by suit. Then sort.
+ logic_card.Card c = theCards[i];
+ switch(c.identifier[0]) {
+ case 'c':
+ cs.add(cardWidgets[i]);
+ break;
+ case 'd':
+ ds.add(cardWidgets[i]);
+ break;
+ case 'h':
+ hs.add(cardWidgets[i]);
+ break;
+ case 's':
+ ss.add(cardWidgets[i]);
+ break;
+ default:
+ assert(false);
+ }
+ }
+ return new Flex(flexChildren(<Widget>[
+ new Flex(flexChildren(cs)), new Flex(flexChildren(ds)), new Flex(flexChildren(hs)), new Flex(flexChildren(ss))
+ ]), direction: FlexDirection.vertical);
default:
assert(false);
return null;
@@ -104,8 +181,10 @@
// https://github.com/domokit/sky_engine/blob/master/sky/packages/sky/lib/src/widgets/sizing.md
cardComponents.add(new Text("")); // new Text(status)
}
- for (int i = 0; i < cards.length; i++) {
- component_card.Card c = new component_card.Card(cards[i], faceUp);
+ List<logic_card.Card> cs = this.comparator != null ? this._sortedCards : this.cards;
+
+ for (int i = 0; i < cs.length; i++) {
+ component_card.Card c = new component_card.Card(cs[i], faceUp);
if (dragChildren) {
cardComponents.add(new Draggable<component_card.Card>(c));
@@ -123,7 +202,8 @@
decoration: new BoxDecoration(
border: new Border.all(width: 3.0, color: colors.white),
backgroundColor: colors.Grey[500]),
- height: 80.0,
+ height: this.desiredHeight,
+ width: this.desiredWidth,
margin: new EdgeDims.all(10.0),
child: wrapCards(cardComponents));
case DropType.card:
@@ -137,7 +217,8 @@
color: data.isEmpty ? colors.white : colors.Blue[500]),
backgroundColor:
data.isEmpty ? colors.Grey[500] : colors.Green[500]),
- height: 80.0,
+ height: this.desiredHeight,
+ width: this.desiredWidth,
margin: new EdgeDims.all(10.0),
child: wrapCards(cardComponents));
});
@@ -152,7 +233,8 @@
color: data.isEmpty ? colors.white : colors.Blue[500]),
backgroundColor:
data.isEmpty ? colors.Grey[500] : colors.Green[500]),
- height: 80.0,
+ height: this.desiredHeight,
+ width: this.desiredWidth,
margin: new EdgeDims.all(10.0),
child: wrapCards(cardComponents));
});
diff --git a/lib/components/game.dart b/lib/components/game.dart
index cb634d4..a1c67c2 100644
--- a/lib/components/game.dart
+++ b/lib/components/game.dart
@@ -167,6 +167,15 @@
});
}
+ int _compareCards(logic_card.Card a, logic_card.Card b) {
+ if (a == b) return 0;
+ assert(a.deck == "classic" && b.deck == "classic");
+ HeartsGame game = this.game as HeartsGame;
+ int r = game.getCardSuit(a).compareTo(game.getCardSuit(b));
+ if (r != 0) return r;
+ return game.getCardValue(a) < game.getCardValue(b) ? -1 : 1;
+ }
+
// This shouldn't always be here, but for now, we have little choice.
void _switchPlayersCallback() {
setState(() {
@@ -262,14 +271,14 @@
List<Widget> cardCollections = new List<Widget>();
cardCollections.add(new Text(game.debugString));
+ cardCollections.add(new Text("Player ${game.whoseTurn}'s turn"));
- for (int i = 0; i < 4; i++) {
- List<logic_card.Card> cards = game.cardCollections[i];
- CardCollectionComponent c = new CardCollectionComponent(cards,
- game.playerNumber == i, Orientation.horz, _makeGameMoveCallback,
- dragChildren: game.whoseTurn == i);
- cardCollections.add(c); // flex
- }
+ int i = game.playerNumber;
+ List<logic_card.Card> cards = game.cardCollections[i];
+ CardCollectionComponent c = new CardCollectionComponent(cards,
+ game.playerNumber == i, Orientation.suit, _makeGameMoveCallback,
+ dragChildren: game.whoseTurn == i, comparator: _compareCards);
+ cardCollections.add(c); // flex
List<Widget> plays = new List<Widget>();
for (int i = 0; i < 4; i++) {
@@ -365,7 +374,7 @@
dragChildren: !hasPassed, acceptType: DropType.card)),
new CardCollectionComponent(
remainingCards, true, Orientation.horz, _uiPassCardCallback,
- dragChildren: !hasPassed, acceptType: DropType.card),
+ dragChildren: !hasPassed, acceptType: DropType.card, comparator: _compareCards),
_makeDebugButtons()
], direction: FlexDirection.vertical));
}
@@ -392,7 +401,7 @@
take,
new CardCollectionComponent(
playerCards, true, Orientation.horz, _makeGameTakeCallback,
- dragChildren: true, acceptType: DropType.card_collection),
+ dragChildren: true, acceptType: DropType.card_collection, comparator: _compareCards),
_makeDebugButtons()
], direction: FlexDirection.vertical));
}
diff --git a/pubspec.yaml b/pubspec.yaml
index d23cca5..8a9341d 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,7 +1,9 @@
name: your_app_name
dependencies:
- sky: any
+ sky: 0.0.41
sky_tools: any
+ sky_engine: 0.0.18
+ sky_services: 0.0.18
test: any
ether: any
dependency_overrides: