Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/lib/common/common.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export 'constants.dart';
export 'theme.dart';
export 'theme.dart';
86 changes: 45 additions & 41 deletions example/lib/pages/bar.dart
Original file line number Diff line number Diff line change
@@ -1,68 +1,68 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_fortune_wheel/flutter_fortune_wheel.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';

import '../common/common.dart';
import '../widgets/widgets.dart';

class FortuneBarPage extends HookWidget {
class FortuneBarPage extends StatefulWidget {
static const kRouteName = 'FortuneBarPage';

static void go(BuildContext context) {
context.goNamed(kRouteName);
}

@override
Widget build(BuildContext context) {
final selected = useStreamController<int>();
final selectedIndex = useStream(selected.stream, initialData: 0).data ?? 0;
final isAnimating = useState(false);
final isIndefinite = useState(false);
_FortuneBarPageState createState() => _FortuneBarPageState();
}

void handleRoll() {
if (isIndefinite.value) {
if (isAnimating.value) {
// Stop an ongoing indefinite spin by sending a definitive target
selected.add(roll(Constants.fortuneValues.length));
} else {
// Start indefinite spin
selected.add(Fortune.indefinite);
}
} else {
selected.add(
roll(Constants.fortuneValues.length),
);
class _FortuneBarPageState extends State<FortuneBarPage> {
late StreamController<int> _selected;
int _selectedIndex = 0;
bool _isAnimating = false;

@override
void initState() {
super.initState();
_selected = StreamController<int>.broadcast();
_selected.stream.listen((event) {
if (mounted) {
setState(() {
_selectedIndex = event;
});
}
}
});
}

@override
void dispose() {
_selected.close();
super.dispose();
}

void _handleRoll() {
_selected.add(
roll(Constants.fortuneValues.length),
);
}

@override
Widget build(BuildContext context) {
return AppLayout(
child: Column(
children: [
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Indefinite wait'),
Switch(
value: isIndefinite.value,
onChanged: (v) => isIndefinite.value = v,
),
],
),
SizedBox(height: 8),
RollButtonWithPreview(
selected: selectedIndex,
selected: _selectedIndex,
items: Constants.fortuneValues,
onPressed:
(isIndefinite.value || !isAnimating.value) ? handleRoll : null,
isStopMode: isIndefinite.value && isAnimating.value,
onPressed: _isAnimating ? null : _handleRoll,
),
SizedBox(height: 8),
Expanded(
child: Center(
child: FortuneBar(
selected: selected.stream,
selected: _selected.stream,
items: [
for (var i = 0; i < Constants.fortuneValues.length; i++)
FortuneItem(
Expand All @@ -71,12 +71,16 @@ class FortuneBarPage extends HookWidget {
weight: i.isEven ? 1 : 2,
)
],
onFling: handleRoll,
onFling: _handleRoll,
onAnimationStart: () {
isAnimating.value = true;
setState(() {
_isAnimating = true;
});
},
onAnimationEnd: () {
isAnimating.value = false;
setState(() {
_isAnimating = false;
});
},
),
),
Expand Down
2 changes: 1 addition & 1 deletion example/lib/pages/pages.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export 'bar.dart';
export 'wheel.dart';
export 'wheel.dart';
100 changes: 53 additions & 47 deletions example/lib/pages/wheel.dart
Original file line number Diff line number Diff line change
@@ -1,46 +1,66 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_fortune_wheel/flutter_fortune_wheel.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';

import '../common/common.dart';
import '../widgets/widgets.dart';

class FortuneWheelPage extends HookWidget {
class FortuneWheelPage extends StatefulWidget {
static const kRouteName = 'FortuneWheelPage';

static void go(BuildContext context) {
context.goNamed(kRouteName);
}

@override
Widget build(BuildContext context) {
final alignment = useState(Alignment.topCenter);
final selected = useStreamController<int>();
final selectedIndex = useStream(selected.stream, initialData: 0).data ?? 0;
final isAnimating = useState(false);
final isIndefinite = useState(false);
_FortuneWheelPageState createState() => _FortuneWheelPageState();
}

final alignmentSelector = AlignmentSelector(
selected: alignment.value,
onChanged: (v) => alignment.value = v!,
class _FortuneWheelPageState extends State<FortuneWheelPage> {
Alignment _alignment = Alignment.topCenter;
late StreamController<int> _selected;
int _selectedIndex = 0;
bool _isAnimating = false;

@override
void initState() {
super.initState();
_selected = StreamController<int>.broadcast();
_selected.stream.listen((event) {
if (mounted) {
setState(() {
_selectedIndex = event;
});
}
});
}

@override
void dispose() {
_selected.close();
super.dispose();
}

void _handleRoll() {
_selected.add(
roll(Constants.fortuneValues.length),
);
}

void handleRoll() {
if (isIndefinite.value) {
if (isAnimating.value) {
// Stop an ongoing indefinite spin by sending a definitive target
selected.add(roll(Constants.fortuneValues.length));
} else {
// Start indefinite spin
selected.add(Fortune.indefinite);
@override
Widget build(BuildContext context) {
final alignmentSelector = AlignmentSelector(
selected: _alignment,
onChanged: (v) {
if (v != null) {
setState(() {
_alignment = v;
});
}
} else {
selected.add(
roll(Constants.fortuneValues.length),
);
}
}
},
);

return AppLayout(
child: Padding(
Expand All @@ -49,37 +69,23 @@ class FortuneWheelPage extends HookWidget {
children: [
alignmentSelector,
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Indefinite wait'),
Switch(
value: isIndefinite.value,
onChanged: (v) => isIndefinite.value = v,
),
],
),
SizedBox(height: 8),
RollButtonWithPreview(
selected: selectedIndex,
selected: _selectedIndex,
items: Constants.fortuneValues,
onPressed: (isIndefinite.value || !isAnimating.value)
? handleRoll
: null,
isStopMode: isIndefinite.value && isAnimating.value,
onPressed: _isAnimating ? null : _handleRoll,
),
SizedBox(height: 8),
Expanded(
child: FortuneWheel(
alignment: alignment.value,
selected: selected.stream,
onAnimationStart: () => isAnimating.value = true,
onAnimationEnd: () => isAnimating.value = false,
onFling: handleRoll,
alignment: _alignment,
selected: _selected.stream,
onAnimationStart: () => setState(() => _isAnimating = true),
onAnimationEnd: () => setState(() => _isAnimating = false),
onFling: _handleRoll,
hapticImpact: HapticImpact.heavy,
indicators: [
FortuneIndicator(
alignment: alignment.value,
alignment: _alignment,
child: TriangleIndicator(),
),
],
Expand Down
2 changes: 1 addition & 1 deletion example/lib/widgets/widgets.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export 'alignment_selector.dart';
export 'app_layout.dart';
export 'roll_button.dart';
export 'theme_mode_scope.dart';
export 'theme_mode_scope.dart';
81 changes: 81 additions & 0 deletions example/linux/flutter/ephemeral/flutter_linux/fl_application.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_SHELL_PLATFORM_LINUX_PUBLIC_FLUTTER_LINUX_FL_APPLICATION_H_
#define FLUTTER_SHELL_PLATFORM_LINUX_PUBLIC_FLUTTER_LINUX_FL_APPLICATION_H_

#if !defined(__FLUTTER_LINUX_INSIDE__) && !defined(FLUTTER_LINUX_COMPILATION)
#error "Only <flutter_linux/flutter_linux.h> can be included directly."
#endif

#include "fl_plugin_registry.h"
#include "fl_view.h"

#include <gmodule.h>
#include <gtk/gtk.h>

G_BEGIN_DECLS

G_MODULE_EXPORT
G_DECLARE_DERIVABLE_TYPE(FlApplication,
fl_application,
FL,
APPLICATION,
GtkApplication);

/**
* FlApplicationClass:
* @register_plugins: invoked when plugins should be registered.
*/
struct _FlApplicationClass {
GtkApplicationClass parent_class;

/**
* FlApplication::register_plugins:
* @application: the application
* @registry: registry to use.
*
* The ::register_plugins signal is emitted when plugins can be registered.
*/
void (*register_plugins)(FlApplication* application,
FlPluginRegistry* registry);

/**
* FlApplication::create_window:
* @application: the application
* @view: the view to add to this window.
*
* The ::create_window signal is emitted when a needs to be created for a
* view. By handling this signal the application can create the appropriate
* window for the given view and set any window properties or additional
* widgets required.
*
* If this signal is not handled a standard GTK window will be created.
*/
GtkWindow* (*create_window)(FlApplication* application, FlView* view);
};

/**
* FlApplication:
*
* #Flutter-based application with the GTK embedder.
*
* Provides default behaviour for basic Flutter applications.
*/

/**
* fl_application_new:
* @application_id: (allow-none): The application ID or %NULL.
* @flags: The application flags.
*
* Creates a new Flutter-based application.
*
* Returns: a new #FlApplication
*/
FlApplication* fl_application_new(const gchar* application_id,
GApplicationFlags flags);

G_END_DECLS

#endif // FLUTTER_SHELL_PLATFORM_LINUX_PUBLIC_FLUTTER_LINUX_FL_APPLICATION_H_
Loading
Loading