mirror of
https://github.com/flutter/samples.git
synced 2025-11-10 23:08:59 +00:00
[Gallery] Fix directory structure (#312)
This commit is contained in:
36
gallery/lib/layout/adaptive.dart
Normal file
36
gallery/lib/layout/adaptive.dart
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2019 The Flutter team. 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';
|
||||
|
||||
enum DisplayType {
|
||||
desktop,
|
||||
mobile,
|
||||
}
|
||||
|
||||
const _desktopBreakpoint = 700.0;
|
||||
const _smallDesktopMaxWidth = 1000.0;
|
||||
|
||||
/// Returns the [DisplayType] for the current screen. This app only supports
|
||||
/// mobile and desktop layouts, and as such we only have one breakpoint.
|
||||
DisplayType displayTypeOf(BuildContext context) {
|
||||
if (MediaQuery.of(context).size.shortestSide > _desktopBreakpoint) {
|
||||
return DisplayType.desktop;
|
||||
} else {
|
||||
return DisplayType.mobile;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a boolean if we are in a display of [DisplayType.desktop]. Used to
|
||||
/// build adaptive and responsive layouts.
|
||||
bool isDisplayDesktop(BuildContext context) {
|
||||
return displayTypeOf(context) == DisplayType.desktop;
|
||||
}
|
||||
|
||||
/// Returns a boolean if we are in a display of [DisplayType.desktop] but less
|
||||
/// than 1000 width. Used to build adaptive and responsive layouts.
|
||||
bool isDisplaySmallDesktop(BuildContext context) {
|
||||
return isDisplayDesktop(context) &&
|
||||
MediaQuery.of(context).size.width < _smallDesktopMaxWidth;
|
||||
}
|
||||
59
gallery/lib/layout/focus_traversal_policy.dart
Normal file
59
gallery/lib/layout/focus_traversal_policy.dart
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2019 The Flutter team. 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';
|
||||
|
||||
/// [EdgeChildrenFocusTraversalPolicy] can be used to make sure that when you
|
||||
/// are at the last or first focus node inside of a focus scope, we'll request
|
||||
/// focus for given focus node outside of the scope.
|
||||
///
|
||||
/// This can be used to for example make sure that you can request focus outside
|
||||
/// of the MaterialApp you are currently in.
|
||||
class EdgeChildrenFocusTraversalPolicy extends WidgetOrderFocusTraversalPolicy {
|
||||
EdgeChildrenFocusTraversalPolicy({
|
||||
@required this.firstFocusNodeOutsideScope,
|
||||
@required this.lastFocusNodeOutsideScope,
|
||||
this.focusScope,
|
||||
this.firstFocusNodeInsideScope,
|
||||
this.lastFocusNodeInsideScope,
|
||||
}) : assert((focusScope != null &&
|
||||
firstFocusNodeInsideScope == null &&
|
||||
lastFocusNodeInsideScope == null) ||
|
||||
(firstFocusNodeInsideScope != null &&
|
||||
lastFocusNodeInsideScope != null &&
|
||||
focusScope == null));
|
||||
|
||||
final FocusNode firstFocusNodeOutsideScope;
|
||||
final FocusNode lastFocusNodeOutsideScope;
|
||||
|
||||
/// Either provide [focusScope] or both [firstFocusNodeInsideScope]
|
||||
/// and [lastFocusNodeInsideScope].
|
||||
final FocusScopeNode focusScope;
|
||||
final FocusNode firstFocusNodeInsideScope;
|
||||
final FocusNode lastFocusNodeInsideScope;
|
||||
|
||||
@override
|
||||
bool previous(FocusNode currentNode) {
|
||||
if (currentNode ==
|
||||
(firstFocusNodeInsideScope ??
|
||||
focusScope.traversalChildren.toList().first)) {
|
||||
firstFocusNodeOutsideScope.requestFocus();
|
||||
return true;
|
||||
} else {
|
||||
return super.previous(currentNode);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool next(FocusNode currentNode) {
|
||||
if (currentNode ==
|
||||
(lastFocusNodeInsideScope ??
|
||||
focusScope.traversalChildren.toList().last)) {
|
||||
lastFocusNodeOutsideScope.requestFocus();
|
||||
return true;
|
||||
} else {
|
||||
return super.next(currentNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
96
gallery/lib/layout/highlight_focus.dart
Normal file
96
gallery/lib/layout/highlight_focus.dart
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright 2019 The Flutter team. 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 'package:flutter/services.dart';
|
||||
|
||||
/// [HighlightFocus] is a helper widget for giving a child focus
|
||||
/// allowing tab-navigation.
|
||||
/// Wrap your widget as [child] of a [HighlightFocus] widget.
|
||||
class HighlightFocus extends StatefulWidget {
|
||||
const HighlightFocus({
|
||||
@required this.onPressed,
|
||||
@required this.child,
|
||||
this.highlightColor,
|
||||
this.borderColor,
|
||||
this.hasFocus = true,
|
||||
this.debugLabel,
|
||||
});
|
||||
|
||||
/// [onPressed] is called when you press space, enter, or numpad-enter
|
||||
/// when the widget is focused.
|
||||
final VoidCallback onPressed;
|
||||
|
||||
/// [child] is your widget.
|
||||
final Widget child;
|
||||
|
||||
/// [highlightColor] is the color filled in the border when the widget
|
||||
/// is focused.
|
||||
/// Use [Colors.transparent] if you do not want one.
|
||||
/// Use an opacity less than 1 to make the underlying widget visible.
|
||||
final Color highlightColor;
|
||||
|
||||
/// [borderColor] is the color of the border when the widget is focused.
|
||||
final Color borderColor;
|
||||
|
||||
/// [hasFocus] is true when focusing on the widget is allowed.
|
||||
/// Set to false if you want the child to skip focus.
|
||||
final bool hasFocus;
|
||||
|
||||
final String debugLabel;
|
||||
|
||||
@override
|
||||
_HighlightFocusState createState() => _HighlightFocusState();
|
||||
}
|
||||
|
||||
class _HighlightFocusState extends State<HighlightFocus> {
|
||||
bool isFocused;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
isFocused = false;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Color _highlightColor = widget.highlightColor ??
|
||||
Theme.of(context).colorScheme.primary.withOpacity(0.5);
|
||||
Color _borderColor =
|
||||
widget.borderColor ?? Theme.of(context).colorScheme.onPrimary;
|
||||
|
||||
BoxDecoration _highlightedDecoration = BoxDecoration(
|
||||
color: _highlightColor,
|
||||
border: Border.all(
|
||||
color: _borderColor,
|
||||
width: 2,
|
||||
),
|
||||
);
|
||||
|
||||
return Focus(
|
||||
canRequestFocus: widget.hasFocus,
|
||||
debugLabel: widget.debugLabel,
|
||||
onFocusChange: (newValue) {
|
||||
setState(() {
|
||||
isFocused = newValue;
|
||||
});
|
||||
},
|
||||
onKey: (node, event) {
|
||||
if (event is RawKeyDownEvent &&
|
||||
(event.logicalKey == LogicalKeyboardKey.space ||
|
||||
event.logicalKey == LogicalKeyboardKey.enter ||
|
||||
event.logicalKey == LogicalKeyboardKey.numpadEnter)) {
|
||||
widget.onPressed();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
foregroundDecoration: isFocused ? _highlightedDecoration : null,
|
||||
child: widget.child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
42
gallery/lib/layout/text_scale.dart
Normal file
42
gallery/lib/layout/text_scale.dart
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright 2019 The Flutter team. 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';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:gallery/data/gallery_options.dart';
|
||||
|
||||
double _textScaleFactor(BuildContext context) {
|
||||
return GalleryOptions.of(context).textScaleFactor(context);
|
||||
}
|
||||
|
||||
// When text is larger, this factor becomes larger, but at half the rate.
|
||||
//
|
||||
// | Text scaling | Text scale factor | reducedTextScale(context) |
|
||||
// |--------------|-------------------|---------------------------|
|
||||
// | Small | 0.8 | 1.0 |
|
||||
// | Normal | 1.0 | 1.0 |
|
||||
// | Large | 2.0 | 1.5 |
|
||||
// | Huge | 3.0 | 2.0 |
|
||||
|
||||
double reducedTextScale(BuildContext context) {
|
||||
double textScaleFactor = _textScaleFactor(context);
|
||||
return textScaleFactor >= 1 ? (1 + textScaleFactor) / 2 : 1;
|
||||
}
|
||||
|
||||
// When text is larger, this factor becomes larger at the same rate.
|
||||
// But when text is smaller, this factor stays at 1.
|
||||
//
|
||||
// | Text scaling | Text scale factor | cappedTextScale(context) |
|
||||
// |--------------|-------------------|---------------------------|
|
||||
// | Small | 0.8 | 1.0 |
|
||||
// | Normal | 1.0 | 1.0 |
|
||||
// | Large | 2.0 | 2.0 |
|
||||
// | Huge | 3.0 | 3.0 |
|
||||
|
||||
double cappedTextScale(BuildContext context) {
|
||||
double textScaleFactor = _textScaleFactor(context);
|
||||
return max(textScaleFactor, 1);
|
||||
}
|
||||
Reference in New Issue
Block a user