Skip to content

Commit

Permalink
offset grid fix update - 0.1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
orlikraf committed Mar 12, 2021
1 parent cea1f5c commit e3bf84b
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 105 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [0.1.1] - 12.03.2021

* Single row/column offset grids won't have displaces tiles.

## [0.1.0] - 04.02.2021

* Added HexagonGrid
Expand Down
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Add this to your package's pubspec.yaml file:

```yaml
dependencies:
hexagon: ^0.1.0
hexagon: ^0.1.1
```
## Usage
Expand Down Expand Up @@ -81,7 +81,9 @@ If you provide a `buildChild` function it will override any child provided in bu

#### Hexagon Grid
As it is expected this grid is in a shape of hexagon.
Since offset coordinates wouldn't be intuitive in this case HexagonGrid uses cube and axial coordinates systems. You can read about them here: [Cube coordinates](https://www.redblobgames.com/grids/hexagons/#coordinates-cube), [Axial coordinates](https://www.redblobgames.com/grids/hexagons/#coordinates-axial).
Since offset coordinates wouldn't be intuitive in this case HexagonGrid uses cube and axial coordinates systems.
You can read about them here: [Cube coordinates](https://www.redblobgames.com/grids/hexagons/#coordinates-cube), [Axial coordinates](https://www.redblobgames.com/grids/hexagons/#coordinates-axial).

`Coordinates` class combines both of them as they are easily convertible between each other.

```dart
Expand All @@ -91,7 +93,7 @@ Coordinates tileXYZ = Coordinates.cube(x, y, z);
```

`HexagonGrid` requires to be constrained by its parent or else you have to provide at lest one size dimension (width or height). Currently this widget will fit itself to fill given space or best match to given size.
Everything related customize hexagon tiles is similar as in offset grid above.
Everything related to customize hexagon tiles is similar as in offset grid above.

Below example of using `HexagonGrid` with `InteractiveViewer`.

Expand All @@ -118,4 +120,5 @@ InteractiveViewer(
* ~~Margins between tiles in HexagonOffsetGrid~~ (Added padding since `0.0.5`)
* ~~Hexagonal shaped grid (using cube/axial coordinates system)~~ (since 0.1.0)
* Solve content spacing in hexagon widget
* Check performance - any ideas how?
* Check performance - any ideas how?
* null-safety
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.1.0"
version: "0.1.1"
matcher:
dependency: transitive
description:
Expand Down
25 changes: 11 additions & 14 deletions lib/src/grid/coordinates.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import 'dart:math';
///Unified representation of cube and axial coordinates systems.
///
class Coordinates {
Coordinates.cube(this.x, this.y, this.z)
///Cube constructor
const Coordinates.cube(this.x, this.y, this.z)
: assert(x != null),
assert(y != null),
assert(z != null);

///Axial constructor
Coordinates.axial(int q, int r)
: assert(q != null),
assert(r != null),
Expand All @@ -21,6 +23,12 @@ class Coordinates {

int get r => z;

///Distance measured in steps between tiles. A single step is only going over edge of neighbouring tiles.
int distance(Coordinates other) {
return max(
(x - other.x).abs(), max((y - other.y).abs(), (z - other.z).abs()));
}

Coordinates operator +(Coordinates other) {
return Coordinates.cube(x + other.x, y + other.y, z + other.z);
}
Expand All @@ -29,19 +37,15 @@ class Coordinates {
return Coordinates.cube(x - other.x, y - other.y, z - other.z);
}

int distance(Coordinates other) {
return max(
(x - other.x).abs(), max((y - other.y).abs(), (z - other.z).abs()));
}

@override
bool operator ==(Object other) =>
other is Coordinates && other.x == x && other.y == y && other.z == z;

@override
int get hashCode => x ^ y ^ z;

static Coordinates zero = Coordinates.cube(0, 0, 0);
///Constant value of space center
static const Coordinates zero = Coordinates.cube(0, 0, 0);

@override
String toString() => 'Coordinates[cube: ($x, $y, $z), axial: ($q, $r)]';
Expand All @@ -62,10 +66,3 @@ class HexDirections {
static Coordinates flatLeftTop = Coordinates.axial(-1, 0);
static Coordinates flatLeftDown = Coordinates.axial(-1, 1);
}

class Tile<T> {
final Coordinates coordinates;
final T item;

Tile(this.coordinates, this.item);
}
131 changes: 46 additions & 85 deletions lib/src/grid/hexagon_offset_grid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ class HexagonOffsetGrid extends StatelessWidget {
final Widget Function(int col, int row) buildChild;
final HexagonWidgetBuilder Function(int col, int row) buildTile;

int get _displaceColumns => rows > 1 && hexType.isPointy ? 1 : 0;
int get _displaceColumns => hexType.isPointy ? 1 : 0;

int get _displaceRows => columns > 1 && hexType.isFlat ? 1 : 0;
int get _displaceRows => hexType.isFlat ? 1 : 0;

Widget _mainAxis(List<Widget> Function(int count) children) {
return hexType.isPointy
Expand Down Expand Up @@ -227,91 +227,52 @@ class HexagonOffsetGrid extends StatelessWidget {
return Container(
color: color,
padding: edgeInsets,
child: _generateLayout(size),
);
},
);
}
child: _mainAxis(
(mainCount) => List.generate(
mainCount,
(mainIndex) => _crossAxis(
(crossCount) => List.generate(crossCount, (crossIndex) {
if ((crossIndex == 0 || crossIndex >= crossCount - 1) &&
gridType.displace(mainIndex, crossIndex)) {
//return container with half the size of the hexagon for displaced row/column
return Container(
width: (hexType.isPointy && rows > 1)
? size.width / 2
: null,
height: (hexType.isFlat && columns > 1)
? size.height / 2
: null,
);
}
//calculate human readable column & row
final col = (hexType.isPointy
? (crossIndex -
(gridType.displaceFront(mainIndex) ? 1 : 0))
: mainIndex);
final row = hexType.isPointy
? mainIndex
: (crossIndex -
(gridType.displaceFront(mainIndex) ? 1 : 0));

Widget _generateLayout(Size size) {
if (hexType.isPointy && rows == 1) {
return _singleRowPointy(size);
} else if (hexType.isFlat && columns == 1) {
return _singleColumnFlat(size);
}
return _mainAxis(
(mainCount) => List.generate(
mainCount,
(mainIndex) => _crossAxis(
(crossCount) => List.generate(crossCount, (crossIndex) {
if ((crossIndex == 0 || crossIndex >= crossCount - 1) &&
gridType.displace(mainIndex, crossIndex)) {
//return container with half the size of the hexagon for displaced row/column
return Container(
width: hexType.isPointy ? size.width / 2 : null,
height: hexType.isFlat ? size.height / 2 : null,
);
}
//calculate human readable column & row
final col = (hexType.isPointy
? (crossIndex - (gridType.displaceFront(mainIndex) ? 1 : 0))
: mainIndex);
final row = hexType.isPointy
? mainIndex
: (crossIndex - (gridType.displaceFront(mainIndex) ? 1 : 0));

HexagonWidgetBuilder builder = buildTile?.call(col, row) ??
hexagonBuilder ??
HexagonWidgetBuilder();
HexagonWidgetBuilder builder = buildTile?.call(col, row) ??
hexagonBuilder ??
HexagonWidgetBuilder();

//use template values
return builder.build(
hexType,
inBounds: false,
width: hexType.isPointy ? size.width : null,
height: hexType.isFlat ? size.height : null,
child: buildChild?.call(col, row),
replaceChild: buildChild != null,
);
}),
),
),
//use template values
return builder.build(
hexType,
inBounds: false,
width: hexType.isPointy ? size.width : null,
height: hexType.isFlat ? size.height : null,
child: buildChild?.call(col, row),
replaceChild: buildChild != null,
);
}),
),
),
),
);
},
);
}

Widget _singleRowPointy(Size size) {
return Row(
children: List.generate(columns, (col) {
HexagonWidgetBuilder builder =
buildTile?.call(col, 0) ?? hexagonBuilder ?? HexagonWidgetBuilder();

//use template values
return builder.build(
hexType,
inBounds: false,
width: hexType.isPointy ? size.width : null,
height: hexType.isFlat ? size.height : null,
child: buildChild?.call(col, 0),
replaceChild: buildChild != null,
);
}));
}

Widget _singleColumnFlat(Size size) {
return Column(
children: List.generate(rows, (row) {
HexagonWidgetBuilder builder =
buildTile?.call(0, row) ?? hexagonBuilder ?? HexagonWidgetBuilder();

//use template values
return builder.build(
hexType,
inBounds: false,
width: hexType.isPointy ? size.width : null,
height: hexType.isFlat ? size.height : null,
child: buildChild?.call(0, row),
replaceChild: buildChild != null,
);
}));
}
}
3 changes: 3 additions & 0 deletions lib/src/hexagon_type.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:math';

///Enum for hexagon "orientation".
enum HexagonType { FLAT, POINTY }

extension HexagonTypeExtension on HexagonType {
Expand All @@ -12,8 +13,10 @@ extension HexagonTypeExtension on HexagonType {
return _ratioPointy;
}

/// Returns true for POINTY;
bool get isPointy => this == HexagonType.POINTY;

/// Returns true for FLAT;
bool get isFlat => this == HexagonType.FLAT;

double flatFactor(bool inBounds) => (isFlat && inBounds == false) ? 0.75 : 1;
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: hexagon
description: Library about hexagon shape. You can create pointy or flat hexagons in any color you like.
version: 0.1.0
version: 0.1.1
homepage: https://github.com/rSquared-software/flutter-hexagon

environment:
Expand Down

0 comments on commit e3bf84b

Please sign in to comment.