This commit is contained in:
tzw
2021-09-11 10:32:50 +06:30
75 changed files with 1112 additions and 522 deletions

View File

@@ -39,7 +39,7 @@ class _CargoTypeEditorState extends State<CargoTypeEditor> {
_loadDefalut() {
ShipmentRateModel shipmentRateModel =
Provider.of<ShipmentRateModel>(context, listen: false);
_cargo = shipmentRateModel.rate.defaultCargoType?.clone();
_cargo = shipmentRateModel.rate.defaultCargoType.clone();
}
@override

View File

@@ -171,7 +171,7 @@ class PartSearchDelegate extends SearchDelegate<Carton> {
// }
try {
String barcode = await scanBarcode();
String? barcode = await scanBarcode();
if (barcode != null) {
query = barcode;
showResults(context);

View File

@@ -103,10 +103,10 @@ class _InvoiceEditorState extends State<InvoiceEditor> {
_loadShipments() async {
ShipmentModel shipmentModel =
Provider.of<ShipmentModel>(context, listen: false);
List<Shipment> shipments = await shipmentModel.getShipmentWithHandlingFee(
List<Shipment?>? shipments = await shipmentModel.getShipmentWithHandlingFee(
widget.fcsShipment!.id!, widget.customer!.id!);
shipments.forEach((s) {
s.isSelected = true;
shipments!.forEach((s) {
s!.isSelected = true;
});
setState(() {
_invoice!.shipments = shipments;
@@ -380,8 +380,8 @@ class _InvoiceEditorState extends State<InvoiceEditor> {
if (shipment == null) return;
shipment.isSelected = true;
setState(() {
_invoice!.shipments.remove(shipment);
_invoice!.shipments.add(shipment);
_invoice!.shipments!.remove(shipment);
_invoice!.shipments!.add(shipment);
});
}
@@ -389,8 +389,8 @@ class _InvoiceEditorState extends State<InvoiceEditor> {
if (shipment == null) return;
shipment.isSelected = false;
setState(() {
_invoice!.shipments.remove(shipment);
_invoice!.shipments.add(shipment);
_invoice!.shipments!.remove(shipment);
_invoice!.shipments!.add(shipment);
});
}
@@ -431,7 +431,7 @@ class _InvoiceEditorState extends State<InvoiceEditor> {
invoice.handlingFee = _invoice!.getHandlingFee();
invoice.cartons = _invoice!.cartons.where((c) => c.isChecked!).toList();
invoice.shipments =
_invoice!.shipments.where((s) => s.isSelected).toList();
_invoice!.shipments!.where((s) => s!.isSelected).toList();
invoice.discount = _invoice!.discount;
invoice.deliveryFee = _invoice!.deliveryFee;

View File

@@ -9,7 +9,7 @@ typedef OnAdd(Shipment shipment);
typedef OnRemove(Shipment shipment);
class InvoiceHandlingFeeList extends StatelessWidget {
final List<Shipment>? shipments;
final List<Shipment?>? shipments;
final OnAdd? onAdd;
final OnRemove? onRemove;
@@ -72,7 +72,7 @@ class InvoiceHandlingFeeList extends StatelessWidget {
onSelectChanged: (value) => Navigator.pop(context, c),
cells: [
MyDataCell(new Text(
c.shipmentNumber!,
c!.shipmentNumber!,
style: textStyle,
)),
MyDataCell(

View File

@@ -39,8 +39,8 @@ class _InvoiceInfoState extends State<InvoiceInfo> {
void initState() {
super.initState();
_invoice = widget.invoice!;
_invoice!.shipments.forEach((s) {
s.isSelected = true;
_invoice!.shipments!.forEach((s) {
s!.isSelected = true;
});
_loadCartons();
}

View File

@@ -70,11 +70,11 @@ class InvoiceTable extends StatelessWidget {
"${c.calWeight.toStringAsFixed(2)} x ${c.calRate.toStringAsFixed(2)}",
amount: "${c.calAmount.toStringAsFixed(2)}"));
});
invoice!.shipments.where((ss) => (ss.isSelected )).forEach((s) {
invoice!.shipments!.where((ss) => (ss!.isSelected )).forEach((s) {
tableRows.add(InvoiceTableRow(
data: s,
invoiceDataType: InvoiceDataType.HandlingFeeType,
desc: "Handling fee\n${s.shipmentNumber}",
desc: "Handling fee\n${s!.shipmentNumber}",
rate: "",
amount: "${s.handlingFee.toStringAsFixed(2)}"));
});

View File

@@ -260,7 +260,7 @@ class PackageModel extends BaseModel {
}
Future<void> createReceiving(
User user, Package package, List<File> files) async {
User user, Package package, List<File?> files) async {
if (user != null) {
package.fcsID = user.fcsID;
}
@@ -288,22 +288,21 @@ class PackageModel extends BaseModel {
}
}
Future<void> updateReceiving(User user, Package package, List<File> files,
List<String> deletedUrls) async {
Future<void> updateReceiving(User user, Package package, List<File?> files,
List<String?> deletedUrls) async {
if (user != null) {
package.fcsID = user.fcsID;
}
if (deletedUrls != null) {
for (String url in deletedUrls) {
for (String? url in deletedUrls) {
package.photoUrls.remove(url);
}
}
List<String> uploadedURL = [];
if (files != null) {
var count = (package.photoUrls?.length ?? 0) +
files.length -
(deletedUrls?.length ?? 0);
var count =
(package.photoUrls.length) + files.length - (deletedUrls.length);
if (count > uploadPhotoLimit)
throw Exception("Exceed number of file upload");
@@ -333,18 +332,17 @@ class PackageModel extends BaseModel {
}
Future<void> updateProcessing(
Package package, List<File> files, List<String> deletedUrls) async {
Package package, List<File?> files, List<String?> deletedUrls) async {
if (deletedUrls != null) {
for (String url in deletedUrls) {
for (String? url in deletedUrls) {
package.photoUrls.remove(url);
}
}
List<String> uploadedURL = [];
if (files != null) {
var count = (package.photoUrls?.length ?? 0) +
files.length -
(deletedUrls?.length ?? 0);
var count =
(package.photoUrls.length) + files.length - (deletedUrls.length);
if (count > uploadPhotoLimit)
throw Exception("Exceed number of file upload");

View File

@@ -164,7 +164,7 @@ class _TrackingIDPageState extends State<TrackingIDPage> {
// }
try {
String barcode = await scanBarcode();
String? barcode = await scanBarcode();
if (barcode != null) {
setState(() {
_transcationIDCtl.text = barcode;

View File

@@ -147,7 +147,7 @@ class PackageSearchDelegate extends SearchDelegate<Package> {
// Barcode bc = barcodes.firstWhere((element) => true);
// String barcode;
// if (bc != null) barcode = bc.rawValue;
String barcode = await scanBarcode();
String? barcode = await scanBarcode();
if (barcode != null) {
query = barcode;
showResults(context);

View File

@@ -80,7 +80,7 @@ class _ProfileState extends State<Profile> {
);
final phonenumberbox = DisplayText(
text: mainModel.user!.phone ?? "",
text: mainModel.user!.phone,
labelTextKey: "profile.phone",
iconData: Icons.phone,
);

View File

@@ -36,7 +36,7 @@ class _CustomEditorState extends State<CustomEditor> {
_productController.text = _custom.name??"";
_feeController.text = _custom.customDutyFee.toStringAsFixed(2);
_shipmentRateController.text =
_custom.rate == null ? "" : _custom.rate?.toStringAsFixed(2) ?? '';
_custom.rate == null ? "" : _custom.rate.toStringAsFixed(2);
} else {
_isNew = true;
}

View File

@@ -86,7 +86,7 @@ class _CustomListState extends State<CustomList> {
custom.rate == null
? ""
: "Shipment rate \$ " +
custom.rate!.toStringAsFixed(2)),
custom.rate.toStringAsFixed(2)),
),
);
}),

View File

@@ -62,11 +62,11 @@ class _ShipmentRatesCalState extends State<ShipmentRatesCal> {
var amount = box.calAmount(rate);
var shipmentWeight = box.getShipmentWeight(rate.volumetricRatio);
var effectiveWeight =
_cargoType.weight! > shipmentWeight ? _cargoType.weight : shipmentWeight;
_cargoType.weight > shipmentWeight ? _cargoType.weight : shipmentWeight;
setState(() {
_deliveryFee =
effectiveWeight! > rate.freeDeliveryWeight ? 0 : rate.deliveryFee;
effectiveWeight > rate.freeDeliveryWeight ? 0 : rate.deliveryFee;
_amount = amount == null ? 0 : amount + _deliveryFee;
_shipmentWeight = shipmentWeight.toDouble();
});

View File

@@ -212,7 +212,7 @@ class _ReceivingEditorState extends State<ReceivingEditor> {
// }
try {
String barcode = await scanBarcode();
String? barcode = await scanBarcode();
if (barcode != null) {
setState(() {
_trackingIDCtl.text = barcode;

View File

@@ -56,7 +56,7 @@ class _ShipmentAssignState extends State<ShipmentAssign> {
_selectedShipmentType = _shipment!.shipmentType;
_fromTimeEditingController.text = _shipment!.pickupTimeStart!;
_toTimeEditingController.text = _shipment!.pickupTimeEnd!;
_pickupDate.text = dateFormatter.format(_shipment!.pickupDate! ?? now);
_pickupDate.text = dateFormatter.format(_shipment!.pickupDate ?? now);
_handlingFee.text = _shipment!.handlingFee != null
? _shipment!.handlingFee.toString()
: "0";

View File

@@ -37,7 +37,7 @@ class _ShipmentConfirmState extends State<ShipmentConfirm> {
super.initState();
_shipment = widget.shipment;
_handlingFee.text = _shipment!.handlingFee?.toString() ?? "0";
_handlingFee.text = _shipment!.handlingFee.toString();
}
@override

View File

@@ -223,7 +223,7 @@ class _ShipmentInfoState extends State<ShipmentInfo> {
iconData: MaterialCommunityIcons.worker);
var handlingFeeBox = DisplayText(
labelTextKey: "shipment.handling.fee",
text: (_shipment!.handlingFee ?? 0).toString(),
text: (_shipment!.handlingFee).toString(),
iconData: FontAwesome.truck);
final assignCompleteBtn = LocalButton(

View File

@@ -8,27 +8,28 @@ import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart';
import 'package:provider/provider.dart';
import 'package:zefyr/zefyr.dart';
// import 'package:zefyr/zefyr.dart';
typedef void ProfileCallback();
class TermEdit extends StatefulWidget {
final Term term;
TermEdit({this.term});
TermEdit({required this.term});
@override
_TermEditState createState() => _TermEditState();
}
class _TermEditState extends State<TermEdit> {
/// Allows to control the editor and the document.
ZefyrController _controllerEng;
ZefyrController _controllerMm;
// ZefyrController _controllerEng;
// ZefyrController _controllerMm;
/// Zefyr editor like any other input field requires a focus node.
FocusNode _focusNodeEng;
FocusNode _focusNodeMm;
bool _isLoading;
// FocusNode _focusNodeEng;
// FocusNode _focusNodeMm;
bool _isLoading = false;
@override
void initState() {
@@ -36,23 +37,23 @@ class _TermEditState extends State<TermEdit> {
_isLoading = false;
// Here we must load the document and pass it to Zefyr controller.
_controllerEng = ZefyrController(_loadDocument(widget.term.termEng));
_controllerMm = ZefyrController(_loadDocument(widget.term.termMm));
_focusNodeEng = FocusNode();
_focusNodeMm = FocusNode();
// _controllerEng = ZefyrController(_loadDocument(widget.term.termEng));
// _controllerMm = ZefyrController(_loadDocument(widget.term.termMm));
// _focusNodeEng = FocusNode();
// _focusNodeMm = FocusNode();
}
/// Loads the document to be edited in Zefyr.
NotusDocument _loadDocument(String data) {
NotusDocument doc;
try {
doc = NotusDocument.fromJson(jsonDecode(data));
} catch (e) {}
if (doc == null) {
doc = NotusDocument();
}
return doc;
}
// NotusDocument _loadDocument(String data) {
// NotusDocument doc;
// try {
// doc = NotusDocument.fromJson(jsonDecode(data));
// } catch (e) {}
// if (doc == null) {
// doc = NotusDocument();
// }
// return doc;
// }
@override
Widget build(BuildContext context) {
@@ -115,8 +116,8 @@ class _TermEditState extends State<TermEdit> {
height: MediaQuery.of(context).size.height - 200,
child: TabBarView(
children: [
textEditor(_controllerEng, _focusNodeEng),
textEditor(_controllerMm, _focusNodeMm),
// textEditor(_controllerEng, _focusNodeEng),
// textEditor(_controllerMm, _focusNodeMm),
],
),
),
@@ -128,35 +129,35 @@ class _TermEditState extends State<TermEdit> {
);
}
Widget textEditor(ZefyrController controller, FocusNode focusNode) {
return ListView(
children: [
Container(
height: MediaQuery.of(context).size.height - 200,
child: ZefyrScaffold(
child: ZefyrTheme(
data: ZefyrThemeData().copyWith(
defaultLineTheme: LineTheme(
padding: EdgeInsets.all(0),
textStyle: TextStyle(fontFamily: "Myanmar3"),
),
),
child: ZefyrEditor(
autofocus: false,
padding: EdgeInsets.all(16),
controller: controller,
focusNode: focusNode,
),
),
),
),
// savebtn,
SizedBox(
height: 10,
)
],
);
}
// Widget textEditor(ZefyrController controller, FocusNode focusNode) {
// return ListView(
// children: [
// Container(
// height: MediaQuery.of(context).size.height - 200,
// child: ZefyrScaffold(
// child: ZefyrTheme(
// data: ZefyrThemeData().copyWith(
// defaultLineTheme: LineTheme(
// padding: EdgeInsets.all(0),
// textStyle: TextStyle(fontFamily: "Myanmar3"),
// ),
// ),
// child: ZefyrEditor(
// autofocus: false,
// padding: EdgeInsets.all(16),
// controller: controller,
// focusNode: focusNode,
// ),
// ),
// ),
// ),
// // savebtn,
// SizedBox(
// height: 10,
// )
// ],
// );
// }
_unfocus() {
FocusScope.of(context).unfocus();
@@ -167,11 +168,11 @@ class _TermEditState extends State<TermEdit> {
_isLoading = true;
});
try {
final contentsEng = jsonEncode(_controllerEng.document);
final contentsMm = jsonEncode(_controllerMm.document);
print('contents => $contentsEng');
TermModel termModel = Provider.of<TermModel>(context, listen: false);
await termModel.saveTerm(Term(termEng: contentsEng, termMm: contentsMm));
// final contentsEng = jsonEncode(_controllerEng.document);
// final contentsMm = jsonEncode(_controllerMm.document);
// print('contents => $contentsEng');
// TermModel termModel = Provider.of<TermModel>(context, listen: false);
// await termModel.saveTerm(Term(termEng: contentsEng, termMm: contentsMm));
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {

View File

@@ -10,46 +10,46 @@ import 'package:fcs/pages/widgets/local_text.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:zefyr/zefyr.dart';
// import 'package:zefyr/zefyr.dart';
typedef void ProfileCallback();
class TermPage extends StatefulWidget {
const TermPage({
Key key,
Key? key,
}) : super(key: key);
@override
_TermPageState createState() => _TermPageState();
}
class _TermPageState extends State<TermPage> {
ZefyrController _controller;
FocusNode _focusNode;
NotusDocument document = new NotusDocument();
// ZefyrController _controller;
// FocusNode _focusNode;
// NotusDocument document = new NotusDocument();
bool isLoading = false;
@override
void initState() {
super.initState();
_focusNode = FocusNode();
// _focusNode = FocusNode();
}
NotusDocument _loadDocument(Setting setting) {
bool isEng = Provider.of<LanguageModel>(context).isEng;
String term = isEng ? setting.termsEng : setting.termsMm;
NotusDocument doc;
try {
doc = NotusDocument.fromJson(jsonDecode(term));
} catch (e) {}
if (doc == null) {
doc = NotusDocument();
}
return doc;
}
// NotusDocument _loadDocument(Setting setting) {
// bool isEng = Provider.of<LanguageModel>(context).isEng;
// String term = isEng ? setting.termsEng : setting.termsMm;
// NotusDocument doc;
// try {
// doc = NotusDocument.fromJson(jsonDecode(term));
// } catch (e) {}
// if (doc == null) {
// doc = NotusDocument();
// }
// return doc;
// }
@override
Widget build(BuildContext context) {
Setting setting = Provider.of<MainModel>(context).setting;
Setting? setting = Provider.of<MainModel>(context).setting;
bool isEditable = context.select((MainModel m) => m.termEditable());
return Scaffold(
@@ -76,7 +76,7 @@ class _TermPageState extends State<TermPage> {
onPressed: () =>
Navigator.of(context).push<void>(CupertinoPageRoute(
builder: (context) =>
TermEdit(term: Term.fromSetting(setting)),
TermEdit(term: Term.fromSetting(setting!)),
)),
icon: Icon(
CupertinoIcons.pen,
@@ -85,25 +85,25 @@ class _TermPageState extends State<TermPage> {
]
: [],
),
body: ZefyrTheme(
data: ZefyrThemeData().copyWith(
defaultLineTheme: LineTheme(
padding: EdgeInsets.all(0),
textStyle: TextStyle(fontFamily: "Myanmar3"),
),
),
// data: ZefyrThemeData().copyWith(
// defaultLineTheme: LineTheme(
// textStyle: TextStyle(color: Colors.black),
// padding: EdgeInsets.all(0))),
child: ZefyrScaffold(
child: ZefyrEditor(
mode: ZefyrMode.view,
padding: EdgeInsets.all(16),
controller: ZefyrController(_loadDocument(setting)),
focusNode: _focusNode,
),
)),
// body: ZefyrTheme(
// data: ZefyrThemeData().copyWith(
// defaultLineTheme: LineTheme(
// padding: EdgeInsets.all(0),
// textStyle: TextStyle(fontFamily: "Myanmar3"),
// ),
// ),
// // data: ZefyrThemeData().copyWith(
// // defaultLineTheme: LineTheme(
// // textStyle: TextStyle(color: Colors.black),
// // padding: EdgeInsets.all(0))),
// child: ZefyrScaffold(
// child: ZefyrEditor(
// mode: ZefyrMode.view,
// padding: EdgeInsets.all(16),
// controller: ZefyrController(_loadDocument(setting)),
// focusNode: _focusNode,
// ),
// )),
);
}
}

View File

@@ -83,12 +83,16 @@ class MyDataRow {
///
/// The [cells] argument must not be null.
MyDataRow.byIndex({
<<<<<<< HEAD
int index = 0,
=======
int? index,
>>>>>>> upstream/master
this.selected = false,
this.onSelectChanged,
required this.cells,
}) : assert(cells != null),
key = ValueKey<int>(index);
key = ValueKey<int>(index!);
/// A [Key] that uniquely identifies this row. This is used to
/// ensure that if a row is added or removed, any stateful widgets
@@ -320,7 +324,7 @@ class MyDataTable extends StatelessWidget {
this.columnSpacing = 56.0,
this.oddLine,
this.evenLine,
@required this.rows,
required this.rows,
}) : assert(columns != null),
assert(columns.isNotEmpty),
assert(sortColumnIndex == null ||
@@ -451,10 +455,10 @@ class MyDataTable extends StatelessWidget {
Color(0x1E000000); // Dark theme variant is just a guess.
Widget _buildCheckbox({
Color color,
bool checked,
VoidCallback onRowTap,
ValueChanged<bool> onCheckboxChanged,
Color? color,
bool? checked,
VoidCallback? onRowTap,
ValueChanged<bool>? onCheckboxChanged,
}) {
Widget contents = Semantics(
container: true,
@@ -465,7 +469,9 @@ class MyDataTable extends StatelessWidget {
child: Checkbox(
activeColor: color,
value: checked,
onChanged: onCheckboxChanged,
onChanged: (bool? value) {
onCheckboxChanged!(value ?? false);
},
),
),
),
@@ -483,32 +489,33 @@ class MyDataTable extends StatelessWidget {
}
Widget _buildHeadingCell({
BuildContext context,
EdgeInsetsGeometry padding,
Widget label,
String tooltip,
bool numeric,
VoidCallback onSort,
bool sorted,
bool ascending,
required BuildContext context,
EdgeInsetsGeometry? padding,
Widget? label,
String? tooltip,
bool? numeric,
VoidCallback? onSort,
bool? sorted,
bool? ascending,
}) {
if (onSort != null) {
final Widget arrow = _SortArrow(
visible: sorted,
visible: sorted!,
down: sorted ? ascending : null,
duration: _sortArrowAnimationDuration,
);
const Widget arrowPadding = SizedBox(width: _sortArrowPadding);
label = Row(
textDirection: numeric ? TextDirection.rtl : null,
children: <Widget>[label, arrowPadding, arrow],
textDirection: (numeric ?? false) ? TextDirection.rtl : null,
children: <Widget>[label ?? Container(), arrowPadding, arrow],
);
}
label = Container(
padding: padding,
height: headingRowHeight,
alignment:
numeric ? Alignment.centerRight : AlignmentDirectional.centerStart,
alignment: (numeric ?? false)
? Alignment.centerRight
: AlignmentDirectional.centerStart,
child: AnimatedDefaultTextStyle(
style: TextStyle(
// TODO(ianh): font family should match Theme; see https://github.com/flutter/flutter/issues/3116
@@ -516,12 +523,16 @@ class MyDataTable extends StatelessWidget {
fontSize: _headingFontSize,
height: math.min(1.0, headingRowHeight / _headingFontSize),
color: (Theme.of(context).brightness == Brightness.light)
? ((onSort != null && sorted) ? Colors.black87 : Colors.black54)
: ((onSort != null && sorted) ? Colors.white : Colors.white70),
? ((onSort != null && (sorted ?? false))
? Colors.black87
: Colors.black54)
: ((onSort != null && (sorted ?? false))
? Colors.white
: Colors.white70),
),
softWrap: false,
duration: _sortArrowAnimationDuration,
child: label,
child: label ?? Container(),
),
);
if (tooltip != null) {
@@ -540,42 +551,43 @@ class MyDataTable extends StatelessWidget {
}
Widget _buildMyDataCell({
BuildContext context,
EdgeInsetsGeometry padding,
Widget label,
bool numeric,
bool placeholder,
bool showEditIcon,
VoidCallback onTap,
VoidCallback onSelectChanged,
required BuildContext context,
EdgeInsetsGeometry? padding,
Widget? label,
bool? numeric,
bool? placeholder,
bool? showEditIcon,
VoidCallback? onTap,
VoidCallback? onSelectChanged,
}) {
final bool isLightTheme = Theme.of(context).brightness == Brightness.light;
if (showEditIcon) {
if (showEditIcon ?? false) {
const Widget icon = Icon(Icons.edit, size: 18.0);
label = Expanded(child: label);
label = Expanded(child: label ?? Container());
label = Row(
textDirection: numeric ? TextDirection.rtl : null,
textDirection: (numeric ?? false) ? TextDirection.rtl : null,
children: <Widget>[label, icon],
);
}
label = Container(
padding: padding,
height: MyDataRowHeight,
alignment:
numeric ? Alignment.centerRight : AlignmentDirectional.centerStart,
alignment: (numeric ?? false)
? Alignment.centerRight
: AlignmentDirectional.centerStart,
child: DefaultTextStyle(
style: TextStyle(
// TODO(ianh): font family should be Roboto; see https://github.com/flutter/flutter/issues/3116
fontSize: 13.0,
color: isLightTheme
? (placeholder ? Colors.black38 : Colors.black87)
: (placeholder ? Colors.white38 : Colors.white70),
? ((placeholder ?? false) ? Colors.black38 : Colors.black87)
: ((placeholder ?? false) ? Colors.white38 : Colors.white70),
),
child: IconTheme.merge(
data: IconThemeData(
color: isLightTheme ? Colors.black54 : Colors.white70,
),
child: DropdownButtonHideUnderline(child: label),
child: DropdownButtonHideUnderline(child: label ?? Container()),
),
),
);
@@ -614,6 +626,10 @@ class MyDataTable extends StatelessWidget {
final List<TableColumnWidth> tableColumns = (columns.length +
(showCheckboxColumn ? 1 : 0)) as List<TableColumnWidth>;
<<<<<<< HEAD
=======
>>>>>>> upstream/master
final List<TableRow> tableRows = List<TableRow>.generate(
rows.length + 1, // the +1 is for the header row
(int index) {
@@ -626,36 +642,36 @@ class MyDataTable extends StatelessWidget {
: index.isEven && evenLine != null
? evenLine
: _kUnselectedDecoration,
children: List<Widget>(tableColumns.length),
children: tableColumns.map((e) => Container()).toList(),
);
},
);
int rowIndex;
int displayColumnIndex = 0;
if (showCheckboxColumn) {
tableColumns[0] = FixedColumnWidth(
horizontalMargin + Checkbox.width + horizontalMargin / 2.0);
tableRows[0].children[0] = _buildCheckbox(
color: theme.accentColor,
checked: allChecked,
onCheckboxChanged: _handleSelectAll,
);
rowIndex = 1;
for (MyDataRow row in rows) {
tableRows[rowIndex].children[0] = _buildCheckbox(
color: theme.accentColor,
checked: row.selected,
onRowTap: () => row.onSelectChanged != null
? row.onSelectChanged(!row.selected)
: null,
onCheckboxChanged: row.onSelectChanged,
);
rowIndex += 1;
}
displayColumnIndex += 1;
}
int displayColumnIndex = 0;
// if (showCheckboxColumn) {
// tableColumns[0] = FixedColumnWidth(
// horizontalMargin + Checkbox.width + horizontalMargin / 2.0);
// tableRows[0].children![0] = _buildCheckbox(
// color: theme.accentColor,
// checked: allChecked,
// onCheckboxChanged: _handleSelectAll,
// );
// rowIndex = 1;
// for (MyDataRow row in rows) {
// tableRows[rowIndex].children[0] = _buildCheckbox(
// color: theme.accentColor,
// checked: row.selected,
// onRowTap: () => row.onSelectChanged != null
// ? row.onSelectChanged(!row.selected)
// : null,
// onCheckboxChanged: row.onSelectChanged,
// );
// rowIndex += 1;
// }
// displayColumnIndex += 1;
// }
for (int MyDataColumnIndex = 0;
MyDataColumnIndex < columns.length;
@@ -688,14 +704,14 @@ class MyDataTable extends StatelessWidget {
} else {
tableColumns[displayColumnIndex] = const IntrinsicColumnWidth();
}
tableRows[0].children[displayColumnIndex] = _buildHeadingCell(
tableRows[0].children![displayColumnIndex] = _buildHeadingCell(
context: context,
padding: padding,
label: column.label,
tooltip: column.tooltip,
numeric: column.numeric,
onSort: () => column.onSort != null
? column.onSort(MyDataColumnIndex,
? column.onSort!(MyDataColumnIndex,
sortColumnIndex != MyDataColumnIndex || !sortAscending)
: null,
sorted: MyDataColumnIndex == sortColumnIndex,
@@ -704,7 +720,7 @@ class MyDataTable extends StatelessWidget {
rowIndex = 1;
for (MyDataRow row in rows) {
final MyDataCell cell = row.cells[MyDataColumnIndex];
tableRows[rowIndex].children[displayColumnIndex] = _buildMyDataCell(
tableRows[rowIndex].children?[displayColumnIndex] = _buildMyDataCell(
context: context,
padding: padding,
label: cell.child,
@@ -713,7 +729,7 @@ class MyDataTable extends StatelessWidget {
showEditIcon: cell.showEditIcon,
onTap: cell.onTap,
onSelectChanged: () => row.onSelectChanged != null
? row.onSelectChanged(!row.selected)
? row.onSelectChanged!(!row.selected)
: null,
);
rowIndex += 1;
@@ -745,11 +761,19 @@ class TableRowInkWell extends InkResponse {
/// Creates an ink well for a table row.
const TableRowInkWell({
Key? key,
<<<<<<< HEAD
Widget child,
GestureTapCallback onTap,
GestureTapCallback onDoubleTap,
GestureLongPressCallback onLongPress,
ValueChanged<bool> onHighlightChanged,
=======
Widget? child,
GestureTapCallback? onTap,
GestureTapCallback? onDoubleTap,
GestureLongPressCallback? onLongPress,
ValueChanged<bool>? onHighlightChanged,
>>>>>>> upstream/master
}) : super(
key: key,
child: child,
@@ -765,7 +789,7 @@ class TableRowInkWell extends InkResponse {
RectCallback getRectCallback(RenderBox referenceBox) {
return () {
RenderObject cell = referenceBox;
AbstractNode table = cell.parent;
AbstractNode? table = cell.parent;
final Matrix4 transform = Matrix4.identity();
while (table is RenderObject && table is! RenderTable) {
final RenderObject parentBox = table as RenderObject;
@@ -778,11 +802,11 @@ class TableRowInkWell extends InkResponse {
final TableCellParentData cellParentData =
cell.parentData as TableCellParentData;
assert(cellParentData.y != null);
final Rect rect = table.getRowBox(cellParentData.y);
final Rect rect = table.getRowBox(cellParentData.y!);
// The rect is in the table's coordinate space. We need to change it to the
// TableRowInkWell's coordinate space.
table.applyPaintTransform(cell, transform);
final Offset offset = MatrixUtils.getAsTranslation(transform);
final Offset? offset = MatrixUtils.getAsTranslation(transform);
if (offset != null) return rect.shift(-offset);
}
return Rect.zero;
@@ -804,17 +828,18 @@ class _SortArrow extends StatefulWidget {
this.duration,
}) : super(key: key);
final bool visible;
final bool? visible;
final bool down;
final bool? down;
final Duration duration;
final Duration? duration;
@override
_SortArrowState createState() => _SortArrowState();
}
class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
<<<<<<< HEAD
late AnimationController _opacityController;
late Animation<double> _opacityAnimation;
@@ -823,6 +848,16 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
double _orientationOffset = 0.0;
late bool _down;
=======
AnimationController? _opacityController;
Animation<double>? _opacityAnimation;
AnimationController? _orientationController;
Animation<double>? _orientationAnimation;
double _orientationOffset = 0.0;
bool? _down;
>>>>>>> upstream/master
static final Animatable<double> _turnTween =
Tween<double>(begin: 0.0, end: math.pi)
@@ -838,15 +873,16 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
),
curve: Curves.fastOutSlowIn,
)..addListener(_rebuild);
_opacityController.value = widget.visible ? 1.0 : 0.0;
_opacityController!.value = (widget.visible ?? false) ? 1.0 : 0.0;
_orientationController = AnimationController(
duration: widget.duration,
vsync: this,
);
_orientationAnimation = _orientationController.drive(_turnTween)
_orientationAnimation = _orientationController!.drive(_turnTween)
..addListener(_rebuild)
..addStatusListener(_resetOrientationAnimation);
if (widget.visible) _orientationOffset = widget.down ? 0.0 : math.pi;
if (widget.visible ?? false)
_orientationOffset = (widget.down ?? false) ? 0.0 : math.pi;
}
void _rebuild() {
@@ -857,9 +893,9 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
void _resetOrientationAnimation(AnimationStatus status) {
if (status == AnimationStatus.completed) {
assert(_orientationAnimation.value == math.pi);
assert(_orientationAnimation!.value == math.pi);
_orientationOffset += math.pi;
_orientationController.value =
_orientationController!.value =
0.0; // TODO(ianh): This triggers a pointless rebuild.
}
}
@@ -868,26 +904,30 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
void didUpdateWidget(_SortArrow oldWidget) {
super.didUpdateWidget(oldWidget);
bool skipArrow = false;
<<<<<<< HEAD
final bool newDown = widget.down;
=======
final bool newDown = widget.down ?? _down!;
>>>>>>> upstream/master
if (oldWidget.visible != widget.visible) {
if (widget.visible &&
(_opacityController.status == AnimationStatus.dismissed)) {
_orientationController.stop();
_orientationController.value = 0.0;
if (widget.visible! &&
(_opacityController!.status == AnimationStatus.dismissed)) {
_orientationController!.stop();
_orientationController!.value = 0.0;
_orientationOffset = newDown ? 0.0 : math.pi;
skipArrow = true;
}
if (widget.visible) {
_opacityController.forward();
if ((widget.visible ?? false)) {
_opacityController!.forward();
} else {
_opacityController.reverse();
_opacityController!.reverse();
}
}
if ((_down != newDown) && !skipArrow) {
if (_orientationController.status == AnimationStatus.dismissed) {
_orientationController.forward();
if (_orientationController!.status == AnimationStatus.dismissed) {
_orientationController?.forward();
} else {
_orientationController.reverse();
_orientationController?.reverse();
}
}
_down = newDown;
@@ -895,8 +935,8 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
@override
void dispose() {
_opacityController.dispose();
_orientationController.dispose();
_opacityController?.dispose();
_orientationController?.dispose();
super.dispose();
}
@@ -906,10 +946,10 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
@override
Widget build(BuildContext context) {
return Opacity(
opacity: _opacityAnimation.value,
opacity: _opacityAnimation!.value,
child: Transform(
transform:
Matrix4.rotationZ(_orientationOffset + _orientationAnimation.value)
Matrix4.rotationZ(_orientationOffset + _orientationAnimation!.value)
..setTranslationRaw(0.0, _arrowIconBaselineOffset, 0.0),
alignment: Alignment.center,
child: Icon(