Skip to content

Commit

Permalink
Merge branch feature/sections_divider into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Alsoxavi committed Nov 26, 2020
2 parents a7e95b5 + ce04aed commit a2e0775
Show file tree
Hide file tree
Showing 13 changed files with 223 additions and 53 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,4 @@ build/
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
.vscode/
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## [0.0.2] - 2020-11-25

* **NEW** now sections have customizable dividers to show its limits.
* **NEW** you can adjust the offset angle of the sections with a `FixedAngle`.
* Updated `example/example.dart`.
* Updated sample images.

## [0.0.1] - 2020-11-24

* First reviewed functional release
* First reviewed functional release.
58 changes: 37 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,39 @@

Control button with adjustable sections

## About this version
## About this package

This widget will allow you to create templates for different kind of controllers.

In this version you can adjust:
- Elevation of the buttons.
- Size of the central button.
- Size of the external buttons.
- Color of the central button.
- Color of the external buttons.
- Change the direction of the shadow.
- Functions of the sections and central button.
### Variables

<img src="images/example.gif"/>
| Variable | Type | Required |
| :---------: | :------: | :---------: |
| `externalDiameter` | _double_ | yes |
| `internalDiameter` | _double_ | yes |
| `mainAction` | _Function_ | yes |
| `sections` | _List<Function>_ | yes |
| `elevation` | _double_ | optional |
| `dividerThickness` | _double_ | optional |
| `externalColor` | _Color_ | optional |
| `internalColor` | _Color_ | optional |
| `dividerColor` | _Color_ | optional |
| `shadowDirection` | _Offset_ | optional |
| `sectionOffset` | _FixedAngles_ | optional |

## Images

| Basic | More Sections | Customizable |
| :---: | :-----------: | :----------: |
| <img src="https://flutter.version-one.com/packages/control_button/basic.gif"/> | <img src="https://flutter.version-one.com/packages/control_button/more_buttons.gif"/> | <img src="https://flutter.version-one.com/packages/control_button/custom.gif"/> |

## Usage

To use this plugin, add `control_button` as a [dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/)

``` dart
dependencies:
control_button: ^0.0.1
control_button: ^0.0.2
```

### Install it
Expand All @@ -43,15 +55,19 @@ See `example/example.dart`

```dart
ControlButton(
sectionOffset: 45,
externalDiameter: 300,
internalDiameter: 120,
mainAction: () => print('Selected Center'),
sections: [
() => print('Selected 1'),
() => print('Selected 2'),
() => print('Selected 3'),
() => print('Selected 4'),
],
sectionOffset: FixedAngles.Zero,
externalDiameter: 300,
internalDiameter: 120,
dividerColor: Colors.blue,
elevation: 2,
externalColor: Colors.lightBlue[100],
internalColor: Colors.grey[300],
mainAction: () => updateState('Selected Center'),
sections: [
() => updateState('Selected 1'),
() => updateState('Selected 2'),
() => updateState('Selected 3'),
() => updateState('Selected 4'),
],
)
```
6 changes: 5 additions & 1 deletion example/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,13 @@ class _MyHomePageState extends State<MyHomePage> {
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ControlButton(
sectionOffset: 45,
sectionOffset: FixedAngles.Zero,
externalDiameter: 300,
internalDiameter: 120,
dividerColor: Colors.blue,
elevation: 2,
externalColor: Colors.lightBlue[100],
internalColor: Colors.grey[300],
mainAction: () => updateState('Selected Center'),
sections: [
() => updateState('Selected 1'),
Expand Down
3 changes: 3 additions & 0 deletions images/basic.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions images/custom.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions images/more_buttons.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion lib/control_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

export 'src/control_button.dart';
export 'src/angles.dart';
export 'src/control_button.dart';
35 changes: 35 additions & 0 deletions lib/src/angles.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:math';

/// FixedAngles enum that includes common angles for the ControlButton.
enum FixedAngles {
Zero,
Rectangular90,
Inclined45,
Inclined120,
Plane180,
}

/// Angles class provides helpers to convert FixedAngles to degrees or radians.
class Angles {
final Map<num, double> _angleMap = const {
0: 0.0,
1: 1.5708,
2: 0.785398,
3: 2.0944,
4: 3.14159,
};

/// fixedToRadian converts an object of class FixedAngles to radians
double fixedToRadian(FixedAngles angle) {
return _angleMap[angle.index];
}

/// fixedToDegrees converts an object of class FixedAngles to degrees
double fixedToDegrees(FixedAngles angle) {
return _angleMap[angle.index] * 180 / pi;
}
}
77 changes: 50 additions & 27 deletions lib/src/control_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,34 @@
// BSD-style license that can be found in the LICENSE file.

import 'package:flutter/material.dart';

import 'angles.dart';
import 'divider.dart';
import 'coordinates_processing.dart';

/// Control button widget
/// Control Button class that extends from StatelessWidget.
class ControlButton extends StatelessWidget {
final double elevation;
final Color dividerColor;
final Color externalColor;
final Color internalColor;
final Function mainAction;
final Offset shadowDirection;
final double externalDiameter;
final double dividerThickness;
final double internalDiameter;
final double sectionOffset;
final List<Function> sections;
final FixedAngles sectionOffset;

/// ControlButton constructor.
/// Required variables: sections<List<Function>>, mainAction<Function>,
/// externalDiameter<double>, internalDiameter<double>.
/// ONLY EVEN NUMBER OF SECTIONS IS POSSIBLE.
ControlButton({
this.elevation = 1.5,
this.sectionOffset = 0,
this.dividerThickness = 1.0,
this.sectionOffset = FixedAngles.Zero,
this.dividerColor = const Color(0x557E7E7E),
this.externalColor = const Color(0xFFF3F3F3),
this.internalColor = const Color(0xFFF3F3F3),
this.shadowDirection = const Offset(0.0, 0.0),
Expand All @@ -29,18 +40,22 @@ class ControlButton extends StatelessWidget {
@required this.internalDiameter,
});

/// ControlButton widget
@override
Widget build(BuildContext context) {
final sectionSize = 360 ~/ sections.length;

return GestureDetector(
onTapDown: (TapDownDetails tapDetails) {
double position = CoordinatesProcessing().getAngle(
new Coordinates(
posx: tapDetails.localPosition.dx,
posy: tapDetails.localPosition.dy,
),
);
sections[position ~/ sectionSize]();
double position = Angles().fixedToDegrees(sectionOffset) +
CoordinatesProcessing().getAngle(
new Coordinates(
posx: tapDetails.localPosition.dx,
posy: tapDetails.localPosition.dy,
),
);
if (position > 360.0) position -= 360.0;
position = sections[position ~/ sectionSize]();
},
child: Container(
width: externalDiameter,
Expand All @@ -57,23 +72,31 @@ class ControlButton extends StatelessWidget {
),
],
),
child: Center(
child: GestureDetector(
onTap: mainAction,
child: Container(
width: internalDiameter,
height: internalDiameter,
decoration: BoxDecoration(
color: internalColor,
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 1,
spreadRadius: elevation,
offset: shadowDirection,
),
],
child: CustomPaint(
painter: PainterClass(
angle: sectionOffset,
sections: sections.length,
dividerColor: dividerColor,
dividerThickness: dividerThickness,
),
child: Center(
child: GestureDetector(
onTap: mainAction,
child: Container(
width: internalDiameter,
height: internalDiameter,
decoration: BoxDecoration(
color: internalColor,
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 1,
spreadRadius: elevation,
offset: shadowDirection,
),
],
),
),
),
),
Expand Down
6 changes: 6 additions & 0 deletions lib/src/coordinates_processing.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,22 @@
import 'dart:math';
import 'package:flutter/foundation.dart';

/// Coordinates class for parsing TapUpDetails elements.
class Coordinates {
final double posx;
final double posy;

/// Coordinates constructor.
Coordinates({
@required this.posx,
@required this.posy,
});
}

/// CoordinatesProcessiong class.
/// Includes functions related to processing elements of the class Coordinates and returns an angle in degrees.
class CoordinatesProcessing {
/// This function uses linear ecuation created from two points to map the input number to the output.
double _numberMap({
@required double input,
@required double inputMin,
Expand All @@ -29,6 +34,7 @@ class CoordinatesProcessing {
outputMin;
}

/// This function converts an objtect of the class Coordinates into an angle in degrees, from the positive x axis.
double getAngle(Coordinates coordinates) {
double position;
double x = _numberMap(
Expand Down
68 changes: 68 additions & 0 deletions lib/src/divider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:flutter/material.dart';

import 'angles.dart';

/// PainterClass class that extends from CustomPainter provides the divisions for the ControlButton.
class PainterClass extends CustomPainter {
final int sections;
final FixedAngles angle;
final Color dividerColor;
final double dividerThickness;

/// PainterClass constructor.
/// You can modify the sections in the ControlButton instance, this will follow along.
PainterClass({
this.sections = 2,
this.dividerThickness = 1.0,
this.angle = FixedAngles.Zero,
this.dividerColor = const Color(0x3377E7E7E),
});

/// Override method on paint to draw in the canvas.
@override
void paint(Canvas canvas, Size size) {
final pinkPaint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = dividerThickness
..color = dividerColor;

_drawSections(
canvas,
sections,
size,
pinkPaint,
Angles().fixedToRadian(angle),
);
}

@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;

/// This functions draws the dividers only horizontally and rotates a defined angle while doing it.
void _drawSections(
Canvas canvas, int sections, Size size, Paint paint, double angleOffset) {
double angle = 6.28319 / sections;

canvas.save();

if (angleOffset != 0.0) {
canvas.translate(size.width / 2, size.height / 2);
canvas.rotate(0.785398);
canvas.translate(-size.width / 2, -size.height / 2);
}

for (int i = 0; i < sections; i++) {
canvas.translate(size.width / 2, size.height / 2);
canvas.rotate(angle);
canvas.translate(-size.width / 2, -size.height / 2);
canvas.drawLine(
Offset(0, size.width / 2), Offset(size.width, size.width / 2), paint);
}

canvas.restore();
}
}
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: control_button
description: Control button with adjustable sections
version: 0.0.1
description: Create a custom Control Button with different sections actions and a central button. Perfect for remote controls or directional input.
version: 0.0.2
homepage: https://flutter.version-one.com

environment:
Expand Down

0 comments on commit a2e0775

Please sign in to comment.