Skip to content

Commit

Permalink
Introduce YaruClip.diagonal() (#591)
Browse files Browse the repository at this point in the history
Convenient for creating app previews and theme cards etc.

Ref: #580
  • Loading branch information
jpnurmi committed Feb 5, 2023
1 parent 8634e87 commit 123a078
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 0 deletions.
13 changes: 13 additions & 0 deletions example/lib/example_page_items.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:yaru_widgets/yaru_widgets.dart';
import 'pages/banner_page.dart';
import 'pages/carousel_page.dart';
import 'pages/checkbox_page.dart';
import 'pages/clip_page.dart';
import 'pages/color_disk_page.dart';
import 'pages/dialog_page.dart';
import 'pages/draggable_page.dart';
Expand Down Expand Up @@ -66,6 +67,18 @@ final examplePageItems = <PageItem>[
? const Icon(YaruIcons.checkbox_checked_filled)
: const Icon(YaruIcons.checkbox_checked),
),
PageItem(
title: 'YaruClip',
snippetUrl:
'https://raw.githubusercontent.com/ubuntu/yaru_widgets.dart/main/example/lib/pages/clip_page.dart',
pageBuilder: (context) => const ClipPage(),
iconBuilder: (context, selected) => Transform.scale(
scaleX: -1,
child: selected
? const Icon(YaruIcons.network_cellular_signal_excellent)
: const Icon(YaruIcons.network_cellular_signal_none),
),
),
PageItem(
title: 'YaruColorDisk',
snippetUrl:
Expand Down
28 changes: 28 additions & 0 deletions example/lib/pages/clip_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
import 'package:yaru_widgets/yaru_widgets.dart';

class ClipPage extends StatelessWidget {
const ClipPage({super.key});

@override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.all(kYaruPagePadding),
children: [
for (final position in YaruDiagonalClip.values)
YaruTile(
leading: Container(
width: 40,
height: 40,
color: Colors.red,
child: YaruClip.diagonal(
position: position,
child: Container(color: Colors.green),
),
),
title: Text(position.toString()),
),
],
);
}
}
1 change: 1 addition & 0 deletions lib/foundation.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export 'src/foundation/yaru_border_radius.dart';
export 'src/foundation/yaru_clip.dart';
export 'src/foundation/yaru_page_controller.dart';
export 'src/foundation/yaru_window.dart';
92 changes: 92 additions & 0 deletions lib/src/foundation/yaru_clip.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import 'package:flutter/widgets.dart';

/// Describe the position of a diagonal clip.
enum YaruDiagonalClip {
topLeft,
topRight,
bottomLeft,
bottomRight,
}

/// A widget that clips its child using a custom clipper.
///
/// ## Diagonal clip
///
/// ```dart
/// Container(
/// color: Colors.red,
/// child: YaruClip.diagonal(
/// position: YaruDiagonalClip.bottomLeft,
/// child: Container(color: Colors.green),
/// ),
/// )
/// ```
abstract class YaruClip extends StatelessWidget {
const YaruClip._({super.key, this.child});

/// Clips the [child] using a diagonal path at the specified [position].
const factory YaruClip.diagonal({
Key? key,
Widget? child,
required YaruDiagonalClip position,
}) = _YaruDiagonalClip;

final Widget? child;
CustomClipper<Path> get clipper;

@override
Widget build(BuildContext context) {
return ClipPath(
clipper: clipper,
child: child,
);
}
}

class _YaruDiagonalClip extends YaruClip {
const _YaruDiagonalClip({super.key, super.child, required this.position})
: super._();

final YaruDiagonalClip position;

@override
CustomClipper<Path> get clipper => _DiagonalClipper(position);
}

class _DiagonalClipper extends CustomClipper<Path> {
const _DiagonalClipper(this.position);

final YaruDiagonalClip position;

@override
Path getClip(Size size) {
switch (position) {
case YaruDiagonalClip.topLeft:
return Path()
..lineTo(size.width, 0)
..lineTo(0, size.height)
..close();
case YaruDiagonalClip.topRight:
return Path()
..lineTo(size.width, 0)
..lineTo(size.width, size.height)
..close();
case YaruDiagonalClip.bottomLeft:
return Path()
..lineTo(size.width, size.height)
..lineTo(0, size.height)
..close();
case YaruDiagonalClip.bottomRight:
return Path()
..moveTo(size.width, 0)
..lineTo(size.width, size.height)
..lineTo(0, size.height)
..close();
}
}

@override
bool shouldReclip(_DiagonalClipper oldClipper) {
return position != oldClipper.position;
}
}

0 comments on commit 123a078

Please sign in to comment.