TF-736 Apply new design for rich text button

This commit is contained in:
dab246
2022-07-25 16:31:18 +07:00
committed by Dat H. Pham
parent 3538212266
commit 1165e000f0
9 changed files with 221 additions and 140 deletions
@@ -23,6 +23,8 @@ class DropDownButtonWidget<T> extends StatelessWidget {
final double sizeIconChecked;
final double radiusButton;
final double opacity;
final Widget? iconArrowDown;
final Color? colorButton;
const DropDownButtonWidget({
Key? key,
@@ -36,6 +38,8 @@ class DropDownButtonWidget<T> extends StatelessWidget {
this.sizeIconChecked = 20,
this.radiusButton = 10,
this.opacity = 1.0,
this.iconArrowDown,
this.colorButton,
}) : super(key: key);
@override
@@ -94,7 +98,7 @@ class DropDownButtonWidget<T> extends StatelessWidget {
color: AppColor.colorInputBorderCreateMailbox,
width: 0.5,
),
color: AppColor.colorInputBackgroundCreateMailbox,
color: colorButton ?? AppColor.colorInputBackgroundCreateMailbox,
),
padding: const EdgeInsets.only(left: 12, right: 10),
child: Row(children: [
@@ -106,12 +110,12 @@ class DropDownButtonWidget<T> extends StatelessWidget {
maxLines: 1,
overflow: CommonTextStyle.defaultTextOverFlow,
)),
SvgPicture.asset(_imagePaths.icDropDown)
iconArrowDown ?? SvgPicture.asset(_imagePaths.icDropDown)
]),
)
: null,
onChanged: onChanged,
icon: SvgPicture.asset(_imagePaths.icDropDown),
icon: iconArrowDown ?? SvgPicture.asset(_imagePaths.icDropDown),
buttonPadding: const EdgeInsets.symmetric(horizontal: 12),
buttonDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(radiusButton),
@@ -119,7 +123,7 @@ class DropDownButtonWidget<T> extends StatelessWidget {
color: AppColor.colorInputBorderCreateMailbox,
width: 0.5,
),
color: AppColor.colorInputBackgroundCreateMailbox,
color: colorButton ?? AppColor.colorInputBackgroundCreateMailbox,
),
itemHeight: heightItem,
buttonHeight: heightItem,
@@ -757,117 +757,144 @@ class ComposerView extends GetWidget<ComposerController>
}
Widget _buildToolbarRichTextWidget(BuildContext context) {
return Container(
padding: const EdgeInsets.only(left: 20, top: 8, bottom: 8),
alignment: Alignment.centerLeft,
child: Wrap(
alignment: WrapAlignment.start,
crossAxisAlignment: WrapCrossAlignment.center,
children: RichTextStyleType.values.map((textType) => Obx(() {
final opacity = controller.richTextWebController.codeViewEnabled ? 0.5 : 1.0;
switch(textType) {
case RichTextStyleType.textColor:
return AbsorbPointer(
absorbing: controller.richTextWebController.codeViewEnabled,
child: buildIconColorText(
iconData: textType.getIconData(),
colorSelected: controller.richTextWebController.selectedTextColor.value,
tooltip: textType.getTooltipButton(context),
opacity: opacity,
onTap: () => controller.richTextWebController.applyRichTextStyle(context, textType)),
);
case RichTextStyleType.textBackgroundColor:
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 2),
child: AbsorbPointer(
absorbing: controller.richTextWebController.codeViewEnabled,
child: buildIconColorBackgroundText(
iconData: textType.getIconData(),
colorSelected: controller.richTextWebController.selectedTextBackgroundColor.value,
tooltip: textType.getTooltipButton(context),
opacity: opacity,
onTap: () => controller.richTextWebController.applyRichTextStyle(context, textType)),
),
);
case RichTextStyleType.fontName:
return AbsorbPointer(
absorbing: controller.richTextWebController.codeViewEnabled,
return Obx(() {
final richTextController = controller.richTextWebController;
final codeViewEnabled = richTextController.codeViewEnabled;
final opacity = codeViewEnabled ? 0.5 : 1.0;
return Container(
padding: const EdgeInsets.only(left: 20, top: 8, bottom: 8),
alignment: Alignment.centerLeft,
child: Wrap(
alignment: WrapAlignment.start,
crossAxisAlignment: WrapCrossAlignment.center,
children: [
AbsorbPointer(
absorbing: codeViewEnabled,
child: DropDownMenuHeaderStyleWidget(
icon: buildWrapIconStyleText(
icon: Tooltip(
message: RichTextStyleType.headerStyle.getTooltipButton(context),
child: SvgPicture.asset(RichTextStyleType.headerStyle.getIcon(imagePaths),
color: AppColor.colorDefaultRichTextButton.withOpacity(opacity),
fit: BoxFit.fill),
)
),
items: HeaderStyleType.values,
onMenuStateChange: (isOpen) {
log('ComposerView::_buildToolbarRichTextWidget(): MenuHeaderStyleStatus: $isOpen');
final newStatus = isOpen
? DropdownMenuFontStatus.open
: DropdownMenuFontStatus.closed;
richTextController.menuHeaderStyleStatus = newStatus;
},
onChanged: (newStyle) => richTextController.applyHeaderStyle(newStyle)),
),
AbsorbPointer(
absorbing: codeViewEnabled,
child: Container(
width: 200,
padding: const EdgeInsets.only(right: 2),
child: DropDownButtonWidget<FontNameType>(
items: FontNameType.values,
itemSelected: controller.richTextWebController.selectedFontName.value,
onChanged: (newFont) => controller.richTextWebController.applyNewFontStyle(newFont),
onMenuStateChange: (isOpen) {
log('ComposerView::_buildToolbarRichTextWidget(): MenuFontStatus: $isOpen');
final newStatus = isOpen
? DropdownMenuFontStatus.open
: DropdownMenuFontStatus.closed;
controller.richTextWebController.menuFontStatus = newStatus;
},
heightItem: 35,
sizeIconChecked: 16,
radiusButton: 5,
opacity: opacity,
supportSelectionIcon: true)),
);
case RichTextStyleType.codeView:
return buildIconStyleText(
path: textType.getIcon(imagePaths),
isSelected: controller.richTextWebController.isTextStyleTypeSelected(textType),
tooltip: textType.getTooltipButton(context),
onTap: () => controller.richTextWebController.toggleCodeView());
case RichTextStyleType.headerStyle:
return AbsorbPointer(
absorbing: controller.richTextWebController.codeViewEnabled,
child: Container(
width: 50,
height: 35,
alignment: Alignment.center,
padding: const EdgeInsets.only(right: 2),
child: DropDownMenuHeaderStyleWidget(
icon: Material(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
side: const BorderSide(
color: AppColor.colorInputBorderCreateMailbox,
width: 0.5)),
color: AppColor.colorInputBackgroundCreateMailbox,
child: Tooltip(
message: textType.getTooltipButton(context),
child: Padding(
padding: const EdgeInsets.only(left: 10, top: 10),
child: SvgPicture.asset(textType.getIcon(imagePaths),
color: AppColor.colorDefaultRichTextButton.withOpacity(opacity),
fit: BoxFit.fill),
),
),
),
items: HeaderStyleType.values,
width: 200,
padding: const EdgeInsets.only(left: 8, right: 8),
child: DropDownButtonWidget<FontNameType>(
items: FontNameType.values,
itemSelected: richTextController.selectedFontName.value,
onChanged: (newFont) => richTextController.applyNewFontStyle(newFont),
onMenuStateChange: (isOpen) {
log('ComposerView::_buildToolbarRichTextWidget(): MenuHeaderStyleStatus: $isOpen');
log('ComposerView::_buildToolbarRichTextWidget(): MenuFontStatus: $isOpen');
final newStatus = isOpen
? DropdownMenuFontStatus.open
: DropdownMenuFontStatus.closed;
controller.richTextWebController.menuHeaderStyleStatus = newStatus;
richTextController.menuFontStatus = newStatus;
},
onChanged: (newStyle) => controller.richTextWebController.applyHeaderStyle(newStyle))),
);
default:
return AbsorbPointer(
absorbing: controller.richTextWebController.codeViewEnabled,
child: buildIconStyleText(
path: textType.getIcon(imagePaths),
isSelected: controller.richTextWebController.isTextStyleTypeSelected(textType),
tooltip: textType.getTooltipButton(context),
opacity: opacity,
onTap: () => controller.richTextWebController.applyRichTextStyle(context, textType)),
);
}
})).toList()
),
);
heightItem: 38,
sizeIconChecked: 16,
radiusButton: 5,
opacity: opacity,
colorButton: Colors.white,
iconArrowDown: SvgPicture.asset(imagePaths.icStyleArrowDown),
supportSelectionIcon: true)),
),
AbsorbPointer(
absorbing: codeViewEnabled,
child: buildWrapIconStyleText(
icon: buildIconWithTooltip(
path: RichTextStyleType.textColor.getIcon(imagePaths),
color: richTextController.selectedTextColor.value,
tooltip: RichTextStyleType.textColor.getTooltipButton(context),
opacity: opacity),
onTap: () => richTextController.applyRichTextStyle(context, RichTextStyleType.textColor)),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: AbsorbPointer(
absorbing: codeViewEnabled,
child: buildWrapIconStyleText(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 5),
icon: buildIconColorBackgroundText(
iconData: RichTextStyleType.textBackgroundColor.getIconData(),
colorSelected: richTextController.selectedTextBackgroundColor.value,
tooltip: RichTextStyleType.textBackgroundColor.getTooltipButton(context),
opacity: opacity),
onTap: () => richTextController.applyRichTextStyle(context, RichTextStyleType.textBackgroundColor)),
),
),
buildWrapIconStyleText(
hasDropdown: false,
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 5),
icon: Wrap(children: [
AbsorbPointer(
absorbing: codeViewEnabled,
child: buildIconStyleText(
path: RichTextStyleType.bold.getIcon(imagePaths),
isSelected: richTextController.isTextStyleTypeSelected(RichTextStyleType.bold),
tooltip: RichTextStyleType.bold.getTooltipButton(context),
opacity: opacity,
onTap: () => richTextController.applyRichTextStyle(context, RichTextStyleType.bold)),
),
AbsorbPointer(
absorbing: codeViewEnabled,
child: buildIconStyleText(
path: RichTextStyleType.italic.getIcon(imagePaths),
isSelected: richTextController.isTextStyleTypeSelected(RichTextStyleType.italic),
tooltip: RichTextStyleType.italic.getTooltipButton(context),
opacity: opacity,
onTap: () => richTextController.applyRichTextStyle(context, RichTextStyleType.italic)),
),
AbsorbPointer(
absorbing: codeViewEnabled,
child: buildIconStyleText(
path: RichTextStyleType.underline.getIcon(imagePaths),
isSelected: richTextController.isTextStyleTypeSelected(RichTextStyleType.underline),
tooltip: RichTextStyleType.underline.getTooltipButton(context),
opacity: opacity,
onTap: () => richTextController.applyRichTextStyle(context, RichTextStyleType.underline)),
),
AbsorbPointer(
absorbing: codeViewEnabled,
child: buildIconStyleText(
path: RichTextStyleType.strikeThrough.getIcon(imagePaths),
isSelected: richTextController.isTextStyleTypeSelected(
RichTextStyleType.strikeThrough),
tooltip: RichTextStyleType.strikeThrough.getTooltipButton(context),
opacity: opacity,
onTap: () => richTextController.applyRichTextStyle(context, RichTextStyleType.strikeThrough)),
)
])),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: buildWrapIconStyleText(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 5),
isSelected: richTextController.isTextStyleTypeSelected(RichTextStyleType.codeView),
icon: buildIconWithTooltip(
path: RichTextStyleType.codeView.getIcon(imagePaths),
color: AppColor.colorDefaultRichTextButton.withOpacity(opacity),
tooltip: RichTextStyleType.codeView.getTooltipButton(context)),
onTap: () => richTextController.toggleCodeView()),
)
]
),
);
});
}
Widget _buildInlineLoadingView() {
@@ -1,11 +1,45 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/views/button/icon_button_web.dart';
import 'package:core/core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
mixin RichTextButtonMixin {
final _imagePaths = Get.find<ImagePaths>();
Widget buildWrapIconStyleText({
required Widget icon,
VoidCallback? onTap,
bool isSelected = false,
bool hasDropdown = true,
double opacity = 1.0,
EdgeInsets? padding,
}){
return InkWell(
onTap: onTap,
child: Container(
padding: padding ?? const EdgeInsets.symmetric(horizontal: 5, vertical: 5),
decoration: BoxDecoration(
color: isSelected == true
? AppColor.colorBackgroundWrapIconStyleCode.withOpacity(opacity)
: Colors.white.withOpacity(opacity),
border: Border.all(
color: AppColor.colorBorderWrapIconStyleCode,
width: 0.5),
borderRadius: BorderRadius.circular(8)),
child: hasDropdown
? Row(
mainAxisSize: MainAxisSize.min,
children: [
icon,
SvgPicture.asset(_imagePaths.icStyleArrowDown)
])
: icon,
),
);
}
Widget buildIconStyleText({
required String path,
required bool? isSelected,
@@ -28,50 +62,38 @@ mixin RichTextButtonMixin {
);
}
Widget buildIconColorText({
required IconData? iconData,
required Color? colorSelected,
required VoidCallback onTap,
Widget buildIconWithTooltip({
required String path,
Color? color,
String? tooltip,
double opacity = 1.0,
}){
return buildIconWeb(
icon: Icon(iconData,
color: (colorSelected ?? Colors.black).withOpacity(opacity),
size: 20),
iconPadding: const EdgeInsets.all(4),
colorSelected: colorSelected == Colors.white
? AppColor.colorFocusRichTextButton
: Colors.transparent,
colorFocus: Colors.white,
minSize: 20,
tooltip: tooltip,
onTap: onTap,
final newColor = color == Colors.white
? AppColor.colorDefaultRichTextButton
: color;
return Tooltip(
child: SvgPicture.asset(path,
color: newColor?.withOpacity(opacity),
fit: BoxFit.fill),
message: tooltip,
);
}
Widget buildIconColorBackgroundText({
required IconData? iconData,
required Color? colorSelected,
required VoidCallback onTap,
String? tooltip,
double opacity = 1.0,
}){
final newColor = colorSelected == Colors.white
? AppColor.colorDefaultRichTextButton
: colorSelected;
return buildIconWeb(
icon: Icon(iconData,
return Tooltip(
child: Icon(iconData,
color: (newColor ?? AppColor.colorDefaultRichTextButton).withOpacity(opacity),
size: 20),
iconPadding: const EdgeInsets.all(4),
colorSelected: newColor == Colors.white
? AppColor.colorFocusRichTextButton
: Colors.transparent,
colorFocus: Colors.white,
minSize: 20,
tooltip: tooltip,
onTap: onTap,
message: tooltip,
);
}
}
@@ -51,6 +51,9 @@ enum RichTextStyleType {
return imagePaths.icStyleCodeView;
case headerStyle:
return imagePaths.icStyleHeader;
case textColor:
case textBackgroundColor:
return imagePaths.icStyleColor;
default:
return '';
}