Browse Source

ComPDFKit(flutter) - 1.阅读设置界面及交互

liuxiaolong 1 year ago
parent
commit
1db042ce37
67 changed files with 847 additions and 52 deletions
  1. 10 0
      android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/common/pdfprovider/provider/CPDFViewCtrlDataProvider.java
  2. BIN
      assets/images/1.5x/ic_book_mode.png
  3. BIN
      assets/images/1.5x/ic_continuous_scroll.png
  4. BIN
      assets/images/1.5x/ic_crop_mode.png
  5. BIN
      assets/images/1.5x/ic_double_page.png
  6. BIN
      assets/images/1.5x/ic_horizontal_scrolling.png
  7. BIN
      assets/images/1.5x/ic_single_page.png
  8. BIN
      assets/images/1.5x/ic_themes_dark.png
  9. BIN
      assets/images/1.5x/ic_themes_light.png
  10. BIN
      assets/images/1.5x/ic_themes_reseda.png
  11. BIN
      assets/images/1.5x/ic_themes_sepia.png
  12. BIN
      assets/images/1.5x/ic_themes_sepia_dark.png
  13. BIN
      assets/images/1.5x/ic_vertical_scrolling.png
  14. BIN
      assets/images/2.0x/ic_book_mode.png
  15. BIN
      assets/images/2.0x/ic_continuous_scroll.png
  16. BIN
      assets/images/2.0x/ic_crop_mode.png
  17. BIN
      assets/images/2.0x/ic_double_page.png
  18. BIN
      assets/images/2.0x/ic_horizontal_scrolling.png
  19. BIN
      assets/images/2.0x/ic_single_page.png
  20. BIN
      assets/images/2.0x/ic_themes_dark.png
  21. BIN
      assets/images/2.0x/ic_themes_light.png
  22. BIN
      assets/images/2.0x/ic_themes_reseda.png
  23. BIN
      assets/images/2.0x/ic_themes_sepia.png
  24. BIN
      assets/images/2.0x/ic_themes_sepia_dark.png
  25. BIN
      assets/images/2.0x/ic_vertical_scrolling.png
  26. BIN
      assets/images/3.0x/ic_book_mode.png
  27. BIN
      assets/images/3.0x/ic_continuous_scroll.png
  28. BIN
      assets/images/3.0x/ic_crop_mode.png
  29. BIN
      assets/images/3.0x/ic_double_page.png
  30. BIN
      assets/images/3.0x/ic_horizontal_scrolling.png
  31. BIN
      assets/images/3.0x/ic_single_page.png
  32. BIN
      assets/images/3.0x/ic_themes_dark.png
  33. BIN
      assets/images/3.0x/ic_themes_light.png
  34. BIN
      assets/images/3.0x/ic_themes_reseda.png
  35. BIN
      assets/images/3.0x/ic_themes_sepia.png
  36. BIN
      assets/images/3.0x/ic_themes_sepia_dark.png
  37. BIN
      assets/images/3.0x/ic_vertical_scrolling.png
  38. BIN
      assets/images/ic_book_mode.png
  39. BIN
      assets/images/ic_continuous_scroll.png
  40. BIN
      assets/images/ic_crop_mode.png
  41. BIN
      assets/images/ic_double_page.png
  42. BIN
      assets/images/ic_horizontal_scrolling.png
  43. BIN
      assets/images/ic_single_page.png
  44. BIN
      assets/images/ic_themes_dark.png
  45. BIN
      assets/images/ic_themes_light.png
  46. BIN
      assets/images/ic_themes_reseda.png
  47. BIN
      assets/images/ic_themes_sepia.png
  48. BIN
      assets/images/ic_themes_sepia_dark.png
  49. BIN
      assets/images/ic_vertical_scrolling.png
  50. 1 1
      example/lib/main.dart
  51. 15 0
      lib/common/util/Strings.dart
  52. 43 0
      lib/core/cpdf_view_ctrl.dart
  53. 5 0
      lib/theme/colors.dart
  54. 24 9
      lib/theme/themes.dart
  55. 23 0
      lib/widgets/common/radio/cpdf_radio_group_data.dart
  56. 55 0
      lib/widgets/common/radio/cpdf_radio_list_group.dart
  57. 64 0
      lib/widgets/common/radio/cpdf_radio_list_tile.dart
  58. 62 0
      lib/widgets/common/switch/cpdf_switch_list_tile.dart
  59. 6 1
      lib/widgets/common/views/cpdf_main_tool_bar.dart
  60. 38 0
      lib/widgets/common/views/cpdf_scaffold.dart
  61. 20 13
      lib/widgets/common/views/cpdf_tool_bar.dart
  62. 23 28
      lib/widgets/viewer/pdfbota/cpdf_bota_page.dart
  63. 83 0
      lib/widgets/viewer/pdfdisplaysettings/cpdf_display_mode_widget.dart
  64. 60 0
      lib/widgets/viewer/pdfdisplaysettings/cpdf_display_settings_page.dart
  65. 114 0
      lib/widgets/viewer/pdfdisplaysettings/cpdf_page_mode_widget.dart
  66. 98 0
      lib/widgets/viewer/pdfdisplaysettings/cpdf_page_setting_widget.dart
  67. 103 0
      lib/widgets/viewer/pdfdisplaysettings/cpdf_themes_widget.dart

+ 10 - 0
android/src/main/java/com/compdfkit/flutter/compdfkit_flutter/common/pdfprovider/provider/CPDFViewCtrlDataProvider.java

@@ -44,6 +44,9 @@ public class CPDFViewCtrlDataProvider implements CPDFDataProvider {
                 case Method.SET_CONTINUE_MODE:
                     readerView.setContinueMode(ParamsUtil.getBoolean(arguments, true));
                     break;
+                case Method.SET_COVER_PAGE_MODE:
+                    readerView.setCoverPageMode(ParamsUtil.getBoolean(arguments, false));
+                    break;
                 case Method.SET_CROP_MODE:
                     readerView.setCropMode(ParamsUtil.getBoolean(arguments, false));
                     break;
@@ -76,6 +79,9 @@ public class CPDFViewCtrlDataProvider implements CPDFDataProvider {
                 case Method.IS_CONTINUE_MODE:
                     result.success(readerView.isContinueMode());
                     break;
+                case Method.IS_COVER_MODE:
+                    result.success(readerView.isCoverPageMode());
+                    break;
                 case Method.IS_CROP_MODE:
                     result.success(readerView.isCropMode());
                     break;
@@ -103,6 +109,10 @@ public class CPDFViewCtrlDataProvider implements CPDFDataProvider {
         public static final String SET_CROP_MODE = "setCropMode";
         public static final String IS_CROP_MODE = "isCropMode";
 
+        public static final String SET_COVER_PAGE_MODE = "setCoverPageMode";
+
+        public static final String IS_COVER_MODE = "isCoverPageMode";
+
         public static final String SET_READ_BACKGROUND_COLOR = "setReadBackgroundColor";
         public static final String GET_READ_BACKGROUND_COLOR = "getReadBackgroundColor";
 

BIN
assets/images/1.5x/ic_book_mode.png


BIN
assets/images/1.5x/ic_continuous_scroll.png


BIN
assets/images/1.5x/ic_crop_mode.png


BIN
assets/images/1.5x/ic_double_page.png


BIN
assets/images/1.5x/ic_horizontal_scrolling.png


BIN
assets/images/1.5x/ic_single_page.png


BIN
assets/images/1.5x/ic_themes_dark.png


BIN
assets/images/1.5x/ic_themes_light.png


BIN
assets/images/1.5x/ic_themes_reseda.png


BIN
assets/images/1.5x/ic_themes_sepia.png


BIN
assets/images/1.5x/ic_themes_sepia_dark.png


BIN
assets/images/1.5x/ic_vertical_scrolling.png


BIN
assets/images/2.0x/ic_book_mode.png


BIN
assets/images/2.0x/ic_continuous_scroll.png


BIN
assets/images/2.0x/ic_crop_mode.png


BIN
assets/images/2.0x/ic_double_page.png


BIN
assets/images/2.0x/ic_horizontal_scrolling.png


BIN
assets/images/2.0x/ic_single_page.png


BIN
assets/images/2.0x/ic_themes_dark.png


BIN
assets/images/2.0x/ic_themes_light.png


BIN
assets/images/2.0x/ic_themes_reseda.png


BIN
assets/images/2.0x/ic_themes_sepia.png


BIN
assets/images/2.0x/ic_themes_sepia_dark.png


BIN
assets/images/2.0x/ic_vertical_scrolling.png


BIN
assets/images/3.0x/ic_book_mode.png


BIN
assets/images/3.0x/ic_continuous_scroll.png


BIN
assets/images/3.0x/ic_crop_mode.png


BIN
assets/images/3.0x/ic_double_page.png


BIN
assets/images/3.0x/ic_horizontal_scrolling.png


BIN
assets/images/3.0x/ic_single_page.png


BIN
assets/images/3.0x/ic_themes_dark.png


BIN
assets/images/3.0x/ic_themes_light.png


BIN
assets/images/3.0x/ic_themes_reseda.png


BIN
assets/images/3.0x/ic_themes_sepia.png


BIN
assets/images/3.0x/ic_themes_sepia_dark.png


BIN
assets/images/3.0x/ic_vertical_scrolling.png


BIN
assets/images/ic_book_mode.png


BIN
assets/images/ic_continuous_scroll.png


BIN
assets/images/ic_crop_mode.png


BIN
assets/images/ic_double_page.png


BIN
assets/images/ic_horizontal_scrolling.png


BIN
assets/images/ic_single_page.png


BIN
assets/images/ic_themes_dark.png


BIN
assets/images/ic_themes_light.png


BIN
assets/images/ic_themes_reseda.png


BIN
assets/images/ic_themes_sepia.png


BIN
assets/images/ic_themes_sepia_dark.png


BIN
assets/images/ic_vertical_scrolling.png


+ 1 - 1
example/lib/main.dart

@@ -45,6 +45,6 @@ class _MyAppState extends State<MyApp> {
 
   @override
   Widget build(BuildContext context) {
-    return const CPDFReaderViewPage(isDark: true);
+    return const CPDFReaderViewPage(isDark: false);
   }
 }

+ 15 - 0
lib/common/util/Strings.dart

@@ -12,4 +12,19 @@ class Strings {
   static const String Bookmarks = 'Bookmarks';
   static const String Outlines = 'Outlines';
   static const String NoOutlines = 'No Outlines';
+  static const String ViewSetting = 'View Setting';
+  static const String DisplayMode = 'Display Mode';
+  static const String VerticalScrolling = 'Vertical Scrolling';
+  static const String HorizontalScrolling = 'Horizontal Scrolling';
+  static const String SinglePage = 'Single Page';
+  static const String DoublePage = 'Double Page';
+  static const String BookMode = 'Book Mode';
+  static const String ContinuousScroll = 'Continuous Scroll';
+  static const String Crop = 'Crop';
+  static const String Themes = 'Themes';
+  static const String Light = 'Light';
+  static const String Dark = 'Dark';
+  static const String Sepia = 'Sepia';
+  static const String Reseda = 'Reseda';
+
 }

+ 43 - 0
lib/core/cpdf_view_ctrl.dart

@@ -1,5 +1,6 @@
 import 'dart:async';
 
+import 'package:compdfkit_flutter/common/util/cpdf_color_extension.dart';
 import 'package:flutter/services.dart';
 
 import 'document/cpdf_document.dart';
@@ -55,6 +56,48 @@ class CPDFViewCtrl {
     await _methodChannel.invokeMethod('setVerticalMode', verticalMode);
   }
 
+  Future<bool> isDoublePageMode() async {
+    return await _methodChannel.invokeMethod('isDoublePage');
+  }
+
+  void setDoublePageMode(bool doublePage) async {
+    await _methodChannel.invokeMethod('setDoublePage', doublePage);
+  }
+
+  Future<bool> isCoverPageMode() async {
+    return await _methodChannel.invokeMethod('isCoverPageMode');
+  }
+
+  void setCoverPageMode(bool coverPage) async {
+    await _methodChannel.invokeMethod('setCoverPageMode', coverPage);
+  }
+
+  Future<bool> isContinueMode() async {
+    return await _methodChannel.invokeMethod('isContinueMode');
+  }
+
+  void setContinueMode(bool continueMode) async {
+    await _methodChannel.invokeMethod('setContinueMode', continueMode);
+  }
+
+  Future<bool> isCropMode() async {
+    return await _methodChannel.invokeMethod('isCropMode');
+  }
+
+  void setCropMode(bool cropMode) async {
+    await _methodChannel.invokeMethod('setCropMode', cropMode);
+  }
+
+  Future<Color> getReadBackgroundColor() async {
+    String hexColor = await _methodChannel.invokeMethod('getReadBackgroundColor');
+    return HexColor.fromHex(hexColor);
+  }
+
+  void setReadBackgroundColor(Color color) async {
+    await _methodChannel.invokeMethod('setReadBackgroundColor', color.toHex());
+  }
+
+
   void setDisplayPageIndex(int pageIndex) async {
     await _methodChannel.invokeMethod('setDisplayPageIndex', {
       'pageIndex' : pageIndex,

+ 5 - 0
lib/theme/colors.dart

@@ -33,4 +33,9 @@ class CPDFColors{
   static const readerSettingHeadBgColorLight = Color(0xFFF2F2F2);
   static const readerSettingHeadBgColorDark = Color(0xFF303238);
 
+  static const themesLight = Colors.white;
+  static const themesDark = Colors.black;
+  static const themesSepia = Color(0xFFFFEFBE);
+  static const themesReseda = Color(0xFFCDE6D0);
+
 }

+ 24 - 9
lib/theme/themes.dart

@@ -9,6 +9,9 @@ import 'package:flutter/material.dart';
 
 import 'colors.dart';
 
+const lightTextStyle = TextStyle(color: Color(0xFF43474D));
+const darkTextStyle = TextStyle(color: Colors.white);
+
 final comPDFKitLightTheme = ThemeData(
     splashColor: const Color(0x334982E6),
     highlightColor: const Color(0x334982E6),
@@ -27,10 +30,16 @@ final comPDFKitLightTheme = ThemeData(
       labelColor: Color(0xFF1460F3),
       unselectedLabelColor: Color(0xFF43474D),
     ),
-    textTheme: const TextTheme(
-        titleMedium: TextStyle(color: Color(0xFF43474D), fontSize: 16),
-        titleLarge: TextStyle(color: Color(0xFF43474D)),
-        titleSmall: TextStyle(color: Color(0xFF43474D), fontSize: 14)));
+    textTheme: TextTheme(
+        titleMedium: lightTextStyle.copyWith(fontSize: 16),
+        titleLarge: lightTextStyle.copyWith(fontSize: 22),
+        titleSmall: lightTextStyle.copyWith(fontSize: 14),
+        labelLarge: lightTextStyle.copyWith(fontSize: 14),
+        labelMedium: lightTextStyle.copyWith(fontSize: 12),
+        labelSmall: lightTextStyle.copyWith(fontSize: 11),
+        bodyLarge: lightTextStyle.copyWith(fontSize: 16),
+        bodyMedium: lightTextStyle.copyWith(fontSize: 14),
+        bodySmall: lightTextStyle.copyWith(fontSize: 12)));
 
 final comPDFKitDarkTheme = ThemeData(
     highlightColor: const Color(0x334982E6),
@@ -43,17 +52,23 @@ final comPDFKitDarkTheme = ThemeData(
       secondary: Color(0xFF6499FF),
       onSecondary: Color(0xFF606773),
       background: Color(0xFF414347),
-      secondaryContainer: Color(0xFF414347),
+      secondaryContainer: Color(0xFF303238),
     ),
     tabBarTheme: const TabBarTheme(
       dividerColor: Color(0xFF6499FF),
       labelColor: Color(0xFF6499FF),
       unselectedLabelColor: Colors.white,
     ),
-    textTheme: const TextTheme(
-        titleMedium: TextStyle(color: Colors.white, fontSize: 16),
-        titleLarge: TextStyle(color: Colors.white),
-        titleSmall: TextStyle(color: Colors.white, fontSize: 14)));
+    textTheme: TextTheme(
+        titleMedium: darkTextStyle.copyWith(fontSize: 16),
+        titleLarge: darkTextStyle.copyWith(fontSize: 22),
+        titleSmall: darkTextStyle.copyWith(fontSize: 14),
+        labelLarge: darkTextStyle.copyWith(fontSize: 14),
+        labelMedium: darkTextStyle.copyWith(fontSize: 12),
+        labelSmall: darkTextStyle.copyWith(fontSize: 11),
+        bodyLarge: darkTextStyle.copyWith(fontSize: 16),
+        bodyMedium: darkTextStyle.copyWith(fontSize: 14),
+        bodySmall: darkTextStyle.copyWith(fontSize: 12)));
 
 InputDecoration textFieldStyle(BuildContext context) {
   return InputDecoration(

+ 23 - 0
lib/widgets/common/radio/cpdf_radio_group_data.dart

@@ -0,0 +1,23 @@
+import 'dart:ui';
+
+///
+///  Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+///
+///  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+///  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+///  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+///  This notice may not be removed from this file.
+
+
+
+class CPDFRadioGroupData {
+
+  String leadingIcon;
+
+  String title;
+
+  int checkId;
+
+  CPDFRadioGroupData(this.checkId, this.leadingIcon, this.title);
+
+}

+ 55 - 0
lib/widgets/common/radio/cpdf_radio_list_group.dart

@@ -0,0 +1,55 @@
+///
+///  Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+///
+///  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+///  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+///  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+///  This notice may not be removed from this file.
+
+import 'package:compdfkit_flutter/widgets/common/radio/cpdf_radio_list_tile.dart';
+import 'package:flutter/material.dart';
+
+import 'cpdf_radio_group_data.dart';
+
+class CPDFRadioListGroup extends StatefulWidget {
+  final checkId;
+
+  final List<CPDFRadioGroupData> list;
+
+  final ValueChanged<int>? onChecked;
+
+  final Color? iconColor;
+
+  const CPDFRadioListGroup(
+      {Key? key,
+      this.checkId = -1,
+      required this.list,
+      this.iconColor,
+      this.onChecked})
+      : super(key: key);
+
+  @override
+  State<CPDFRadioListGroup> createState() => _CPDFRadioListGroupState();
+}
+
+class _CPDFRadioListGroupState extends State<CPDFRadioListGroup> {
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: widget.list.map((e) {
+        return CPDFRadioListTile(
+          iconColor: widget.iconColor,
+          leadingImageIcon: e.leadingIcon,
+          leadingPackage: 'compdfkit_flutter',
+          titleText: e.title,
+          checked: e.checkId == widget.checkId,
+          onPressed: () {
+            if (widget.onChecked != null) {
+              widget.onChecked!(e.checkId);
+            }
+          },
+        );
+      }).toList(),
+    );
+  }
+}

+ 64 - 0
lib/widgets/common/radio/cpdf_radio_list_tile.dart

@@ -0,0 +1,64 @@
+///
+///  Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+///
+///  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+///  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+///  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+///  This notice may not be removed from this file.
+
+import 'package:flutter/material.dart';
+
+class CPDFRadioListTile extends StatelessWidget {
+  final String leadingImageIcon;
+
+  final String leadingPackage;
+
+  final String titleText;
+
+  final bool checked;
+
+  final VoidCallback? onPressed;
+
+  final Color? iconColor;
+
+  const CPDFRadioListTile(
+      {Key? key,
+      required this.leadingImageIcon,
+      this.leadingPackage = '',
+      required this.titleText,
+      required this.checked,
+      this.iconColor,
+      this.onPressed})
+      : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return _item(context, leadingImageIcon, titleText);
+  }
+
+  Widget _item(BuildContext context, String imageIcon, String titleText) {
+    return Ink(
+        height: 55,
+        color: Theme.of(context).colorScheme.background,
+        child: InkWell(
+          onTap: onPressed,
+          child: Padding(
+              padding: const EdgeInsets.symmetric(horizontal: 16),
+              child: Row(
+                children: [
+                  Image.asset(imageIcon, package: leadingPackage, color: iconColor),
+                  Expanded(
+                      child: Padding(
+                    padding: const EdgeInsets.only(left: 16),
+                    child: Text(titleText,
+                        style: Theme.of(context).textTheme.bodyMedium),
+                  )),
+                  if (checked) ...{
+                    Icon(Icons.check,
+                        color: Theme.of(context).colorScheme.primaryContainer)
+                  }
+                ],
+              )),
+        ));
+  }
+}

+ 62 - 0
lib/widgets/common/switch/cpdf_switch_list_tile.dart

@@ -0,0 +1,62 @@
+///
+///  Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+///
+///  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+///  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+///  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+///  This notice may not be removed from this file.
+
+import 'package:flutter/material.dart';
+
+class CPDFSwitchListTile extends StatelessWidget {
+  final String leadingImageIcon;
+
+  final String leadingPackage;
+
+  final String titleText;
+
+  final bool checked;
+
+  final Color? iconColor;
+
+  final ValueChanged<bool>? onChecked;
+
+  const CPDFSwitchListTile(
+      {Key? key,
+      required this.leadingImageIcon,
+      this.leadingPackage = '',
+      required this.titleText,
+      required this.checked,
+      this.iconColor,
+      this.onChecked})
+      : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return _item(context, leadingImageIcon, titleText);
+  }
+
+  Widget _item(BuildContext context, String imageIcon, String titleText) {
+    return Ink(
+        height: 55,
+        color: Theme.of(context).colorScheme.background,
+        child: Padding(
+            padding: const EdgeInsets.symmetric(horizontal: 16),
+            child: Row(
+              children: [
+                Image.asset(
+                  imageIcon,
+                  package: leadingPackage,
+                  color: iconColor,
+                ),
+                Expanded(
+                    child: Padding(
+                  padding: const EdgeInsets.only(left: 16),
+                  child: Text(titleText,
+                      style: Theme.of(context).textTheme.bodyMedium),
+                )),
+                Switch(value: checked, onChanged: onChecked)
+              ],
+            )));
+  }
+}

+ 6 - 1
lib/widgets/common/views/cpdf_main_tool_bar.dart

@@ -2,6 +2,7 @@ import 'package:compdfkit_flutter/core/cpdf_view_ctrl.dart';
 import 'package:compdfkit_flutter/theme/colors.dart';
 import 'package:compdfkit_flutter/theme/themes.dart';
 import 'package:compdfkit_flutter/widgets/viewer/pdfbota/cpdf_bota_page.dart';
+import 'package:compdfkit_flutter/widgets/viewer/pdfdisplaysettings/cpdf_display_settings_page.dart';
 import 'package:flutter/material.dart';
 
 import '../../viewer/pdfbota/pdfthumbnail/cpdf_thumbnail_page.dart';
@@ -68,7 +69,11 @@ class CPDFMainToolbar extends StatelessWidget implements PreferredSizeWidget {
       CPDFActions.bota(onPressed: (context)  {
         pushToBota(context, const [CPDFBotaType.outline]);
       }),
-      CPDFActions.more()
+      CPDFActions.more(onPressed: (context){
+        Navigator.push(context, MaterialPageRoute(builder: (_) {
+          return CPDFDisplaySettingsPage(ctrl: ctrl, isDark: isDark,);
+        }));
+      })
     ];
   }
 

+ 38 - 0
lib/widgets/common/views/cpdf_scaffold.dart

@@ -0,0 +1,38 @@
+///
+///  Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+///
+///  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+///  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+///  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+///  This notice may not be removed from this file.
+
+import 'package:flutter/material.dart';
+
+import '../../../theme/colors.dart';
+import '../../../theme/themes.dart';
+
+class CPDFScaffold extends StatelessWidget {
+  final bool isDark;
+
+  final PreferredSizeWidget? appBar;
+
+  final Widget? body;
+
+  const CPDFScaffold({Key? key, this.isDark = false, this.appBar, this.body})
+      : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return Theme(
+      data: isDark
+          ? comPDFKitDarkTheme
+          : comPDFKitLightTheme.copyWith(
+              colorScheme: comPDFKitLightTheme.colorScheme
+                  .copyWith(primary: CPDFColors.backgroundLight)),
+      child: Scaffold(
+        appBar: appBar,
+        body: body,
+      ),
+    );
+  }
+}

+ 20 - 13
lib/widgets/common/views/cpdf_tool_bar.dart

@@ -8,10 +8,7 @@ import 'package:flutter/material.dart';
 ///  This notice may not be removed from this file.
 
 class CPDFToolbar extends AppBar {
-
-  final VoidCallback? onPressed;
-
-  final Widget? leadingIcon;
+  late final Widget? leadingIcon;
 
   CPDFToolbar(
       {super.key,
@@ -19,17 +16,27 @@ class CPDFToolbar extends AppBar {
       super.actions,
       super.backgroundColor,
       this.leadingIcon,
-      super.bottom,
-      this.onPressed})
+      super.bottom})
       : super(
-          leading: leadingIcon != null
-              ? IconButton(
-                  onPressed: onPressed,
-                  icon: leadingIcon,
-                  splashRadius: 24,
-                )
-              : null,
+          leading: leadingIcon,
           elevation: 2,
           titleSpacing: title == null ? 15 : 0,
         );
+
+  CPDFToolbar.normal(
+      {super.key,
+      required BuildContext context,
+      VoidCallback? leadingOnPressed,
+      required String titleText, super.bottom})
+      : super(
+            leading: IconButton(
+              onPressed: leadingOnPressed,
+              icon: Icon(Icons.arrow_back,
+                  color: Theme.of(context).colorScheme.onBackground),
+            ),
+            title: Text(
+              titleText,
+              style: const TextStyle(
+                  fontFamily: 'sans-serif-medium', fontSize: 22),
+            ),elevation: 2);
 }

+ 23 - 28
lib/widgets/viewer/pdfbota/cpdf_bota_page.dart

@@ -2,6 +2,7 @@ import 'package:compdfkit_flutter/common/util/Strings.dart';
 import 'package:compdfkit_flutter/core/cpdf_view_ctrl.dart';
 import 'package:compdfkit_flutter/theme/colors.dart';
 import 'package:compdfkit_flutter/theme/themes.dart';
+import 'package:compdfkit_flutter/widgets/common/views/cpdf_scaffold.dart';
 import 'package:compdfkit_flutter/widgets/viewer/pdfbota/pdfoutline/cpdf_outline_page.dart';
 import 'package:compdfkit_flutter/widgets/viewer/pdfbota/pdfthumbnail/cpdf_thumbnail_page.dart';
 import 'package:flutter/material.dart';
@@ -61,36 +62,30 @@ class _CPDFBotaPageState extends State<CPDFBotaPage>
 
   @override
   Widget build(BuildContext context) {
-    return Theme(
-        data: widget.isDark
-            ? comPDFKitDarkTheme
-            : comPDFKitLightTheme.copyWith(
-                colorScheme: comPDFKitLightTheme.colorScheme
-                    .copyWith(primary: CPDFColors.backgroundLight)),
-        child: Scaffold(
-          appBar: CPDFToolbar(
-            bottom: widget.types.length > 1
-                ? TabBar(controller: _tabController, tabs: _tabItems())
-                : null,
-            leadingIcon: IconButton(
-                onPressed: () {
-                  Navigator.pop(context);
-                },
-                icon: Icon(Icons.arrow_back,
-                    color: Theme.of(context).colorScheme.onBackground)),
-            title: ValueListenableBuilder(
-              builder: (BuildContext context, String title, Widget? child) {
-                return Text(title,
-                    style: const TextStyle(
-                        fontFamily: 'sans-serif-medium', fontSize: 22));
+    return CPDFScaffold(
+        isDark: widget.isDark,
+        appBar: CPDFToolbar(
+          bottom: widget.types.length > 1
+              ? TabBar(controller: _tabController, tabs: _tabItems())
+              : null,
+          leadingIcon: IconButton(
+              onPressed: () {
+                Navigator.pop(context);
               },
-              valueListenable: _title,
-            ),
-          ),
-          body: TabBarView(
-            controller: _tabController,
-            children: _pages(),
+              icon: Icon(Icons.arrow_back,
+                  color: Theme.of(context).colorScheme.onBackground)),
+          title: ValueListenableBuilder(
+            builder: (BuildContext context, String title, Widget? child) {
+              return Text(title,
+                  style: const TextStyle(
+                      fontFamily: 'sans-serif-medium', fontSize: 22));
+            },
+            valueListenable: _title,
           ),
+        ),
+        body: TabBarView(
+          controller: _tabController,
+          children: _pages(),
         ));
   }
 

+ 83 - 0
lib/widgets/viewer/pdfdisplaysettings/cpdf_display_mode_widget.dart

@@ -0,0 +1,83 @@
+///
+///  Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+///
+///  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+///  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+///  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+///  This notice may not be removed from this file.
+
+import 'package:compdfkit_flutter/core/cpdf_view_ctrl.dart';
+import 'package:flutter/material.dart';
+
+import '../../../common/util/Strings.dart';
+import '../../common/radio/cpdf_radio_group_data.dart';
+import '../../common/radio/cpdf_radio_list_group.dart';
+
+final displayModes = [
+  CPDFRadioGroupData(
+      0, 'assets/images/ic_vertical_scrolling.png', Strings.VerticalScrolling),
+  CPDFRadioGroupData(1, 'assets/images/ic_horizontal_scrolling.png',
+      Strings.HorizontalScrolling)
+];
+
+class CPDFDisplayModeWidget extends StatefulWidget {
+  final CPDFViewCtrl ctrl;
+
+  const CPDFDisplayModeWidget({Key? key, required this.ctrl}) : super(key: key);
+
+  @override
+  State<CPDFDisplayModeWidget> createState() => _CPDFDisplayModeWidgetState();
+}
+
+class _CPDFDisplayModeWidgetState extends State<CPDFDisplayModeWidget> {
+  bool _isVerticalMode = true;
+
+  @override
+  void initState() {
+    super.initState();
+    _initDisplaySettings();
+  }
+
+  void _initDisplaySettings() async {
+    CPDFViewCtrl ctrl = widget.ctrl;
+    bool verticalMode = await ctrl.isVerticalMode();
+    setState(() {
+      _isVerticalMode = verticalMode;
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        _title(context, Strings.DisplayMode),
+        CPDFRadioListGroup(
+          iconColor: Theme.of(context).brightness == Brightness.dark
+              ? Colors.white
+              : null,
+          checkId: _isVerticalMode ? 0 : 1,
+          list: displayModes,
+          onChecked: (checkId) {
+            setState(() {
+              _isVerticalMode = checkId == 0;
+              widget.ctrl.setVerticalMode(_isVerticalMode);
+            });
+          },
+        )
+      ],
+    );
+  }
+
+  Widget _title(BuildContext context, String title) {
+    return Container(
+      alignment: Alignment.centerLeft,
+      height: 28,
+      padding: const EdgeInsets.symmetric(horizontal: 16),
+      color: Theme.of(context).colorScheme.secondaryContainer,
+      child: Text(
+        title,
+        style: Theme.of(context).textTheme.labelMedium,
+      ),
+    );
+  }
+}

+ 60 - 0
lib/widgets/viewer/pdfdisplaysettings/cpdf_display_settings_page.dart

@@ -0,0 +1,60 @@
+///
+///  Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+///
+///  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+///  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+///  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+///  This notice may not be removed from this file.
+import 'package:compdfkit_flutter/common/util/Strings.dart';
+import 'package:compdfkit_flutter/core/cpdf_view_ctrl.dart';
+import 'package:compdfkit_flutter/widgets/common/views/cpdf_scaffold.dart';
+import 'package:compdfkit_flutter/widgets/common/views/cpdf_tool_bar.dart';
+import 'package:compdfkit_flutter/widgets/viewer/pdfdisplaysettings/cpdf_display_mode_widget.dart';
+import 'package:compdfkit_flutter/widgets/viewer/pdfdisplaysettings/cpdf_page_mode_widget.dart';
+import 'package:compdfkit_flutter/widgets/viewer/pdfdisplaysettings/cpdf_page_setting_widget.dart';
+import 'package:compdfkit_flutter/widgets/viewer/pdfdisplaysettings/cpdf_themes_widget.dart';
+import 'package:flutter/material.dart';
+
+class CPDFDisplaySettingsPage extends StatefulWidget {
+  final bool isDark;
+
+  final CPDFViewCtrl ctrl;
+
+  const CPDFDisplaySettingsPage(
+      {Key? key, this.isDark = false, required this.ctrl})
+      : super(key: key);
+
+  @override
+  State<CPDFDisplaySettingsPage> createState() =>
+      _CPDFDisplaySettingsPageState();
+}
+
+class _CPDFDisplaySettingsPageState extends State<CPDFDisplaySettingsPage> {
+  @override
+  void initState() {
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return CPDFScaffold(
+      isDark: widget.isDark,
+      appBar: CPDFToolbar.normal(
+        context: context,
+        titleText: Strings.ViewSetting,
+        leadingOnPressed: () {
+          Navigator.pop(context);
+        },
+      ),
+      body: Column(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          CPDFDisplayModeWidget(ctrl: widget.ctrl),
+          CPDFPageModeWidget(ctrl: widget.ctrl),
+          CPDFPageSettingWidget(ctrl: widget.ctrl),
+          CPDFThemesWidget(ctrl: widget.ctrl)
+        ],
+      ),
+    );
+  }
+}

+ 114 - 0
lib/widgets/viewer/pdfdisplaysettings/cpdf_page_mode_widget.dart

@@ -0,0 +1,114 @@
+///
+///  Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+///
+///  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+///  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+///  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+///  This notice may not be removed from this file.
+
+import 'package:compdfkit_flutter/core/cpdf_view_ctrl.dart';
+import 'package:flutter/material.dart';
+
+import '../../../common/util/Strings.dart';
+import '../../common/radio/cpdf_radio_group_data.dart';
+import '../../common/radio/cpdf_radio_list_group.dart';
+
+const singlePage = 0;
+
+const doublePage = 1;
+
+const coverPage = 2;
+
+final pageModes = [
+  CPDFRadioGroupData(
+      singlePage, 'assets/images/ic_single_page.png', Strings.SinglePage),
+  CPDFRadioGroupData(
+      doublePage, 'assets/images/ic_double_page.png', Strings.DoublePage),
+  CPDFRadioGroupData(
+      coverPage, 'assets/images/ic_book_mode.png', Strings.BookMode),
+];
+
+class CPDFPageModeWidget extends StatefulWidget {
+  final CPDFViewCtrl ctrl;
+
+  const CPDFPageModeWidget({Key? key, required this.ctrl}) : super(key: key);
+
+  @override
+  State<CPDFPageModeWidget> createState() => _CPDFPageModeWidgetState();
+}
+
+class _CPDFPageModeWidgetState extends State<CPDFPageModeWidget> {
+  // 0:single page、 1: double page、 2: book mode
+  int _pageMode = -1;
+
+  @override
+  void initState() {
+    super.initState();
+    _initDisplaySettings();
+  }
+
+  void _initDisplaySettings() async {
+    CPDFViewCtrl ctrl = widget.ctrl;
+    bool isDoublePage = await ctrl.isDoublePageMode();
+    bool isCoverPage = await ctrl.isCoverPageMode();
+    setState(() {
+      if (isDoublePage) {
+        if (isCoverPage) {
+          _pageMode = coverPage;
+        } else {
+          _pageMode = doublePage;
+        }
+      } else {
+        _pageMode = singlePage;
+      }
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        _title(context, ''),
+        CPDFRadioListGroup(
+          iconColor: Theme.of(context).brightness == Brightness.dark
+              ? Colors.white
+              : null,
+          checkId: _pageMode,
+          list: pageModes,
+          onChecked: (checkId) {
+            setState(() {
+              _pageMode = checkId;
+              switch (checkId) {
+                case doublePage:
+                  widget.ctrl.setDoublePageMode(true);
+                  widget.ctrl.setCoverPageMode(false);
+                  break;
+                case coverPage:
+                  widget.ctrl.setDoublePageMode(true);
+                  widget.ctrl.setCoverPageMode(true);
+                  break;
+                default:
+                  widget.ctrl.setDoublePageMode(false);
+                  widget.ctrl.setCoverPageMode(false);
+                  break;
+              }
+            });
+          },
+        )
+      ],
+    );
+  }
+
+  Widget _title(BuildContext context, String title) {
+    return Container(
+      alignment: Alignment.centerLeft,
+      height: 28,
+      padding: const EdgeInsets.symmetric(horizontal: 16),
+      color: Theme.of(context).colorScheme.secondaryContainer,
+      child: Text(
+        title,
+        style: Theme.of(context).textTheme.labelMedium,
+      ),
+    );
+  }
+}

+ 98 - 0
lib/widgets/viewer/pdfdisplaysettings/cpdf_page_setting_widget.dart

@@ -0,0 +1,98 @@
+///
+///  Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+///
+///  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+///  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+///  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+///  This notice may not be removed from this file.
+
+import 'package:compdfkit_flutter/core/cpdf_view_ctrl.dart';
+import 'package:flutter/material.dart';
+
+import '../../../common/util/Strings.dart';
+import '../../common/radio/cpdf_radio_group_data.dart';
+import '../../common/radio/cpdf_radio_list_group.dart';
+import '../../common/switch/cpdf_switch_list_tile.dart';
+
+class CPDFPageSettingWidget extends StatefulWidget {
+  final CPDFViewCtrl ctrl;
+
+  const CPDFPageSettingWidget({Key? key, required this.ctrl}) : super(key: key);
+
+  @override
+  State<CPDFPageSettingWidget> createState() => _CPDFPageSettingWidgetState();
+}
+
+class _CPDFPageSettingWidgetState extends State<CPDFPageSettingWidget> {
+  bool _isContinuousScroll = false;
+
+  bool _cropMode = false;
+
+  @override
+  void initState() {
+    super.initState();
+    _initDisplaySettings();
+  }
+
+  void _initDisplaySettings() async {
+    CPDFViewCtrl ctrl = widget.ctrl;
+    bool isContinuous = await ctrl.isContinueMode();
+    bool isCrop = await ctrl.isCropMode();
+    setState(() {
+      _isContinuousScroll = isContinuous;
+      _cropMode = isCrop;
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Column(
+      children: [
+        _title(context, ''),
+        CPDFSwitchListTile(
+          iconColor: Theme.of(context).brightness == Brightness.dark
+              ? Colors.white
+              : null,
+          leadingPackage: 'compdfkit_flutter',
+          leadingImageIcon: 'assets/images/ic_continuous_scroll.png',
+          titleText: Strings.ContinuousScroll,
+          checked: _isContinuousScroll,
+          onChecked: (check) {
+            setState(() {
+              _isContinuousScroll = check;
+              widget.ctrl.setContinueMode(_isContinuousScroll);
+            });
+          },
+        ),
+        CPDFSwitchListTile(
+          iconColor: Theme.of(context).brightness == Brightness.dark
+              ? Colors.white
+              : null,
+          leadingPackage: 'compdfkit_flutter',
+          leadingImageIcon: 'assets/images/ic_crop_mode.png',
+          titleText: Strings.Crop,
+          checked: _cropMode,
+          onChecked: (check) {
+            setState(() {
+              _cropMode = check;
+              widget.ctrl.setCropMode(_cropMode);
+            });
+          },
+        )
+      ],
+    );
+  }
+
+  Widget _title(BuildContext context, String title) {
+    return Container(
+      alignment: Alignment.centerLeft,
+      height: 28,
+      padding: const EdgeInsets.symmetric(horizontal: 16),
+      color: Theme.of(context).colorScheme.secondaryContainer,
+      child: Text(
+        title,
+        style: Theme.of(context).textTheme.labelMedium,
+      ),
+    );
+  }
+}

+ 103 - 0
lib/widgets/viewer/pdfdisplaysettings/cpdf_themes_widget.dart

@@ -0,0 +1,103 @@
+///
+///  Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+///
+///  THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
+///  AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
+///  UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
+///  This notice may not be removed from this file.
+
+import 'package:compdfkit_flutter/core/cpdf_view_ctrl.dart';
+import 'package:compdfkit_flutter/theme/colors.dart';
+import 'package:flutter/material.dart';
+
+import '../../../common/util/Strings.dart';
+import '../../common/radio/cpdf_radio_group_data.dart';
+import '../../common/radio/cpdf_radio_list_group.dart';
+import '../../common/radio/cpdf_radio_list_tile.dart';
+import '../../common/switch/cpdf_switch_list_tile.dart';
+
+class CPDFThemesWidget extends StatefulWidget {
+  final CPDFViewCtrl ctrl;
+
+  const CPDFThemesWidget({Key? key, required this.ctrl}) : super(key: key);
+
+  @override
+  State<CPDFThemesWidget> createState() => _CPDFPageThemesWidgetState();
+}
+
+class _CPDFPageThemesWidgetState extends State<CPDFThemesWidget> {
+  final themes = [
+    CPDFRadioGroupData(CPDFColors.themesLight.value,
+        'assets/images/ic_themes_light.png', Strings.Light),
+    CPDFRadioGroupData(CPDFColors.themesDark.value,
+        'assets/images/ic_themes_dark.png', Strings.Dark),
+    CPDFRadioGroupData(CPDFColors.themesSepia.value,
+        'assets/images/ic_themes_sepia.png', Strings.Sepia),
+    CPDFRadioGroupData(CPDFColors.themesReseda.value,
+        'assets/images/ic_themes_reseda.png', Strings.Reseda),
+  ];
+
+  int _theme = CPDFColors.themesLight.value;
+
+  @override
+  void initState() {
+    super.initState();
+    _initDisplaySettings();
+  }
+
+  void _initDisplaySettings() async {
+    CPDFViewCtrl ctrl = widget.ctrl;
+    ctrl.getReadBackgroundColor().then((value) {
+      setState(() {
+        _theme = value.value;
+      });
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    var sepia = themes.firstWhere((element) {
+      return element.checkId == CPDFColors.themesSepia.value;
+    });
+    if (Theme.of(context).brightness == Brightness.dark) {
+      sepia.leadingIcon = 'assets/images/ic_themes_sepia_dark.png';
+    }
+    var iconColor =
+        Theme.of(context).brightness == Brightness.dark ? Colors.white : null;
+    return Column(
+      children: [
+        _title(context, Strings.Themes),
+        Column(
+            children: themes.map((e) {
+          return CPDFRadioListTile(
+            iconColor:
+                e.checkId != CPDFColors.themesSepia.value ? iconColor : null,
+            leadingImageIcon: e.leadingIcon,
+            leadingPackage: 'compdfkit_flutter',
+            titleText: e.title,
+            checked: e.checkId == _theme,
+            onPressed: () {
+              setState(() {
+                _theme = e.checkId;
+                widget.ctrl.setReadBackgroundColor(Color(e.checkId));
+              });
+            },
+          );
+        }).toList()),
+      ],
+    );
+  }
+
+  Widget _title(BuildContext context, String title) {
+    return Container(
+      alignment: Alignment.centerLeft,
+      height: 28,
+      padding: const EdgeInsets.symmetric(horizontal: 16),
+      color: Theme.of(context).colorScheme.secondaryContainer,
+      child: Text(
+        title,
+        style: Theme.of(context).textTheme.labelMedium,
+      ),
+    );
+  }
+}