@@ -14,6 +14,7 @@ import 'package:tsdm_client/shared/providers/image_cache_provider/image_cache_pr
1414import 'package:tsdm_client/shared/providers/image_cache_provider/models/models.dart' ;
1515import 'package:tsdm_client/utils/logger.dart' ;
1616import 'package:tsdm_client/widgets/section_switch_list_tile.dart' ;
17+ import 'package:tsdm_client/widgets/tips.dart' ;
1718
1819/// Show a picture dialog to add picture into editor.
1920Future <BBCodeImageInfo ?> showImagePicker (BuildContext context, {String ? url, int ? width, int ? height}) async =>
@@ -72,6 +73,20 @@ class _ImageDialogState extends State<_ImageDialog> with LoggerMixin, SingleTick
7273 /// So fill with original image size is fine.
7374 bool autoFillSize = true ;
7475
76+ /// Automatically determine the width.
77+ ///
78+ /// Fill a zero value in bbcode.
79+ ///
80+ /// This can not be true when [autoScaleHeight] is true.
81+ bool autoScaleWidth = false ;
82+
83+ /// Automatically determine the height.
84+ ///
85+ /// Fill a zero value in bbcode.
86+ ///
87+ /// This can not be true when [autoScaleWidth] is true.
88+ bool autoScaleHeight = false ;
89+
7590 /// Flag indicating in auto-fill-size progress.
7691 bool fillingSize = false ;
7792
@@ -284,41 +299,94 @@ class _ImageDialogState extends State<_ImageDialog> with LoggerMixin, SingleTick
284299 // _buildSmmsField(context),
285300 ],
286301 ),
287- TextFormField (
288- controller: widthController,
289- keyboardType: TextInputType .number,
290- inputFormatters: [FilteringTextInputFormatter .allow (RegExp ('[0-9]+' ))],
291- decoration: InputDecoration (
292- prefixIcon: const Icon (Icons .horizontal_distribute_outlined),
293- labelText: tr.width,
294- ),
295- validator: (v) {
296- if (v == null || v.trim ().isEmpty) {
297- return tr.errorEmpty;
298- }
299- final vv = double .tryParse (v);
300- if (vv == null || vv <= 0 ) {
301- return tr.errorInvalidNumber;
302- }
303- return null ;
304- },
302+ Row (
303+ children: [
304+ Expanded (
305+ child: TextFormField (
306+ controller: widthController,
307+ enabled: ! autoScaleWidth,
308+ keyboardType: TextInputType .number,
309+ inputFormatters: [FilteringTextInputFormatter .allow (RegExp ('[0-9]+' ))],
310+ decoration: InputDecoration (
311+ prefixIcon: const Icon (Icons .horizontal_distribute_outlined),
312+ labelText: tr.width,
313+ ),
314+ validator: (v) {
315+ if (autoScaleWidth) {
316+ return null ;
317+ }
318+ if (v == null || v.trim ().isEmpty) {
319+ return tr.errorEmpty;
320+ }
321+ final vv = double .tryParse (v);
322+ if (vv == null || vv <= 0 ) {
323+ return tr.errorInvalidNumber;
324+ }
325+ return null ;
326+ },
327+ ),
328+ ),
329+ Checkbox (
330+ value: autoScaleWidth,
331+ onChanged: (v) {
332+ if (v == null ) {
333+ return ;
334+ }
335+
336+ setState (() {
337+ if (autoScaleHeight) {
338+ autoScaleHeight = false ;
339+ }
340+ autoScaleWidth = v;
341+ });
342+ },
343+ ),
344+ Text (tr.auto),
345+ ],
305346 ),
306- TextFormField (
307- controller: heightController,
308- keyboardType: TextInputType .number,
309- inputFormatters: [FilteringTextInputFormatter .allow (RegExp ('[0-9]+' ))],
310- decoration: InputDecoration (prefixIcon: const Icon (Icons .add), labelText: tr.height),
311- validator: (v) {
312- if (v == null || v.trim ().isEmpty) {
313- return tr.errorEmpty;
314- }
315- final vv = double .tryParse (v);
316- if (vv == null || vv <= 0 ) {
317- return tr.errorInvalidNumber;
318- }
319- return null ;
320- },
347+ Row (
348+ children: [
349+ Expanded (
350+ child: TextFormField (
351+ controller: heightController,
352+ enabled: ! autoScaleHeight,
353+ keyboardType: TextInputType .number,
354+ inputFormatters: [FilteringTextInputFormatter .allow (RegExp ('[0-9]+' ))],
355+ decoration: InputDecoration (prefixIcon: const Icon (Icons .add), labelText: tr.height),
356+ validator: (v) {
357+ if (autoScaleHeight) {
358+ return null ;
359+ }
360+ if (v == null || v.trim ().isEmpty) {
361+ return tr.errorEmpty;
362+ }
363+ final vv = double .tryParse (v);
364+ if (vv == null || vv <= 0 ) {
365+ return tr.errorInvalidNumber;
366+ }
367+ return null ;
368+ },
369+ ),
370+ ),
371+ Checkbox (
372+ value: autoScaleHeight,
373+ onChanged: (v) {
374+ if (v == null ) {
375+ return ;
376+ }
377+
378+ setState (() {
379+ if (autoScaleWidth) {
380+ autoScaleWidth = false ;
381+ }
382+ autoScaleHeight = v;
383+ });
384+ },
385+ ),
386+ Text (tr.auto),
387+ ],
321388 ),
389+ Tips (tr.autoSingleDirectionSize),
322390 SectionSwitchListTile (
323391 title: Text (tr.autoFillSize),
324392 subtitle: Text (tr.autoFillSizeDetail),
@@ -342,12 +410,16 @@ class _ImageDialogState extends State<_ImageDialog> with LoggerMixin, SingleTick
342410 return ;
343411 }
344412
345- final width = int .parse (widthController.text);
346- final height = int .parse (heightController.text);
347- assert (width != 0 , 'image width should >= zero' );
348- assert (height != 0 , 'image height should >= zero' );
413+ final width = int .tryParse (widthController.text);
414+ final height = int .tryParse (heightController.text);
349415
350- context.pop (BBCodeImageInfo (urlController.text, width: width, height: height));
416+ context.pop (
417+ BBCodeImageInfo (
418+ urlController.text,
419+ width: autoScaleWidth ? 0 : width,
420+ height: autoScaleHeight ? 0 : height,
421+ ),
422+ );
351423 },
352424 ),
353425 ],
0 commit comments