Browse Source

PDFTools(Android) - 1.新增Note属性弹窗 2.新增调色盘 3.优化属性面板与调色盘之间的切换效果

liuxiaolong 1 year ago
parent
commit
70315283f5
67 changed files with 2507 additions and 339 deletions
  1. 3 2
      annotation-ctrl-demo/src/main/AndroidManifest.xml
  2. 101 5
      annotation-ctrl-demo/src/main/java/com/compdfkit/demo/annotation/MainActivity.java
  3. 30 11
      annotation-ctrl-demo/src/main/res/layout/activity_main.xml
  4. 1 1
      annotation-ctrl-demo/src/main/res/values-night/themes.xml
  5. 1 1
      annotation-ctrl-demo/src/main/res/values/themes.xml
  6. 3 3
      compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfannotationlist/CPDFAnnotationListFragment.java
  7. 63 12
      compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/CAnnotStyleDialogFragment.java
  8. 16 4
      compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfannotstyle/adapter/CAnnotPropertiesFragmentAdapter.java
  9. 99 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfannotstyle/adapter/CWrapHeightPageChangeCallback.java
  10. 99 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfannotstyle/data/CPropertiesFragmentDatas.java
  11. 0 55
      compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfannotstyle/data/CPropertiesFragmentFactory.java
  12. 42 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfannotstyle/viewmodel/CAnnotStyleViewModel.java
  13. 21 17
      compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfattr/CAnnotStyle.java
  14. 1 3
      compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfmarkup/CLinkStyleFragment.java
  15. 31 4
      compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfmarkup/CMarkupStyleFragment.java
  16. 61 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfnote/CNoteStyleFragment.java
  17. 18 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/interfaces/COnColorChangeListener.java
  18. 1 1
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/interfaces/OnSetPDFDisplayPageIndexListener.java
  19. 133 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/utils/animation/CFillScreenManager.java
  20. 6 6
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/utils/dialog/CGotoPageDialog.java
  21. 36 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/utils/transformer/CascadeTransformer.java
  22. 12 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/utils/viewutils/CViewUtils.java
  23. 144 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/utils/window/CPDFToolbarPopupMenu.java
  24. 57 96
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/CPDFToolBar.java
  25. 7 4
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfannotationbar/CAnnotationToolbar.java
  26. 22 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfannotationbar/adapter/CPDFAnnotationToolListAdapter.java
  27. 12 2
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfannotationbar/bean/CAnnotationType.java
  28. 1 1
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfannotationbar/data/CAnnotationToolDatas.java
  29. 3 3
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfbota/adapter/CBotaViewPagerAdapter.java
  30. 51 3
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/basic/CBasicPropertiesFragment.java
  31. 4 1
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorlist/CColorListAdapter.java
  32. 16 8
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorlist/CColorListView.java
  33. 58 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/CColorPickerFragment.java
  34. 19 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/interfaces/CMotionEventUpdatable.java
  35. 37 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/CThrottledTouchEventHandler.java
  36. 190 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorAlphaSliderView.java
  37. 19 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorPickerData.java
  38. 127 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorPickerView.java
  39. 74 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorRectPalette.java
  40. 81 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorRectSelector.java
  41. 100 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorRectShowView.java
  42. 202 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorRectView.java
  43. 206 0
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorSliderView.java
  44. 61 38
      compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfview/CPDFViewCtrl.java
  45. 3 3
      compdfkit-tools/src/main/java/com/compdfkit/tools/viewer/pdfbookmark/CPDFBookmarkFragment.java
  46. 3 3
      compdfkit-tools/src/main/java/com/compdfkit/tools/viewer/pdfbookmark/adapter/CPDFBookmarkListAdapter.java
  47. 3 3
      compdfkit-tools/src/main/java/com/compdfkit/tools/viewer/pdfoutline/CPDFOutlineFragment.java
  48. 3 3
      compdfkit-tools/src/main/java/com/compdfkit/tools/viewer/pdfoutline/adapter/COutlineListAdapter.java
  49. 3 3
      compdfkit-tools/src/main/java/com/compdfkit/tools/viewer/pdfthumbnail/CPDFThumbnailFragment.java
  50. 3 3
      compdfkit-tools/src/main/java/com/compdfkit/tools/viewer/pdfthumbnail/adpater/CPDFThumbnailListAdapter.java
  51. 7 0
      compdfkit-tools/src/main/res/anim/tools_slide_in_right.xml
  52. 7 0
      compdfkit-tools/src/main/res/anim/tools_slide_out_left.xml
  53. BIN
      compdfkit-tools/src/main/res/drawable/tools_color_picker_bg_color_alpha.png
  54. BIN
      compdfkit-tools/src/main/res/drawable/tools_color_picker_bg_color_rect.png
  55. 9 0
      compdfkit-tools/src/main/res/drawable/tools_common_oval_ripple.xml
  56. 5 0
      compdfkit-tools/src/main/res/drawable/tools_ic_close.xml
  57. 65 18
      compdfkit-tools/src/main/res/layout/tools_annot_style_dialog_fragment.xml
  58. 1 0
      compdfkit-tools/src/main/res/layout/tools_annot_tool_bar.xml
  59. 17 0
      compdfkit-tools/src/main/res/layout/tools_color_pick_fragment.xml
  60. 61 0
      compdfkit-tools/src/main/res/layout/tools_color_pick_view.xml
  61. 3 2
      compdfkit-tools/src/main/res/layout/tools_properties_markup_style_fragment.xml
  62. 26 0
      compdfkit-tools/src/main/res/layout/tools_properties_note_style_fragment.xml
  63. 1 1
      viewer-ctrl-demo/src/main/res/menu/viewer_pdf_more.xml
  64. 1 0
      compdfkit-tools/src/main/res/values/tools_attrs.xml
  65. 4 1
      compdfkit-tools/src/main/res/values/tools_strings.xml
  66. 2 0
      compdfkit-tools/src/main/res/values/tools_styles.xml
  67. 11 18
      viewer-ctrl-demo/src/main/java/com/compdfkit/demo/viewer/PDFViewerSampleActivity.java

+ 3 - 2
annotation-ctrl-demo/src/main/AndroidManifest.xml

@@ -1,12 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.compdfkit.demo.annotation">
 
     <application
         android:allowBackup="true"
         android:icon="@mipmap/ic_launcher"
         android:label="@string/app_name"
         android:supportsRtl="true"
-        android:theme="@style/Theme.Compdfkit_android_demo">
+        android:theme="@style/Annotation_Basic_Theme">
         <activity
             android:name=".MainActivity"
             android:exported="true">

+ 101 - 5
annotation-ctrl-demo/src/main/java/com/compdfkit/demo/annotation/MainActivity.java

@@ -1,17 +1,29 @@
 package com.compdfkit.demo.annotation;
 
 import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
 
 import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.PopupMenu;
 import androidx.core.content.ContextCompat;
 
 import com.compdfkit.demo.annotation.databinding.ActivityMainBinding;
+import com.compdfkit.tools.common.utils.animation.CFillScreenManager;
+import com.compdfkit.tools.common.utils.window.CPDFToolbarPopupMenu;
+import com.compdfkit.tools.common.views.CPDFToolBar;
 import com.compdfkit.tools.common.views.pdfannotationbar.bean.CAnnotationType;
 import com.compdfkit.tools.annotation.pdfproperties.pdfattr.CAnnotAttr;
 import com.compdfkit.tools.common.utils.task.CExtractAssetFileTask;
 import com.compdfkit.tools.common.views.pdfbota.CPDFBOTA;
 import com.compdfkit.tools.common.views.pdfbota.CPDFBotaDialogFragment;
 import com.compdfkit.tools.common.views.pdfbota.CPDFBotaFragmentTabs;
+import com.compdfkit.tools.viewer.pdfdisplaysettings.CPDFDisplaySettingDialogFragment;
+import com.compdfkit.tools.viewer.pdfinfo.CPDFDocumentInfoDialogFragment;
+import com.compdfkit.tools.viewer.pdfsearch.CSearchResultBottomSheetDialogFragment;
+import com.compdfkit.ui.textsearch.ITextSearcher;
+
+import java.util.ArrayList;
 
 public class MainActivity extends AppCompatActivity {
 
@@ -22,6 +34,8 @@ public class MainActivity extends AppCompatActivity {
 
     private ActivityMainBinding binding;
 
+    private CFillScreenManager screenManager = new CFillScreenManager();
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -29,25 +43,107 @@ public class MainActivity extends AppCompatActivity {
         setContentView(binding.getRoot());
         //Extract PDF files from the Android assets folder
         CExtractAssetFileTask.extract(this, QUICK_START_GUIDE, QUICK_START_GUIDE, (filePath) -> binding.pdfView.openPDF(filePath));
-        binding.annotationToolBar.initWithPDFView(binding.pdfView);
-        binding.annotationToolBar.setFragmentManager(getSupportFragmentManager());
         initAnnotationAttributes();
         initListener();
+        initSearchBar();
     }
+
     private void initListener(){
-        binding.pdfToolBar.setBoTaBtnClickListener(v -> {
+        screenManager.bindTopToolView(binding.flTool);
+        screenManager.bindBottomToolViewList(binding.annotationToolBar);
+        screenManager.bindLeftToolViewList(binding.pdfView.indicatorView);
+        screenManager.bindRightToolViewList(binding.pdfView.slideBar);
+        binding.pdfView.setOnTapMainDocAreaCallback(()->{
+            screenManager.fillScreenChange(binding.flTool.getVisibility() == View.VISIBLE);
+        });
+
+        binding.pdfToolBar.addMode(CPDFToolbarPopupMenu.PreviewMode.Annotation);
+        binding.pdfToolBar.setPreviewModeChangeListener((mode, title) -> {
+            if (mode == CPDFToolbarPopupMenu.PreviewMode.PDFView){
+                screenManager.hideFromBottom(binding.annotationToolBar, 200);
+                screenManager.removeToolView(binding.annotationToolBar);
+            }else {
+                screenManager.bindBottomToolViewList(binding.annotationToolBar);
+                screenManager.showFromBottom(binding.annotationToolBar, 200);
+            }
+            binding.pdfView.setAllowAddAndEditAnnot(mode != CPDFToolbarPopupMenu.PreviewMode.PDFView);
+            binding.pdfView.resetAnnotationType();
+        });
+
+        binding.pdfToolBar.setSearchBtnClickListener(v -> {
+            binding.pdfToolBar.setVisibility(View.GONE);
+            binding.pdfSearchToolBar.setVisibility(View.VISIBLE);
+        });
+        binding.pdfToolBar.setThumbnailBtnClickListener(v -> {
             CPDFBotaDialogFragment dialogFragment = CPDFBotaDialogFragment.newInstance();
             dialogFragment.initWithPDFView(binding.pdfView);
-            CPDFBotaFragmentTabs annotationTab = new CPDFBotaFragmentTabs(CPDFBOTA.ANNOTATION, "Annotations");
+            CPDFBotaFragmentTabs annotationTab = new CPDFBotaFragmentTabs(CPDFBOTA.THUMBNAIL, getString(R.string.tools_thumbnail));
             dialogFragment.setBotaDialogTab(annotationTab);
+            dialogFragment.show(getSupportFragmentManager(), "ThumbnailList");
+        });
+
+        binding.pdfToolBar.setBoTaBtnClickListener(v -> {
+            ArrayList<CPDFBotaFragmentTabs> tabs = new ArrayList<>();
+            CPDFBotaFragmentTabs annotationTab = new CPDFBotaFragmentTabs(CPDFBOTA.ANNOTATION, getString(R.string.tools_annotations));
+            CPDFBotaFragmentTabs outlineTab = new CPDFBotaFragmentTabs(CPDFBOTA.OUTLINE, getString(R.string.tools_outline));
+            CPDFBotaFragmentTabs bookmarkTab = new CPDFBotaFragmentTabs(CPDFBOTA.BOOKMARKS, getString(R.string.tools_bookmarks));
+            if (binding.pdfToolBar.getMode() == CPDFToolbarPopupMenu.PreviewMode.PDFView){
+                tabs.add(outlineTab);
+                tabs.add(bookmarkTab);
+            }else {
+                tabs.add(outlineTab);
+                tabs.add(bookmarkTab);
+                tabs.add(annotationTab);
+                annotationTab.setDefaultSelect(true);
+            }
+            CPDFBotaDialogFragment dialogFragment = CPDFBotaDialogFragment.newInstance();
+            dialogFragment.initWithPDFView(binding.pdfView);
+            dialogFragment.setBotaDialogTabs(tabs);
             dialogFragment.show(getSupportFragmentManager(), "annotationList");
         });
+
+        binding.pdfToolBar.setMoreMenuListener(menu -> {
+            if (menu == CPDFToolBar.MoreMenu.DocumentInfo){
+                CPDFDocumentInfoDialogFragment infoDialogFragment = CPDFDocumentInfoDialogFragment.newInstance();
+                infoDialogFragment.initWithPDFView(binding.pdfView);
+                infoDialogFragment.show(getSupportFragmentManager(), "documentInfoDialogFragment");
+            }else {
+                CPDFDisplaySettingDialogFragment displaySettingDialogFragment =  CPDFDisplaySettingDialogFragment.newInstance();
+                displaySettingDialogFragment.initWithPDFView(binding.pdfView);
+                displaySettingDialogFragment.show(getSupportFragmentManager(), "displaySettingsDialog");
+            }
+        });
+
+        binding.annotationToolBar.initWithPDFView(binding.pdfView);
+        binding.annotationToolBar.setFragmentManager(getSupportFragmentManager());
     }
 
+    private void initSearchBar() {
+        binding.pdfSearchToolBar.initWithPDFView(binding.pdfView);
+        binding.pdfSearchToolBar.onSearchQueryResults(list -> {
+            CSearchResultBottomSheetDialogFragment searchResultDialog = new CSearchResultBottomSheetDialogFragment();
+            searchResultDialog.show(getSupportFragmentManager(), "searchResultDialogFragment");
+            searchResultDialog.setSearchTextInfos(list);
+            searchResultDialog.setOnClickSearchItemListener(clickItem -> {
+                binding.pdfView.getCPdfReaderView().setDisplayPageIndex(clickItem.page);
+                binding.pdfView.getCPdfReaderView().getTextSearcher().searchBegin(clickItem.page, clickItem.textRangeIndex);
+                searchResultDialog.dismiss();
+            });
+        });
+
+        binding.pdfSearchToolBar.setExitSearchListener(() -> {
+            ITextSearcher searcher = binding.pdfView.getCPdfReaderView().getTextSearcher();
+            if (searcher != null) {
+                searcher.cancelSearch();
+                binding.pdfView.getCPdfReaderView().invalidateAllChildren();
+            }
+            binding.pdfToolBar.setVisibility(View.VISIBLE);
+            binding.pdfSearchToolBar.setVisibility(View.GONE);
+        });
+    }
 
     private void initAnnotationAttributes() {
         int defaultColor = ContextCompat.getColor(this, R.color.tools_annotation_markup_default_color);
-
         new CAnnotAttr.Builder(binding.pdfView)
                 .setMarkup(CAnnotationType.HIGHLIGHT, defaultColor, 255)
                 .setMarkup(CAnnotationType.UNDERLINE, defaultColor, 255)

+ 30 - 11
annotation-ctrl-demo/src/main/res/layout/activity_main.xml

@@ -6,30 +6,49 @@
     android:layout_height="match_parent"
     tools:context=".MainActivity">
 
-    <com.compdfkit.tools.common.views.CPDFToolBar
-        android:id="@+id/pdf_tool_bar"
+    <FrameLayout
+        android:id="@+id/fl_tool"
         android:layout_width="match_parent"
-        android:layout_height="?android:attr/actionBarSize"
-        app:layout_constraintTop_toTopOf="parent"
-        android:elevation="4dp"
-        app:layout_constraintStart_toStartOf="parent"
+        android:layout_height="wrap_content"
         app:layout_constraintEnd_toEndOf="parent"
-        app:tools_toolbar_title="@string/annotation_title"
-        />
+        app:layout_constraintStart_toStartOf="parent"
+        android:elevation="4dp"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <com.compdfkit.tools.common.views.CPDFToolBar
+            android:id="@+id/pdf_tool_bar"
+            android:layout_width="match_parent"
+            android:layout_height="?android:attr/actionBarSize"
+            android:elevation="4dp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:tools_toolbar_title="@string/tools_menu_pdfview" />
 
+        <com.compdfkit.tools.viewer.pdfsearch.CSearchToolbar
+            android:id="@+id/pdf_search_tool_bar"
+            android:layout_width="match_parent"
+            android:layout_height="?android:attr/actionBarSize"
+            android:visibility="gone"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+             />
 
+    </FrameLayout>
 
     <com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl
         android:id="@+id/pdf_view"
         android:layout_width="match_parent"
-        android:layout_height="0dp"
+        android:layout_height="match_parent"
         app:tools_enable_page_indicator="true"
         app:tools_enable_slider_bar="true"
         app:tools_slider_bar_position="right"
         app:layout_constrainedHeight="true"
+        app:layout_constraintTop_toTopOf="parent"
+        app:tools_page_indicator_margin_bottom="?android:attr/actionBarSize"
         app:tools_slider_bar_icon="@drawable/tools_ic_pdf_slider_bar"
-        app:layout_constraintTop_toBottomOf="@id/pdf_tool_bar"
-        app:layout_constraintBottom_toTopOf="@id/annotation_tool_bar"/>
+        app:layout_constraintBottom_toBottomOf="parent"/>
 
 
     <com.compdfkit.tools.common.views.pdfannotationbar.CAnnotationToolbar

+ 1 - 1
annotation-ctrl-demo/src/main/res/values-night/themes.xml

@@ -1,6 +1,6 @@
 <resources>
     <!-- Base application theme. -->
-    <style name="Theme.Compdfkit_android_demo" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
+    <style name="Annotation_Basic_Theme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
         <item name="colorPrimary">@color/md_theme_dark_primary</item>
         <item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item>
         <item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item>

+ 1 - 1
annotation-ctrl-demo/src/main/res/values/themes.xml

@@ -1,6 +1,6 @@
 <resources>
     <!-- Base application theme. -->
-    <style name="Theme.Compdfkit_android_demo" parent="Theme.MaterialComponents.DayNight.NoActionBar">
+    <style name="Annotation_Basic_Theme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
         <item name="colorPrimary">@color/md_theme_light_primary</item>
         <item name="colorOnPrimary">@color/md_theme_light_onPrimary</item>
         <item name="colorPrimaryContainer">@color/md_theme_light_primaryContainer</item>

+ 3 - 3
compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfannotationlist/CPDFAnnotationListFragment.java

@@ -24,7 +24,7 @@ import com.compdfkit.tools.R;
 import com.compdfkit.tools.annotation.pdfannotationlist.adapter.CPDFAnnotListAdapter;
 import com.compdfkit.tools.annotation.pdfannotationlist.bean.CPDFAnnotListItem;
 import com.compdfkit.tools.annotation.pdfannotationlist.data.CPDFAnnotDatas;
-import com.compdfkit.tools.common.interfaces.OnSetPDFDisplayPageIndexListener;
+import com.compdfkit.tools.common.interfaces.COnSetPDFDisplayPageIndexListener;
 import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
 
 
@@ -34,7 +34,7 @@ public class CPDFAnnotationListFragment  extends Fragment {
 
     private CPDFViewCtrl pdfView;
 
-    private OnSetPDFDisplayPageIndexListener displayPageIndexListener;
+    private COnSetPDFDisplayPageIndexListener displayPageIndexListener;
 
     public static CPDFAnnotationListFragment newInstance() {
         return new CPDFAnnotationListFragment();
@@ -69,7 +69,7 @@ public class CPDFAnnotationListFragment  extends Fragment {
         rvAnnotation.setAdapter(listAdapter);
     }
 
-    public void setPDFDisplayPageIndexListener(OnSetPDFDisplayPageIndexListener displayPageIndexListener) {
+    public void setPDFDisplayPageIndexListener(COnSetPDFDisplayPageIndexListener displayPageIndexListener) {
         this.displayPageIndexListener = displayPageIndexListener;
     }
 

+ 63 - 12
compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/CAnnotStyleDialogFragment.java

@@ -1,40 +1,67 @@
 package com.compdfkit.tools.annotation.pdfproperties;
 
+import android.animation.ObjectAnimator;
 import android.os.Bundle;
+import android.util.Log;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.animation.LinearInterpolator;
+import android.widget.TextSwitcher;
+import android.widget.TextView;
+import android.widget.ViewSwitcher;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatImageView;
+import androidx.appcompat.widget.AppCompatTextView;
+import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.fragment.app.Fragment;
+import androidx.interpolator.view.animation.FastOutLinearInInterpolator;
+import androidx.lifecycle.ViewModelProvider;
 import androidx.viewpager2.widget.ViewPager2;
 
 import com.compdfkit.tools.R;
 import com.compdfkit.tools.annotation.pdfproperties.pdfannotstyle.adapter.CAnnotPropertiesFragmentAdapter;
+import com.compdfkit.tools.annotation.pdfproperties.pdfannotstyle.adapter.CWrapHeightPageChangeCallback;
+import com.compdfkit.tools.annotation.pdfproperties.pdfannotstyle.viewmodel.CAnnotStyleViewModel;
 import com.compdfkit.tools.annotation.pdfproperties.pdfattr.CAnnotStyle;
+import com.compdfkit.tools.common.utils.dialog.CDialogFragmentUtil;
+import com.compdfkit.tools.common.utils.transformer.CascadeTransformer;
+import com.compdfkit.tools.common.utils.viewutils.CViewUtils;
 import com.compdfkit.tools.common.views.CToolBar;
+import com.compdfkit.tools.common.views.pdfproperties.basic.CBasicPropertiesFragment;
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
 import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
 
 import java.util.ArrayList;
 import java.util.List;
 
 
-public class CAnnotStyleDialogFragment extends BottomSheetDialogFragment {
+public class CAnnotStyleDialogFragment extends BottomSheetDialogFragment implements CBasicPropertiesFragment.OnSwitchFragmentListener {
 
 
-    private CToolBar toolBar;
+    private AppCompatImageView ivPreviousFragment;
+
+    private AppCompatImageView ivClose;
+
+    private AppCompatTextView tvTitle;
 
     private ViewPager2 viewPager;
 
     private CAnnotStyle style;
 
-    public static CAnnotStyleDialogFragment newInstance(CAnnotStyle style){
+    private CAnnotStyleViewModel viewModel;
+
+    public static CAnnotStyleDialogFragment newInstance(CAnnotStyle style) {
         CAnnotStyleDialogFragment dialogFragment = new CAnnotStyleDialogFragment();
         dialogFragment.setStyle(style);
         return dialogFragment;
     }
 
-    public void setStyle(CAnnotStyle style){
+    public void setStyle(CAnnotStyle style) {
         this.style = style;
     }
 
@@ -42,35 +69,50 @@ public class CAnnotStyleDialogFragment extends BottomSheetDialogFragment {
     public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setStyle(STYLE_NORMAL, R.style.Tools_Base_Theme_BottomSheetDialogStyle);
+        viewModel = new ViewModelProvider(getActivity()).get(CAnnotStyleViewModel.class);
+        viewModel.setStyle(style);
     }
 
     @Nullable
     @Override
     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
         View rootView = inflater.inflate(R.layout.tools_annot_style_dialog_fragment, container, false);
-        toolBar = rootView.findViewById(R.id.tool_bar);
+        ivPreviousFragment = rootView.findViewById(R.id.iv_tool_bar_previous);
+        ivClose = rootView.findViewById(R.id.iv_tool_bar_close);
+        tvTitle = rootView.findViewById(R.id.tv_tool_bar_title);
         viewPager = rootView.findViewById(R.id.view_pager);
         return rootView;
     }
 
-
     @Override
     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
-        if (style != null) {
-            toolBar.setTitle(style.getAnnotTypeTitle(getContext()));
-        }
-        toolBar.setOnClickListener(v -> {
+        ivClose.setOnClickListener(v -> {
             dismiss();
         });
+        ivPreviousFragment.setOnClickListener(v -> {
+            previousFragment();
+        });
         initViewPager();
     }
 
-    private void initViewPager(){
-        if (style != null){
+    private void initViewPager() {
+        if (style != null) {
             CAnnotPropertiesFragmentAdapter adapter = new CAnnotPropertiesFragmentAdapter(style, getChildFragmentManager(), getLifecycle());
+            adapter.setSwitchFragmentListener(this);
             viewPager.setAdapter(adapter);
             viewPager.setUserInputEnabled(false);
+            viewPager.setOffscreenPageLimit(2);
+            viewPager.registerOnPageChangeCallback(new CWrapHeightPageChangeCallback(viewPager, getChildFragmentManager()));
+            viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
+                @Override
+                public void onPageSelected(int position) {
+                    super.onPageSelected(position);
+                    ivPreviousFragment.setVisibility(position != 0 ? View.VISIBLE : View.GONE);
+                    ivClose.setVisibility(position == 0 ? View.VISIBLE : View.GONE);
+                    tvTitle.setText(getString(adapter.getTitleByIndex(position)));
+                }
+            });
         }
     }
 
@@ -80,4 +122,13 @@ public class CAnnotStyleDialogFragment extends BottomSheetDialogFragment {
         super.onSaveInstanceState(outState);
     }
 
+    @Override
+    public void nextFragment() {
+        viewPager.setCurrentItem(1);
+    }
+
+    @Override
+    public void previousFragment() {
+        viewPager.setCurrentItem(0);
+    }
 }

+ 16 - 4
compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfannotstyle/adapter/CAnnotPropertiesFragmentAdapter.java

@@ -6,7 +6,7 @@ import androidx.fragment.app.FragmentManager;
 import androidx.lifecycle.Lifecycle;
 import androidx.viewpager2.adapter.FragmentStateAdapter;
 
-import com.compdfkit.tools.annotation.pdfproperties.pdfannotstyle.data.CPropertiesFragmentFactory;
+import com.compdfkit.tools.annotation.pdfproperties.pdfannotstyle.data.CPropertiesFragmentDatas;
 import com.compdfkit.tools.annotation.pdfproperties.pdfattr.CAnnotStyle;
 import com.compdfkit.tools.common.views.pdfproperties.basic.CBasicPropertiesFragment;
 
@@ -18,22 +18,34 @@ public class CAnnotPropertiesFragmentAdapter  extends FragmentStateAdapter {
 
     private CAnnotStyle style;
 
-    private List<Class<? extends CBasicPropertiesFragment>> propertiesClass = new ArrayList<>();
+    private List<CPropertiesFragmentDatas.CPropertiesFragmentBean> propertiesClass = new ArrayList<>();
+
+    private CBasicPropertiesFragment.OnSwitchFragmentListener listener;
 
     public CAnnotPropertiesFragmentAdapter(CAnnotStyle style, @NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
         super(fragmentManager, lifecycle);
         this.style = style;
-        propertiesClass = CPropertiesFragmentFactory.getPropertiesFragmentClass(style);
+        propertiesClass = CPropertiesFragmentDatas.getPropertiesFragmentClass(style);
     }
 
     @NonNull
     @Override
     public Fragment createFragment(int position) {
-        return CPropertiesFragmentFactory.createPropertiesFragment(propertiesClass.get(position), style);
+        CBasicPropertiesFragment fragment = CPropertiesFragmentDatas.createPropertiesFragment(propertiesClass.get(position).getFragmentClass(), style);
+        fragment.setSwitchFragmentListener(listener);
+        return fragment;
     }
 
     @Override
     public int getItemCount() {
         return propertiesClass.size();
     }
+
+    public int getTitleByIndex(int index){
+        return propertiesClass.get(index).getTitleResId();
+    }
+
+    public void setSwitchFragmentListener(CBasicPropertiesFragment.OnSwitchFragmentListener listener) {
+        this.listener = listener;
+    }
 }

+ 99 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfannotstyle/adapter/CWrapHeightPageChangeCallback.java

@@ -0,0 +1,99 @@
+/**
+ * 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.
+ */
+
+package com.compdfkit.tools.annotation.pdfproperties.pdfannotstyle.adapter;
+
+import android.animation.ObjectAnimator;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.LinearInterpolator;
+
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.viewpager2.widget.ViewPager2;
+
+
+public class CWrapHeightPageChangeCallback extends ViewPager2.OnPageChangeCallback {
+
+    private FragmentManager fragmentManager;
+
+    private ViewPager2 viewPager2;
+
+    public CWrapHeightPageChangeCallback(ViewPager2 viewPager2, FragmentManager childFragmentManager){
+        this.fragmentManager = childFragmentManager;
+        this.viewPager2 = viewPager2;
+        viewPager2.setOffscreenPageLimit(2);
+    }
+
+    @Override
+    public void onPageSelected(int position) {
+        super.onPageSelected(position);
+        if (fragmentManager != null) {
+            Fragment myFragment = fragmentManager.findFragmentByTag("f" + position);
+            if (myFragment != null && myFragment.getView() != null) {
+                updatePagerHeightForChild(myFragment.getView());
+            }
+        }
+    }
+
+    private void updatePagerHeightForChild(View view) {
+        view.post(() -> {
+            int wMeasureSpec =
+                    View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY);
+            int hMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
+            view.measure(wMeasureSpec, hMeasureSpec);
+            int hei = view.getMeasuredHeight();
+            int he = viewPager2.getLayoutParams().height;
+            if (he != hei) {
+                if (he > 0 && hei > 0) {
+                    requestHeightAnimation(viewPager2, he, hei);
+                }else {
+                    ViewGroup.LayoutParams layoutParams = viewPager2.getLayoutParams();
+                    layoutParams.height = view.getMeasuredHeight();
+                    viewPager2.setLayoutParams(layoutParams);
+                }
+            }
+        });
+    }
+
+    private void requestHeightAnimation(View view, int startHeight, int endHeight) {
+        ViewWrapper viewWrapper = new ViewWrapper(view);
+        ObjectAnimator objectAnimator = ObjectAnimator.ofInt(viewWrapper, "height", startHeight, endHeight);
+        objectAnimator.setDuration(200);
+        objectAnimator.setInterpolator(new LinearInterpolator());
+        objectAnimator.start();
+    }
+
+    private static class ViewWrapper {
+
+        private View rView;
+
+        public ViewWrapper(View target) {
+            rView = target;
+        }
+
+        public int getWidth() {
+            return rView.getLayoutParams().width;
+        }
+
+        public void setWidth(int width) {
+            rView.getLayoutParams().width = width;
+            rView.requestLayout();
+        }
+
+        public int getHeight() {
+            return rView.getLayoutParams().height;
+        }
+
+        public void setHeight(int height) {
+            rView.getLayoutParams().height = height;
+            rView.requestLayout();
+        }
+    }
+}

+ 99 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfannotstyle/data/CPropertiesFragmentDatas.java

@@ -0,0 +1,99 @@
+/**
+ * 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.
+ */
+
+package com.compdfkit.tools.annotation.pdfproperties.pdfannotstyle.data;
+
+import androidx.annotation.StringRes;
+
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.annotation.pdfproperties.pdfattr.CAnnotStyle;
+import com.compdfkit.tools.annotation.pdfproperties.pdfmarkup.CMarkupStyleFragment;
+import com.compdfkit.tools.annotation.pdfproperties.pdfnote.CNoteStyleFragment;
+import com.compdfkit.tools.common.views.pdfproperties.basic.CBasicPropertiesFragment;
+import com.compdfkit.tools.common.views.pdfproperties.colorpicker.CColorPickerFragment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class CPropertiesFragmentDatas {
+
+
+    public static List<CPropertiesFragmentBean> getPropertiesFragmentClass(CAnnotStyle style) {
+        List<CPropertiesFragmentBean> list = new ArrayList<>();
+        switch (style.getType()) {
+            case STRIKEOUT:
+            case HIGHLIGHT:
+            case UNDERLINE:
+            case SQUIGGLY:
+                list.addAll(markupFragments(style));
+                break;
+            case TEXT:
+                list.addAll(noteFragments(style));
+                break;
+            default:
+               break;
+        }
+        return list;
+    }
+
+    public static <T extends CBasicPropertiesFragment> CBasicPropertiesFragment createPropertiesFragment(Class<T> tClass, CAnnotStyle style){
+        try{
+            return tClass.getDeclaredConstructor().newInstance();
+        }catch (Exception e){
+            return null;
+        }
+    }
+
+
+    private static List<CPropertiesFragmentBean> markupFragments(CAnnotStyle style) {
+        List<CPropertiesFragmentBean> list = new ArrayList<>();
+        list.add(new CPropertiesFragmentBean(style.getAnnotTypeTitleResId(), CMarkupStyleFragment.class));
+        list.add(new CPropertiesFragmentBean(R.string.tools_custom_color, CColorPickerFragment.class));
+        return list;
+    }
+
+    private static List<CPropertiesFragmentBean> noteFragments(CAnnotStyle style){
+        List<CPropertiesFragmentBean> list = new ArrayList<>();
+        list.add(new CPropertiesFragmentBean(style.getAnnotTypeTitleResId(), CNoteStyleFragment.class));
+        list.add(new CPropertiesFragmentBean(R.string.tools_custom_color, CColorPickerFragment.class));
+        return list;
+    }
+
+
+    public static class CPropertiesFragmentBean{
+
+        private Class<? extends CBasicPropertiesFragment> fragmentClass;
+
+        private int titleResId;
+
+        public CPropertiesFragmentBean(@StringRes int titleRes, Class<? extends  CBasicPropertiesFragment> fragmentClass){
+            this.titleResId = titleRes;
+            this.fragmentClass = fragmentClass;
+        }
+
+
+        public Class<? extends CBasicPropertiesFragment> getFragmentClass() {
+            return fragmentClass;
+        }
+
+        public void setFragmentClass(Class<? extends CBasicPropertiesFragment> claz) {
+            this.fragmentClass = claz;
+        }
+
+        public int getTitleResId() {
+            return titleResId;
+        }
+
+        public void setTitleResId(int titleResId) {
+            this.titleResId = titleResId;
+        }
+    }
+
+}

+ 0 - 55
compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfannotstyle/data/CPropertiesFragmentFactory.java

@@ -1,55 +0,0 @@
-/**
- * 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.
- */
-
-package com.compdfkit.tools.annotation.pdfproperties.pdfannotstyle.data;
-
-import com.compdfkit.tools.annotation.pdfproperties.pdfattr.CAnnotStyle;
-import com.compdfkit.tools.annotation.pdfproperties.pdfmarkup.CMarkupStyleFragment;
-import com.compdfkit.tools.common.views.pdfproperties.basic.CBasicPropertiesFragment;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-public class CPropertiesFragmentFactory {
-
-
-    public static List<Class<? extends CBasicPropertiesFragment>> getPropertiesFragmentClass(CAnnotStyle style) {
-        List<Class<? extends CBasicPropertiesFragment>> list = new ArrayList<>();
-        switch (style.getType()) {
-            case STRIKEOUT:
-            case HIGHLIGHT:
-            case UNDERLINE:
-            case SQUIGGLY:
-                list.addAll(markupFragments());
-                break;
-            default:
-               break;
-        }
-        return list;
-    }
-
-    public static <T extends CBasicPropertiesFragment> CBasicPropertiesFragment createPropertiesFragment(Class<T> tClass, CAnnotStyle style){
-        try{
-            CBasicPropertiesFragment fragment = tClass.getDeclaredConstructor().newInstance();
-            fragment.setStyle(style);
-            return fragment;
-        }catch (Exception e){
-            return null;
-        }
-    }
-
-
-    private static List<Class<? extends CBasicPropertiesFragment>> markupFragments() {
-        List<Class<? extends CBasicPropertiesFragment>> list = new ArrayList<>();
-        list.add(CMarkupStyleFragment.class);
-        return list;
-    }
-
-}

+ 42 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfannotstyle/viewmodel/CAnnotStyleViewModel.java

@@ -0,0 +1,42 @@
+package com.compdfkit.tools.annotation.pdfproperties.pdfannotstyle.viewmodel;
+
+import android.graphics.Color;
+
+import androidx.annotation.ColorInt;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+
+import com.compdfkit.tools.annotation.pdfproperties.pdfattr.CAnnotStyle;
+
+
+public class CAnnotStyleViewModel extends ViewModel {
+
+    public MutableLiveData<CAnnotStyle> liveData = new MutableLiveData<>();
+
+    public void setStyle(CAnnotStyle style) {
+        this.liveData.setValue(style);
+    }
+
+    public CAnnotStyle getStyle() {
+        return liveData.getValue();
+    }
+
+    public void setColor(@ColorInt int color) {
+        setColor(color, getStyle() != null ? getStyle().getColorAlpha() : 255);
+    }
+
+    public void setColorAlpha(int colorAlpha) {
+        setColor(getStyle() != null ? getStyle().getColor() : Color.WHITE, colorAlpha );
+    }
+
+    public void setColor(@ColorInt int color, int colorAlpha) {
+        CAnnotStyle style = liveData.getValue();
+        if (style != null) {
+            style.setColor(color);
+            style.setColorAlpha(colorAlpha);
+            liveData.setValue(style);
+        }
+    }
+
+}

+ 21 - 17
compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfattr/CAnnotStyle.java

@@ -11,6 +11,7 @@ package com.compdfkit.tools.annotation.pdfproperties.pdfattr;
 
 
 import android.content.Context;
+import android.graphics.Color;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -26,23 +27,23 @@ import com.compdfkit.core.annotation.CPDFTextAttribute;
 import com.compdfkit.tools.R;
 import com.compdfkit.tools.common.views.pdfannotationbar.bean.CAnnotationType;
 
-public class CAnnotStyle implements Parcelable {
+public class CAnnotStyle implements Parcelable ,Cloneable{
 
     private CAnnotationType type;
 
-    private int color;
+    private int color = Color.BLACK;
 
-    private int colorAlpha;
+    private int colorAlpha = 255;
 
     private float borderWidth;
 
-    private int lineColor;
+    private int lineColor = Color.BLACK;
 
-    private int lineColorAlpha;
+    private int lineColorAlpha = 255;
 
-    private int fillColor;
+    private int fillColor = Color.BLACK;
 
-    private int fillAlpha;
+    private int fillAlpha = 255;
 
     private CPDFLineAnnotation.LineType startLineType;
 
@@ -52,9 +53,9 @@ public class CAnnotStyle implements Parcelable {
 
     private boolean fontItalic;
 
-    private int textColor;
+    private int textColor = Color.BLACK;
 
-    private int textColorAlpha;
+    private int textColorAlpha = 255;
 
     private int fontSize;
 
@@ -312,26 +313,29 @@ public class CAnnotStyle implements Parcelable {
         this.textStampColor = textStampColor;
     }
 
-    public String getAnnotTypeTitle(Context context) {
-        String title = "";
+    public int getAnnotTypeTitleResId() {
+        int titleResId = 0;
         switch (type) {
+            case TEXT:
+                titleResId = R.string.tools_annot_note;
+                break;
             case HIGHLIGHT:
-                title = context.getString(R.string.tools_annot_highlight);
+                titleResId = R.string.tools_annot_highlight;
                 break;
             case STRIKEOUT:
-                title = context.getString(R.string.tools_annot_strikeout);
+                titleResId = R.string.tools_annot_strikeout;
                 break;
 
             case UNDERLINE:
-                title = context.getString(R.string.tools_annot_underline);
+                titleResId = R.string.tools_annot_underline;
                 break;
             case SQUIGGLY:
-                title = context.getString(R.string.tools_annot_squiggly);
+                titleResId = R.string.tools_annot_squiggly;
                 break;
             default:
-                title = "Not impt...";
+                titleResId = R.string.tools_menu_pdfview;
                 break;
         }
-        return title;
+        return titleResId;
     }
 }

+ 1 - 3
compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfmarkup/CLinkStyleFragment.java

@@ -25,9 +25,7 @@ public class CLinkStyleFragment extends CBasicPropertiesFragment {
 
 
     public static CLinkStyleFragment newInstance(CAnnotStyle style) {
-        CLinkStyleFragment fragment = new CLinkStyleFragment();
-        fragment.setStyle(style);
-        return fragment;
+        return new CLinkStyleFragment();
     }
 
     @Nullable

+ 31 - 4
compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfmarkup/CMarkupStyleFragment.java

@@ -11,35 +11,62 @@ package com.compdfkit.tools.annotation.pdfproperties.pdfmarkup;
 
 
 import android.os.Bundle;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.lifecycle.ViewModel;
+import androidx.lifecycle.ViewModelProvider;
 
 import com.compdfkit.tools.R;
+import com.compdfkit.tools.annotation.pdfproperties.pdfannotstyle.viewmodel.CAnnotStyleViewModel;
 import com.compdfkit.tools.annotation.pdfproperties.pdfattr.CAnnotStyle;
 import com.compdfkit.tools.common.views.pdfproperties.basic.CBasicPropertiesFragment;
+import com.compdfkit.tools.common.views.pdfproperties.colorlist.CColorListView;
+import com.compdfkit.tools.common.views.pdfproperties.sliderbar.CSliderBar;
 
 public class CMarkupStyleFragment extends CBasicPropertiesFragment {
 
+    private CColorListView colorListView;
 
-    public static CMarkupStyleFragment newInstance(CAnnotStyle style) {
-        CMarkupStyleFragment fragment = new CMarkupStyleFragment();
-        fragment.setStyle(style);
-        return fragment;
+    private CSliderBar sliderBar;
+
+    public static CMarkupStyleFragment newInstance() {
+        return new CMarkupStyleFragment();
     }
 
     @Nullable
     @Override
     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
         View rootView = inflater.inflate(R.layout.tools_properties_markup_style_fragment, container, false);
+        colorListView = rootView.findViewById(R.id.color_list_view);
+        sliderBar = rootView.findViewById(R.id.slider_bar);
         return rootView;
     }
 
     @Override
     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
+        colorListView.setColorChangeListener(color -> {
+            viewModel.setColor(color);
+        });
+        sliderBar.setProgress(viewModel.getStyle().getColorAlpha());
+        colorListView.setColorPickerClickListener(this::nextFragment);
+        sliderBar.setChangeListener((progress, percentageValue) ->{
+            viewModel.setColorAlpha(progress);
+        });
+        viewModel.liveData.observe(getViewLifecycleOwner(), style -> {
+            if (style != null && !isOnResume) {
+                if (colorListView != null) {
+                    colorListView.setSelectColor(style.getColor());
+                }
+                if (sliderBar != null) {
+                    sliderBar.setProgress(style.getColorAlpha());
+                }
+            }
+        });
     }
 }

+ 61 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/annotation/pdfproperties/pdfnote/CNoteStyleFragment.java

@@ -0,0 +1,61 @@
+/**
+ * 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.
+ */
+
+package com.compdfkit.tools.annotation.pdfproperties.pdfnote;
+
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.common.views.pdfproperties.basic.CBasicPropertiesFragment;
+import com.compdfkit.tools.common.views.pdfproperties.colorlist.CColorListView;
+import com.compdfkit.tools.common.views.pdfproperties.sliderbar.CSliderBar;
+
+public class CNoteStyleFragment extends CBasicPropertiesFragment {
+
+    private CColorListView colorListView;
+
+    public static CNoteStyleFragment newInstance() {
+        return new CNoteStyleFragment();
+    }
+
+    private View rootView;
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        rootView = inflater.inflate(R.layout.tools_properties_note_style_fragment, container, false);
+        colorListView = rootView.findViewById(R.id.color_list_view);
+        return rootView;
+    }
+
+    @Override
+    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        colorListView.setColorChangeListener(color -> {
+            viewModel.setColor(color);
+        });
+        colorListView.setColorPickerClickListener(this::nextFragment);
+        viewModel.liveData.observe(getViewLifecycleOwner(), style -> {
+            if (style != null && !isOnResume) {
+                if (colorListView != null) {
+                    colorListView.setSelectColor(style.getColor());
+                }
+            }
+        });
+    }
+
+
+}

+ 18 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/interfaces/COnColorChangeListener.java

@@ -0,0 +1,18 @@
+/**
+ * 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.
+ */
+
+package com.compdfkit.tools.common.interfaces;
+
+import androidx.annotation.ColorInt;
+
+public interface COnColorChangeListener {
+
+    void color(@ColorInt int color);
+
+}

+ 1 - 1
compdfkit-tools/src/main/java/com/compdfkit/tools/common/interfaces/OnSetPDFDisplayPageIndexListener.java

@@ -13,7 +13,7 @@ package com.compdfkit.tools.common.interfaces;
 /**
  * Interface for handling the event of setting the display page index of a PDF.
  */
-public interface OnSetPDFDisplayPageIndexListener {
+public interface COnSetPDFDisplayPageIndexListener {
 
     /**
      * Called when the display page index of a PDF is being set.

+ 133 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/utils/animation/CFillScreenManager.java

@@ -17,6 +17,9 @@ import android.view.View;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.LinearInterpolator;
 
+import com.compdfkit.tools.common.views.CPDFToolBar;
+import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -29,6 +32,10 @@ public class CFillScreenManager {
     private List<View> topToolViewList = new ArrayList<>();
     private List<View> bottomToolViewList = new ArrayList<>();
 
+    private List<View> leftToolViewList = new ArrayList<>();
+
+    private List<View> rightToolViewList = new ArrayList<>();
+
     public void showFromTop(View view, long duration) {
         if (view.getVisibility() == android.view.View.VISIBLE) {
             return;
@@ -128,6 +135,106 @@ public class CFillScreenManager {
     }
 
 
+    public void showFromLeft(View view,long duration) {
+        if (view.getVisibility() == View.VISIBLE) {
+            return;
+        }
+
+        if (!view.isHardwareAccelerated()) {
+            view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        }
+        view.setAlpha(0F);
+        view.setVisibility(View.VISIBLE);
+
+        view.animate()
+                .alpha(1f)
+                .translationX(0f)
+                .setInterpolator(new AccelerateInterpolator())
+                .setDuration(duration)
+                .setListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        super.onAnimationEnd(animation);
+                        animation.removeListener(this);
+                        view.setLayerType(View.LAYER_TYPE_NONE, null);
+                        view.clearAnimation();
+                    }
+                });
+    }
+
+    public void hideFromLeft(View view, long duration) {
+        if (view.getVisibility() != View.VISIBLE) {
+            return;
+        }
+        if (!view.isHardwareAccelerated()) {
+            view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        }
+        view.animate()
+                .alpha(0.0f)
+                .translationXBy(-1.0f * view.getWidth())
+                .setInterpolator(new AccelerateInterpolator())
+                .setDuration(duration)
+                .setListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        super.onAnimationEnd(animation);
+                        animation.removeListener(this);
+                        view.setLayerType(View.LAYER_TYPE_NONE, null);
+                        view.clearAnimation();
+                        view.setVisibility(View.GONE);
+                    }
+                });
+    }
+
+    public void showFromRight(View view, long duration) {
+        if (view.getVisibility() == View.VISIBLE) {
+            return;
+        }
+        if (!view.isHardwareAccelerated()) {
+            view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        }
+        view.setAlpha(0F);
+        view.setVisibility(View.VISIBLE);
+
+        view.animate()
+                .alpha(1f)
+                .translationX(0.0f)
+                .setInterpolator(new AccelerateInterpolator())
+                .setDuration(duration)
+                .setListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        super.onAnimationEnd(animation);
+                        animation.removeListener(this);
+                        view.setLayerType(View.LAYER_TYPE_NONE, null);
+                        view.clearAnimation();
+                    }
+                });
+    }
+
+    public void hideFromRight(View view, long duration) {
+        if (view.getVisibility() != View.VISIBLE) {
+            return;
+        }
+        if (!view.isHardwareAccelerated()) {
+            view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        }
+        view.animate()
+                .alpha(0.0f)
+                .translationX((float)view.getWidth())
+                .setInterpolator(new AccelerateInterpolator())
+                .setDuration(duration)
+                .setListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        super.onAnimationEnd(animation);
+                        animation.removeListener(this);
+                        view.setLayerType(View.LAYER_TYPE_NONE, null);
+                        view.clearAnimation();
+                        view.setVisibility(View.INVISIBLE);
+                    }
+                });
+    }
 
     public void bindTopToolView(View... topToolView) {
         topToolViewList.addAll(Arrays.asList(topToolView));
@@ -137,6 +244,13 @@ public class CFillScreenManager {
         bottomToolViewList.addAll(Arrays.asList(bottomToolView));
     }
 
+    public void bindLeftToolViewList(View... leftToolView) {
+        leftToolViewList.addAll(Arrays.asList(leftToolView));
+    }
+
+    public void bindRightToolViewList(View... rightToolView) {
+        rightToolViewList.addAll(Arrays.asList(rightToolView));
+    }
 
     public void fillScreenChange(boolean fillScreen) {
         if (fillScreen) {
@@ -146,6 +260,12 @@ public class CFillScreenManager {
             for (View view : bottomToolViewList) {
                 hideFromBottom(view, CONFIG_SHORT_ANIM_TIME);
             }
+            for (View view : leftToolViewList) {
+                hideFromLeft(view, CONFIG_SHORT_ANIM_TIME);
+            }
+            for (View view : rightToolViewList) {
+                hideFromRight(view, CONFIG_SHORT_ANIM_TIME);
+            }
         } else {
             for (View view : topToolViewList) {
                 showFromTop(view, CONFIG_SHORT_ANIM_TIME);
@@ -153,6 +273,19 @@ public class CFillScreenManager {
             for (View view : bottomToolViewList) {
                 showFromBottom(view, CONFIG_SHORT_ANIM_TIME);
             }
+            for (View view : leftToolViewList) {
+                showFromLeft(view, CONFIG_SHORT_ANIM_TIME);
+            }
+            for (View view : rightToolViewList) {
+                showFromRight(view, CONFIG_SHORT_ANIM_TIME);
+            }
         }
     }
+
+    public void removeToolView(View view){
+        topToolViewList.remove(view);
+        bottomToolViewList.remove(view);
+        leftToolViewList.remove(view);
+        rightToolViewList.remove(view);
+    }
 }

+ 6 - 6
compdfkit-tools/src/main/java/com/compdfkit/tools/common/utils/dialog/CGotoPageDialog.java

@@ -14,9 +14,9 @@ import android.text.InputType;
 import android.text.TextUtils;
 
 import com.compdfkit.tools.R;
-import com.compdfkit.tools.common.interfaces.OnSetPDFDisplayPageIndexListener;
+import com.compdfkit.tools.common.interfaces.COnSetPDFDisplayPageIndexListener;
 public class CGotoPageDialog extends CCommonInputDialog {
-    private OnSetPDFDisplayPageIndexListener onSetPDFDisplayPageIndexListener;
+    private COnSetPDFDisplayPageIndexListener COnSetPDFDisplayPageIndexListener;
 
     public CGotoPageDialog(Context context) {
         super(context);
@@ -33,8 +33,8 @@ public class CGotoPageDialog extends CCommonInputDialog {
         initDialogView();
     }
 
-    public void setOnSetPDFDisplayPageIndexListener(OnSetPDFDisplayPageIndexListener onSetPDFDisplayPageIndexListener) {
-        this.onSetPDFDisplayPageIndexListener = onSetPDFDisplayPageIndexListener;
+    public void setOnSetPDFDisplayPageIndexListener(COnSetPDFDisplayPageIndexListener COnSetPDFDisplayPageIndexListener) {
+        this.COnSetPDFDisplayPageIndexListener = COnSetPDFDisplayPageIndexListener;
     }
 
     private void initDialogView() {
@@ -42,12 +42,12 @@ public class CGotoPageDialog extends CCommonInputDialog {
         setMessage(getContext().getResources().getText(R.string.tools_goto_page_dialog_msg).toString());
         setInputType(InputType.TYPE_CLASS_NUMBER);
         setConfirmCallback(getContext().getResources().getText(R.string.tools_common_okay).toString(), text -> {
-            if (null != onSetPDFDisplayPageIndexListener && (!TextUtils.isEmpty(text))) {
+            if (null != COnSetPDFDisplayPageIndexListener && (!TextUtils.isEmpty(text))) {
                int page;
                try {
                    page = Integer.parseInt(text);
                    if (page >= 0) {
-                       onSetPDFDisplayPageIndexListener.displayPage(page);
+                       COnSetPDFDisplayPageIndexListener.displayPage(page);
                    }
                } catch (NumberFormatException e) {
                     e.printStackTrace();

+ 36 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/utils/transformer/CascadeTransformer.java

@@ -0,0 +1,36 @@
+package com.compdfkit.tools.common.utils.transformer;
+
+import android.view.View;
+
+import androidx.viewpager2.widget.ViewPager2;
+
+public class CascadeTransformer implements ViewPager2.PageTransformer {
+
+    private static final float MIN_SCALE = 0.95f;
+
+    @Override
+    public void transformPage(View page, float position) {
+        page.animate().cancel();
+
+        if (position < -1) {
+            page.setAlpha(0f);
+            page.setScaleX(1.0f);
+            page.setScaleY(1.0f);
+        } else if (position <= 0) {
+            page.setAlpha(1f);
+            page.setTranslationZ(0f);
+            page.setTranslationX(0f);
+            page.setScaleX(1.0f);
+            page.setScaleY(1.0f);
+        } else if (position <= 1) {
+            page.setAlpha(1 - position);
+            page.setTranslationX(-position * page.getWidth());
+            float scale = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
+            page.setScaleX(scale);
+            page.setScaleY(scale);
+            page.setTranslationZ(-position);
+        } else {
+            page.setAlpha(0f);
+        }
+    }
+}

+ 12 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/utils/viewutils/CViewUtils.java

@@ -14,6 +14,7 @@ import android.app.Dialog;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
+import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.util.TypedValue;
@@ -23,6 +24,7 @@ import android.widget.EditText;
 
 import androidx.annotation.Nullable;
 import androidx.appcompat.content.res.AppCompatResources;
+import androidx.core.content.ContextCompat;
 import androidx.core.view.ViewCompat;
 
 import com.google.android.material.shape.MaterialShapeDrawable;
@@ -52,6 +54,16 @@ public class CViewUtils {
         }
     }
 
+    public static int getAttrColor(Context context, int resId){
+        TypedValue tv = new TypedValue();
+        if (context.getTheme().resolveAttribute(resId, tv, true)) {
+            int colorRes = tv.resourceId;
+            return ContextCompat.getColor(context, colorRes);
+        }else {
+            return Color.WHITE;
+        }
+    }
+
     public static void applyViewBackground(View view) {
         int color;
         if (view.getBackground() != null && view.getBackground() instanceof ColorDrawable) {

+ 144 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/utils/window/CPDFToolbarPopupMenu.java

@@ -0,0 +1,144 @@
+package com.compdfkit.tools.common.utils.window;
+
+
+import android.content.Context;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+
+import androidx.appcompat.widget.PopupMenu;
+
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.common.views.CPDFToolBar;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CPDFToolbarPopupMenu implements PopupMenu.OnMenuItemClickListener {
+
+    public enum PreviewMode {
+        PDFView,
+        Annotation,
+        Form,
+        Edit,
+        PageEdit
+    }
+
+    private List<PreviewMode> previewModes = new ArrayList<>();
+
+    private int samplePDFViewMenuId = View.generateViewId();
+
+    private int annotViewMenuId = View.generateViewId();
+
+    private int editMenuId = View.generateViewId();
+
+    private int pageEditMenuId = View.generateViewId();
+
+    private int formMenuId = View.generateViewId();
+
+    private PreviewMode currentPreviewMode = PreviewMode.PDFView;
+
+    private OnPreviewModeChangeListener changeListener;
+
+    private PopupMenu popupMenu;
+
+    private Context context;
+
+    public CPDFToolbarPopupMenu(Context context,View anchor ){
+        this.context = context;
+        popupMenu = new PopupMenu(context,anchor );
+        popupMenu.setOnMenuItemClickListener(this);
+        addMode(currentPreviewMode);
+    }
+
+    public void addMode(PreviewMode mode){
+        previewModes.add(mode);
+        modifyPopupMenuStatus();
+        changeMode(mode);
+    }
+
+    public int getMenuCount(){
+        return previewModes.size();
+    }
+
+    public PreviewMode getMode(){
+        return currentPreviewMode;
+    }
+
+    private void modifyPopupMenuStatus() {
+        popupMenu.getMenu().clear();
+        for (int i = 0; i < previewModes.size(); i++) {
+            PreviewMode type = previewModes.get(i);
+            int menuId;
+            switch (type) {
+                case Edit:
+                    menuId = editMenuId;
+                    break;
+                case Form:
+                    menuId = formMenuId;
+                    break;
+                case PageEdit:
+                    menuId = pageEditMenuId;
+                    break;
+                case Annotation:
+                    menuId = annotViewMenuId;
+                    break;
+                default:
+                    menuId = samplePDFViewMenuId;
+                    break;
+            }
+            popupMenu.getMenu().add(Menu.NONE, menuId, i, getTitleByMode(type));
+        }
+    }
+
+    public String getTitleByMode(PreviewMode mode){
+        switch (mode){
+            case Annotation:
+                return context.getString(R.string.tools_menu_annotation);
+            case Edit:
+                return context.getString(R.string.tools_menu_edit);
+            case PageEdit:
+                return context.getString(R.string.tools_menu_page_edit);
+            case Form:
+                return context.getString(R.string.tools_menu_form);
+            default:
+                return context.getString(R.string.tools_menu_pdfview);
+        }
+    }
+
+    public void show() {
+        if (popupMenu != null) {
+            popupMenu.show();
+        }
+    }
+    @Override
+    public boolean onMenuItemClick(MenuItem item) {
+        if (item.getItemId() == samplePDFViewMenuId) {
+            changeMode(CPDFToolbarPopupMenu.PreviewMode.PDFView);
+        } else if (item.getItemId() == annotViewMenuId) {
+            changeMode(PreviewMode.Annotation);
+        } else if (item.getItemId() == editMenuId) {
+            changeMode(PreviewMode.Edit);
+        } else if (item.getItemId() == pageEditMenuId) {
+            changeMode(PreviewMode.PageEdit);
+        } else if (item.getItemId() == formMenuId) {
+            changeMode(PreviewMode.Form);
+        }
+        return false;
+    }
+
+    private void changeMode(PreviewMode mode) {
+        currentPreviewMode = mode;
+        if (changeListener != null) {
+            changeListener.change(currentPreviewMode, getTitleByMode(currentPreviewMode));
+        }
+    }
+
+    public void setMenuChangeListener(OnPreviewModeChangeListener changeListener) {
+        this.changeListener = changeListener;
+    }
+
+    public interface OnPreviewModeChangeListener {
+        void change(PreviewMode mode, String title);
+    }
+}

+ 57 - 96
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/CPDFToolBar.java

@@ -22,6 +22,7 @@ import android.view.MenuItem;
 import android.view.View;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
+import android.widget.PopupWindow;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -29,9 +30,14 @@ import androidx.appcompat.widget.AppCompatImageView;
 import androidx.appcompat.widget.AppCompatTextView;
 import androidx.appcompat.widget.PopupMenu;
 import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.core.widget.PopupMenuCompat;
+import androidx.core.widget.PopupWindowCompat;
 
 import com.compdfkit.tools.R;
 import com.compdfkit.tools.common.utils.viewutils.CViewUtils;
+import com.compdfkit.tools.common.utils.window.CPDFToolbarPopupMenu;
+import com.compdfkit.tools.viewer.pdfdisplaysettings.CPDFDisplaySettingDialogFragment;
+import com.compdfkit.tools.viewer.pdfinfo.CPDFDocumentInfoDialogFragment;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -69,21 +75,8 @@ import java.util.List;
  * <p>
  * botaBtnClick:
  * @see CPDFToolBar#setBoTaBtnClickListener(OnClickListener)
- * <p>
- * moreBtnClick:
- * @see CPDFToolBar#setMoreBtnClickListener(OnClickListener)
  */
-public class CPDFToolBar extends FrameLayout implements PopupMenu.OnMenuItemClickListener {
-
-
-
-    enum PreviewMode {
-        PDFView,
-        Annotation,
-        Form,
-        Edit,
-        PageEdit
-    }
+public class CPDFToolBar extends FrameLayout implements CPDFToolbarPopupMenu.OnPreviewModeChangeListener {
 
     private AppCompatTextView tvToolBarTitle;
 
@@ -101,18 +94,11 @@ public class CPDFToolBar extends FrameLayout implements PopupMenu.OnMenuItemClic
 
     private LinearLayout llTitle;
 
-    private PopupMenu popupMenu;
+    private CPDFToolbarPopupMenu popupMenu;
 
-    private List<PreviewMode> previewModes = new ArrayList<>();
-    private int samplePDFViewMenuId = View.generateViewId();
-    private int annotViewMenuId = View.generateViewId();
-    private int editMenuId = View.generateViewId();
-    private int pageEditMenuId = View.generateViewId();
-    private int formMenuId = View.generateViewId();
+    private OnMoreMenuListener moreMenuListener;
 
-    private PreviewMode currentPreviewMode = PreviewMode.PDFView;
-
-    private OnPreviewModeChangeListener changeListener;
+    private CPDFToolbarPopupMenu.OnPreviewModeChangeListener changeListener;
 
     public CPDFToolBar(@NonNull Context context) {
         this(context, null);
@@ -137,11 +123,26 @@ public class CPDFToolBar extends FrameLayout implements PopupMenu.OnMenuItemClic
         ivToolBarThumbnail = findViewById(R.id.iv_tool_bar_thumbnail);
         llTitle = findViewById(R.id.ll_title);
         ivTitleArrow = findViewById(R.id.iv_down_arrow);
-        popupMenu = new PopupMenu(getContext(), llTitle, Gravity.CENTER);
-        modifyPopupMenuStatus();
-        llTitle.setOnClickListener(v -> {
-            PopupMenu popupMenu = new PopupMenu(getContext(), llTitle, Gravity.CENTER);
-
+        popupMenu = new CPDFToolbarPopupMenu(getContext(), llTitle);
+        popupMenu.setMenuChangeListener(this);
+        llTitle.setOnClickListener(v -> popupMenu.show());
+        ivToolBarMoreBtn.setOnClickListener(v -> {
+            //Show the PDF settings dixalog fragment
+            PopupMenu popupMenu = new PopupMenu(getContext(), v);
+            popupMenu.inflate(R.menu.tools_more_menu);
+            popupMenu.setOnMenuItemClickListener(item -> {
+                if (item.getItemId() == R.id.menu_id_document_info) {
+                    if (moreMenuListener != null) {
+                        moreMenuListener.menu(MoreMenu.DocumentInfo);
+                    }
+                } else if (item.getItemId() == R.id.menu_id_reader_settings) {
+                    if (moreMenuListener != null) {
+                        moreMenuListener.menu(MoreMenu.Settings);
+                    }
+                }
+                return true;
+            });
+            popupMenu.show();
         });
         initAttributes(context, attrs);
     }
@@ -171,91 +172,51 @@ public class CPDFToolBar extends FrameLayout implements PopupMenu.OnMenuItemClic
         }
     }
 
-    private void modifyPopupMenuStatus(){
-        ivTitleArrow.setVisibility(previewModes.size() <=0 ? GONE : VISIBLE);
-        popupMenu.getMenu().clear();
-        for (int i = 0; i < previewModes.size(); i++) {
-            PreviewMode type = previewModes.get(i);
-            int titleResId;
-            int menuId;
-            switch(type){
-                case Edit:
-                    titleResId = R.string.tools_menu_edit;
-                    menuId = editMenuId;
-                    break;
-                case Form:
-                    titleResId = R.string.tools_menu_form;
-                    menuId = formMenuId;
-                    break;
-                case PageEdit:
-                    titleResId = R.string.tools_menu_page_edit;
-                    menuId = pageEditMenuId;
-                    break;
-                case Annotation:
-                    titleResId = R.string.tools_menu_annotation;
-                    menuId = annotViewMenuId;
-                    break;
-                default:
-                    titleResId = R.string.tools_menu_pdfview;
-                    menuId = samplePDFViewMenuId;
-                    break;
-            }
-            popupMenu.getMenu().add(Menu.NONE, menuId, i, getContext().getString(titleResId));
-        }
+    public void setSearchBtnClickListener(View.OnClickListener clickListener) {
+        ivToolBarSearchBtn.setOnClickListener(clickListener);
     }
 
+    public void setBoTaBtnClickListener(View.OnClickListener clickListener) {
+        ivToolBarBoTaBtn.setOnClickListener(clickListener);
+    }
 
-    @Override
-    public boolean onMenuItemClick(MenuItem item) {
-        if (item.getItemId() == samplePDFViewMenuId){
-
-        } else if (item.getItemId() == annotViewMenuId) {
-
-        } else if (item.getItemId() == editMenuId) {
-
-        } else if (item.getItemId() == pageEditMenuId) {
-
-        } else if (item.getItemId() == formMenuId){
+    public void setThumbnailBtnClickListener(View.OnClickListener clickListener) {
+        ivToolBarThumbnail.setOnClickListener(clickListener);
+    }
 
-        }
-        return false;
+    public void setPreviewModeChangeListener(CPDFToolbarPopupMenu.OnPreviewModeChangeListener changeListener) {
+        this.changeListener = changeListener;
     }
 
-    private void changeMode(PreviewMode mode){
-        currentPreviewMode = mode;
+    @Override
+    public void change(CPDFToolbarPopupMenu.PreviewMode mode, String title) {
+        tvToolBarTitle.setText(title);
         if (changeListener != null) {
-            changeListener.change(currentPreviewMode);
+            changeListener.change(mode, title);
         }
     }
 
-    public void setSearchBtnClickListener(View.OnClickListener clickListener) {
-        ivToolBarSearchBtn.setOnClickListener(clickListener);
+    public void setMoreMenuListener(OnMoreMenuListener moreMenuListener) {
+        this.moreMenuListener = moreMenuListener;
     }
 
-    public void setBoTaBtnClickListener(View.OnClickListener clickListener) {
-        ivToolBarBoTaBtn.setOnClickListener(clickListener);
-    }
-
-    public void setMoreBtnClickListener(View.OnClickListener clickListener) {
-        ivToolBarMoreBtn.setOnClickListener(clickListener);
+    public void addMode(CPDFToolbarPopupMenu.PreviewMode previewMode) {
+        popupMenu.addMode(previewMode);
+        tvToolBarTitle.setText(popupMenu.getTitleByMode(previewMode));
+        ivTitleArrow.setVisibility(popupMenu.getMenuCount() >1 ? VISIBLE : GONE);
     }
 
-    public void setThumbnailBtnClickListener(View.OnClickListener clickListener){
-        ivToolBarThumbnail.setOnClickListener(clickListener);
+    public CPDFToolbarPopupMenu.PreviewMode getMode(){
+        return popupMenu != null ? popupMenu.getMode() : CPDFToolbarPopupMenu.PreviewMode.PDFView;
     }
 
-    public void setPreviewModeChangeListener(OnPreviewModeChangeListener changeListener) {
-        this.changeListener = changeListener;
-    }
+    public enum MoreMenu {
+        DocumentInfo,
 
-    public void addMode(PreviewMode previewMode){
-        previewModes.add(previewMode);
-        modifyPopupMenuStatus();
+        Settings
     }
 
-    public interface OnPreviewModeChangeListener{
-        void change(PreviewMode mode);
+    public interface OnMoreMenuListener {
+        void menu(MoreMenu menu);
     }
-
-
 }

+ 7 - 4
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfannotationbar/CAnnotationToolbar.java

@@ -25,6 +25,7 @@ import com.compdfkit.core.annotation.CPDFAnnotation;
 import com.compdfkit.tools.R;
 import com.compdfkit.tools.common.views.pdfannotationbar.adapter.CPDFAnnotationToolListAdapter;
 import com.compdfkit.tools.common.views.pdfannotationbar.bean.CAnnotToolBean;
+import com.compdfkit.tools.common.views.pdfannotationbar.bean.CAnnotationType;
 import com.compdfkit.tools.common.views.pdfannotationbar.data.CAnnotationToolDatas;
 import com.compdfkit.tools.annotation.pdfproperties.CAnnotStyleDialogFragment;
 import com.compdfkit.tools.annotation.pdfproperties.pdfattr.CAnnotStyle;
@@ -67,13 +68,13 @@ public class CAnnotationToolbar extends FrameLayout {
         ivRedo = findViewById(R.id.iv_annotation_attr_redo);
         toolListAdapter = new CPDFAnnotationToolListAdapter();
         toolListAdapter.setList(CAnnotationToolDatas.getAnnotationList());
-
         rvAnnotationList.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
         rvAnnotationList.setAdapter(toolListAdapter);
         initListener();
     }
 
     private void initListener(){
+        ivSetting.setEnabled(false);
         ivSetting.setOnClickListener(v -> {
             CAnnotStyle style = new CAnnotStyle(toolListAdapter.getCurrentAnnotType());
             CAnnotStyleDialogFragment dialogFragment = CAnnotStyleDialogFragment.newInstance(style);
@@ -94,6 +95,10 @@ public class CAnnotationToolbar extends FrameLayout {
 
     public void initWithPDFView(CPDFViewCtrl pdfView){
         this.pdfView = pdfView;
+        this.pdfView.addOnPDFFocusedTypeChangeListener(type -> {
+            toolListAdapter.selectByType(CAnnotationType.getType(type));
+            ivSetting.setEnabled(toolListAdapter.hasSelectAnnotType());
+        });
     }
 
     public void setFragmentManager(FragmentManager fragmentManager) {
@@ -106,7 +111,7 @@ public class CAnnotationToolbar extends FrameLayout {
             return;
         }
         switch (bean.getType()){
-            case NOTE:
+            case TEXT:
                 pdfView.changeAnnotationType(CPDFAnnotation.Type.TEXT);
                 break;
             case ARROW:
@@ -122,6 +127,4 @@ public class CAnnotationToolbar extends FrameLayout {
                 break;
         }
     }
-
-
 }

+ 22 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfannotationbar/adapter/CPDFAnnotationToolListAdapter.java

@@ -61,6 +61,28 @@ public class CPDFAnnotationToolListAdapter extends CBaseQuickAdapter<CAnnotToolB
         }
     }
 
+    public void selectByType(CAnnotationType type){
+        for (int i = 0; i < list.size(); i++) {
+            CAnnotToolBean item = list.get(i);
+            if (item.getType() == type) {
+                item.setSelect(true);
+            } else {
+                item.setSelect(false);
+            }
+            notifyItemChanged(i, REFRESH_SELECT);
+        }
+    }
+
+    public boolean hasSelectAnnotType(){
+        for (int i = 0; i < list.size(); i++) {
+            CAnnotToolBean item = list.get(i);
+            if (item.isSelect()){
+                return true;
+            }
+        }
+        return false;
+    }
+
     public CAnnotationType getCurrentAnnotType() {
         for (CAnnotToolBean cAnnotToolBean : list) {
             if (cAnnotToolBean.isSelect()){

+ 12 - 2
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfannotationbar/bean/CAnnotationType.java

@@ -10,9 +10,11 @@
 package com.compdfkit.tools.common.views.pdfannotationbar.bean;
 
 
+import com.compdfkit.core.annotation.CPDFAnnotation;
+
 public enum CAnnotationType {
     UNKNOWN,
-    NOTE,
+    TEXT,
     HIGHLIGHT,
     UNDERLINE,
     SQUIGGLY,
@@ -27,6 +29,14 @@ public enum CAnnotationType {
     STAMP,
     PIC,
     LINK,
-    SOUND,
+    SOUND;
+
+    public static CAnnotationType getType(CPDFAnnotation.Type type){
+        try{
+            return CAnnotationType.valueOf(type.name());
+        }catch (Exception e){
+            return CAnnotationType.UNKNOWN;
+        }
+    }
 
 }

+ 1 - 1
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfannotationbar/data/CAnnotationToolDatas.java

@@ -12,7 +12,7 @@ public class CAnnotationToolDatas {
 
     public static List<CAnnotToolBean> getAnnotationList() {
         List<CAnnotToolBean> list = new ArrayList<>();
-        list.add(new CAnnotToolBean(CAnnotationType.NOTE, R.drawable.tools_ic_annotation_note));
+        list.add(new CAnnotToolBean(CAnnotationType.TEXT, R.drawable.tools_ic_annotation_note));
         list.add(new CAnnotToolBean(CAnnotationType.HIGHLIGHT, R.drawable.tools_ic_annotation_highlight));
         list.add(new CAnnotToolBean(CAnnotationType.UNDERLINE, R.drawable.tools_ic_annotation_underline));
         list.add(new CAnnotToolBean(CAnnotationType.STRIKEOUT, R.drawable.tools_ic_annotation_deleteline));

+ 3 - 3
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfbota/adapter/CBotaViewPagerAdapter.java

@@ -17,7 +17,7 @@ import androidx.lifecycle.Lifecycle;
 import androidx.viewpager2.adapter.FragmentStateAdapter;
 
 import com.compdfkit.tools.annotation.pdfannotationlist.CPDFAnnotationListFragment;
-import com.compdfkit.tools.common.interfaces.OnSetPDFDisplayPageIndexListener;
+import com.compdfkit.tools.common.interfaces.COnSetPDFDisplayPageIndexListener;
 import com.compdfkit.tools.common.views.pdfbota.CPDFBOTA;
 import com.compdfkit.tools.common.views.pdfbota.CPDFBotaEmptyFragment;
 import com.compdfkit.tools.common.views.pdfbota.CPDFBotaFragmentTabs;
@@ -46,7 +46,7 @@ public class CBotaViewPagerAdapter extends FragmentStateAdapter {
     /**
      * Listener for setting the display page index of the PDF
      */
-    private OnSetPDFDisplayPageIndexListener pdfDisplayPageIndexListener;
+    private COnSetPDFDisplayPageIndexListener pdfDisplayPageIndexListener;
 
     public CBotaViewPagerAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle, CPDFViewCtrl pdfView, ArrayList<CPDFBotaFragmentTabs> tabs) {
         super(fragmentManager, lifecycle);
@@ -117,7 +117,7 @@ public class CBotaViewPagerAdapter extends FragmentStateAdapter {
      * Method that sets the PDF display page index listener
      * @param displayPageIndexListener
      */
-    public void setPDFDisplayPageIndexListener(OnSetPDFDisplayPageIndexListener displayPageIndexListener) {
+    public void setPDFDisplayPageIndexListener(COnSetPDFDisplayPageIndexListener displayPageIndexListener) {
         this.pdfDisplayPageIndexListener = displayPageIndexListener;
     }
 }

+ 51 - 3
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/basic/CBasicPropertiesFragment.java

@@ -10,18 +10,66 @@
 package com.compdfkit.tools.common.views.pdfproperties.basic;
 
 import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
+import androidx.lifecycle.ViewModelProvider;
 
+import com.compdfkit.tools.annotation.pdfproperties.pdfannotstyle.viewmodel.CAnnotStyleViewModel;
 import com.compdfkit.tools.annotation.pdfproperties.pdfattr.CAnnotStyle;
 
 
 public abstract class CBasicPropertiesFragment extends Fragment {
-    private CAnnotStyle style;
 
-    public void setStyle(CAnnotStyle style) {
-        this.style = style;
+    protected CAnnotStyleViewModel viewModel;
+
+    protected OnSwitchFragmentListener switchFragmentListener;
+
+    protected boolean isOnResume = false;
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        viewModel = new ViewModelProvider(getActivity()).get(CAnnotStyleViewModel.class);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        isOnResume = true;
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        isOnResume = false;
+    }
+
+    public void setSwitchFragmentListener(OnSwitchFragmentListener switchFragmentListener) {
+        this.switchFragmentListener = switchFragmentListener;
+    }
+
+    protected void nextFragment() {
+        if (switchFragmentListener != null) {
+            switchFragmentListener.nextFragment();
+        }
+    }
+
+    protected void previousFragment() {
+        if (switchFragmentListener != null) {
+            switchFragmentListener.previousFragment();
+        }
     }
 
+    public interface OnSwitchFragmentListener {
+
+        void nextFragment();
+
+        void previousFragment();
+    }
 
 }

+ 4 - 1
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorlist/CColorListAdapter.java

@@ -59,6 +59,9 @@ class CColorListAdapter extends CBaseQuickAdapter<CColorItemBean, CBaseQuickView
         for (int i = 0; i < list.size(); i++) {
             CColorItemBean bean = list.get(i);
             if (i == position) {
+                if (bean.isSelect()) {
+                    continue;
+                }
                 bean.setSelect(true);
             } else {
                 bean.setSelect(false);
@@ -67,7 +70,7 @@ class CColorListAdapter extends CBaseQuickAdapter<CColorItemBean, CBaseQuickView
         }
     }
 
-    public void selectByColor(@ColorInt int color){
+    public void selectByColor(@ColorInt int color) {
         for (int i = 0; i < list.size(); i++) {
             CColorItemBean bean = list.get(i);
             if (bean.getColor() == color) {

+ 16 - 8
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorlist/CColorListView.java

@@ -23,6 +23,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.compdfkit.tools.R;
+import com.compdfkit.tools.common.interfaces.COnColorChangeListener;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -39,9 +40,12 @@ public class CColorListView extends LinearLayout {
 
     private int selectColor;
 
-    private OnColorChangeListener colorChangeListener;
     private CColorListAdapter colorListAdapter;
 
+    private COnColorChangeListener colorChangeListener;
+
+    private OnColorPickerClickListener colorPickerClickListener;
+
     private int colorListResId = R.array.tools_annot_markup_colors;
 
     public CColorListView(Context context) {
@@ -85,7 +89,9 @@ public class CColorListView extends LinearLayout {
         colorListAdapter.setOnItemClickListener((adapter, view, position) -> {
             CColorItemBean bean = adapter.list.get(position);
             if (bean.isColorPicker()){
-
+                if (colorPickerClickListener != null) {
+                    colorPickerClickListener.colorPicker();
+                }
             }else {
                 colorListAdapter.selectItem(position);
                 if (colorChangeListener != null) {
@@ -118,9 +124,6 @@ public class CColorListView extends LinearLayout {
         if (colorListAdapter != null) {
             colorListAdapter.selectByColor(color);
         }
-        if (colorChangeListener != null) {
-            colorChangeListener.color(color);
-        }
     }
 
     public void showColorPicker(boolean show){
@@ -131,11 +134,16 @@ public class CColorListView extends LinearLayout {
         }
     }
 
-    public void setColorChangeListener(OnColorChangeListener colorChangeListener) {
+    public void setColorChangeListener(COnColorChangeListener colorChangeListener) {
         this.colorChangeListener = colorChangeListener;
     }
 
-    public interface OnColorChangeListener {
-        void color(@ColorInt int color);
+    public void setColorPickerClickListener(OnColorPickerClickListener colorPickerClickListener) {
+        this.colorPickerClickListener = colorPickerClickListener;
+    }
+
+    public interface OnColorPickerClickListener{
+        void colorPicker();
     }
+
 }

+ 58 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/CColorPickerFragment.java

@@ -0,0 +1,58 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * 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.
+ */
+
+package com.compdfkit.tools.common.views.pdfproperties.colorpicker;
+
+import android.graphics.Color;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.common.views.pdfproperties.basic.CBasicPropertiesFragment;
+import com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget.ColorPickerView;
+
+
+public class CColorPickerFragment extends CBasicPropertiesFragment {
+
+    public static CColorPickerFragment newInstance() {
+        return new CColorPickerFragment();
+    }
+
+    private ColorPickerView colorPickerView;
+
+    private View rootView;
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+        rootView = inflater.inflate(R.layout.tools_color_pick_fragment, container, false);
+        colorPickerView = rootView.findViewById(R.id.color_picker_view);
+        int color = viewModel.getStyle().getColor();
+        int alpha = viewModel.getStyle().getColorAlpha();
+        colorPickerView.initColor(color, alpha);
+        colorPickerView.setColorPickerListener((color1, colorAlpha) -> {
+            viewModel.setColor(color1, colorAlpha);
+        });
+        viewModel.liveData.observe(getViewLifecycleOwner(), style -> {
+            if (!isOnResume) {
+                if (colorPickerView != null) {
+                    colorPickerView.initColor(style.getColor(), style.getColorAlpha());
+                }
+            }
+        });
+        return rootView;
+    }
+
+}

+ 19 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/interfaces/CMotionEventUpdatable.java

@@ -0,0 +1,19 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * 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.
+ */
+
+package com.compdfkit.tools.common.views.pdfproperties.colorpicker.interfaces;
+
+import android.view.MotionEvent;
+
+
+public interface CMotionEventUpdatable {
+
+    void update(MotionEvent event);
+
+}

+ 37 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/CThrottledTouchEventHandler.java

@@ -0,0 +1,37 @@
+package com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget;
+
+
+import android.view.MotionEvent;
+
+import com.compdfkit.tools.common.views.pdfproperties.colorpicker.interfaces.CMotionEventUpdatable;
+
+class CThrottledTouchEventHandler {
+
+    /**
+     * 16ms
+     */
+    private static final int EVENT_MIN_INTERVAL = 1000 / 60;
+
+    private final int minInterval;
+    private final CMotionEventUpdatable updatable;
+    private long lastPassedEventTime;
+
+    public CThrottledTouchEventHandler(int minInterval, CMotionEventUpdatable updatable) {
+        this.minInterval = minInterval;
+        this.updatable = updatable;
+    }
+
+    public CThrottledTouchEventHandler(CMotionEventUpdatable updatable) {
+        this(EVENT_MIN_INTERVAL, updatable);
+    }
+
+    public void onTouchEvent(MotionEvent event) {
+        long current = System.currentTimeMillis();
+        if (current - lastPassedEventTime <= minInterval) {
+            return;
+        }
+        lastPassedEventTime = current;
+        updatable.update(event);
+    }
+
+}

+ 190 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorAlphaSliderView.java

@@ -0,0 +1,190 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * 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.
+ */
+
+package com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import com.compdfkit.tools.R;
+import com.compdfkit.tools.common.utils.viewutils.CDimensUtils;
+import com.compdfkit.tools.common.views.pdfproperties.colorpicker.interfaces.CMotionEventUpdatable;
+
+class ColorAlphaSliderView extends View implements CMotionEventUpdatable {
+
+    private float circleWidth;
+
+    private float selectorRadiusPx;
+
+    private float selectorHalfWidth;
+
+    int baseColor = Color.BLACK;
+
+    private Paint colorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    private Paint selectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    private Paint outPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    private boolean onlyUpdateOnTouchEventUp = false;
+
+    private CThrottledTouchEventHandler handler;
+
+    private OnPercentChangeListener onPercentChangeListener;
+
+    private float percent = 0F;
+
+    private RectF roundRectF = new RectF();
+
+    private Bitmap alphaBitmap;
+
+    private Paint bitmapPaint = new Paint();
+
+    public ColorAlphaSliderView(Context context) {
+        this(context, null);
+    }
+
+    public ColorAlphaSliderView(Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public ColorAlphaSliderView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init(context);
+    }
+
+    private void init(Context context) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            setForceDarkAllowed(false);
+        }
+        handler = new CThrottledTouchEventHandler(this);
+        circleWidth = CDimensUtils.px2dp(context, 12);
+        selectorRadiusPx = CDimensUtils.px2dp(context, 80);
+        selectorHalfWidth = CDimensUtils.px2dp(context, 30);
+        selectorPaint.setColor(Color.WHITE);
+        selectorPaint.setStyle(Paint.Style.STROKE);
+        selectorPaint.setStrokeWidth(circleWidth);
+
+        outPaint.setColor(0x29000000);
+        outPaint.setStyle(Paint.Style.STROKE);
+        outPaint.setStrokeWidth(CDimensUtils.px2dp(context, 2));
+
+        alphaBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.tools_color_picker_bg_color_alpha);
+    }
+
+    private float getCurrentX() {
+        return ((getWidth() - 2 * selectorHalfWidth) * percent + selectorHalfWidth);
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        configurePaint();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        roundRectF.set(0F, 0F, (float) getWidth(), (float) getHeight());
+        if (alphaBitmap != null) {
+            canvas.drawBitmap(alphaBitmap, null, roundRectF, bitmapPaint);
+            canvas.drawRoundRect(roundRectF, 90f, 90f, colorPaint);
+            canvas.drawCircle(getCurrentX(), (float) (getHeight() / 2), selectorRadiusPx, selectorPaint);
+            canvas.drawCircle(getCurrentX(), (float) (getHeight() / 2), selectorRadiusPx + circleWidth, outPaint);
+        }
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        switch (event.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_MOVE:
+                handler.onTouchEvent(event);
+                return true;
+            case MotionEvent.ACTION_UP:
+                update(event);
+                return true;
+            default:
+                return super.onTouchEvent(event);
+        }
+    }
+
+    @Override
+    public void update(MotionEvent event) {
+        if (event == null) {
+            return;
+        }
+        updateValue(event.getX());
+        boolean isTouchUpEvent = event.getActionMasked() == MotionEvent.ACTION_UP;
+        if (!onlyUpdateOnTouchEventUp || isTouchUpEvent) {
+            if (onPercentChangeListener != null) {
+                onPercentChangeListener.value((int) (percent * 255));
+            }
+        }
+    }
+
+    /**
+     * 更新数据
+     */
+    private void updateValue(float eventX_) {
+        float eventX = eventX_;
+
+        float left = selectorHalfWidth;
+        float right = (float) getWidth() - selectorHalfWidth;
+
+        if (eventX < left) {
+            eventX = left;
+        }
+        if (eventX > right) {
+            eventX = right;
+        }
+        percent = (eventX - left) / (right - left);
+        invalidate();
+    }
+
+    private void configurePaint() {
+        LinearGradient shader = new LinearGradient(0f, 0f, (float) getWidth(), (float) getHeight(), Color.TRANSPARENT, baseColor, Shader.TileMode.CLAMP);
+        colorPaint.setShader(shader);
+        invalidate();
+    }
+
+    public void setBaseColor(int color) {
+        this.baseColor = color;
+        configurePaint();
+        invalidate();
+    }
+
+    public void setPercent(float percent) {
+        this.percent = percent;
+    }
+
+    public void setOnlyUpdateOnTouchEventUp(boolean onlyUpdateOnTouchEventUp) {
+        this.onlyUpdateOnTouchEventUp = onlyUpdateOnTouchEventUp;
+    }
+
+    public void setOnPercentChangeListener(OnPercentChangeListener onPercentChangeListener) {
+        this.onPercentChangeListener = onPercentChangeListener;
+    }
+
+    public interface OnPercentChangeListener {
+        void value(int percent);
+    }
+}
+

+ 19 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorPickerData.java

@@ -0,0 +1,19 @@
+package com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget;
+
+
+import androidx.annotation.ColorInt;
+import androidx.annotation.IntRange;
+
+class ColorPickerData {
+
+    @ColorInt
+    public int color;
+
+    public int alpha = 255;
+
+    public ColorPickerData(@ColorInt int color, @IntRange(from = 0, to = 255) int alpha) {
+        this.color = color;
+        this.alpha = alpha;
+    }
+
+}

+ 127 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorPickerView.java

@@ -0,0 +1,127 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * 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.
+ */
+
+package com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import androidx.annotation.ColorInt;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.compdfkit.tools.R;
+
+
+public class ColorPickerView extends FrameLayout implements View.OnTouchListener {
+
+    private ColorRectShowView mCurrentIndicatorColorView;
+
+    private ColorRectShowView mLastColorShowView;
+
+    private ColorRectView colorRectView;
+
+    private ColorSliderView colorSliderView;
+
+    private ColorAlphaSliderView colorAlphaSliderView;
+
+    private int color = Color.BLACK;
+
+    private int colorAlpha = 255;
+
+    private int lastColor = Color.WHITE;
+
+    private int lastColorAlpha = 255;
+
+    private ColorRectShowView.OnColorPickerListener colorPickerListener;
+
+    public ColorPickerView(@NonNull Context context) {
+        this(context, null);
+    }
+
+    public ColorPickerView(@NonNull Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public ColorPickerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        initView(context);
+    }
+
+    private void initView(Context context){
+        inflate(context, R.layout.tools_color_pick_view, this);
+        mCurrentIndicatorColorView = findViewById(R.id.id_bottom_customize_cv_indicator);
+        mLastColorShowView = findViewById(R.id.id_bottom_customize_cv_last);
+        colorRectView = findViewById(R.id.id_bottom_customize_v_color_set);
+        colorSliderView = findViewById(R.id.id_customize_color_slider);
+        colorAlphaSliderView = findViewById(R.id.id_customize_color_alpha_slider);
+
+        colorRectView.setColorSelectListener(color1 -> {
+            mCurrentIndicatorColorView.changeColor(color1);
+            colorSliderView.setBaseColor(color1);
+            colorAlphaSliderView.setBaseColor(color1);
+        });
+
+        colorSliderView.setOnColorLightChange(color1 -> {
+            mCurrentIndicatorColorView.changeColor(color1);
+        });
+
+        colorAlphaSliderView.setOnPercentChangeListener(percent -> {
+            mCurrentIndicatorColorView.changeAlpha(percent);
+        });
+        colorRectView.setOnTouchListener(this::onTouch);
+        colorSliderView.setOnTouchListener(this::onTouch);
+        colorAlphaSliderView.setOnTouchListener(this::onTouch);
+    }
+
+    public void initColor(@ColorInt int color, int colorAlpha){
+        this.color = color;
+        this.colorAlpha = colorAlpha;
+        this.lastColor = color;
+        this.lastColorAlpha = colorAlpha;
+        updateColorView();
+    }
+
+
+
+    private void updateColorView(){
+        colorRectView.setColor(color);
+        colorSliderView.setBaseColor(color);
+        colorAlphaSliderView.setBaseColor(color);
+        colorAlphaSliderView.setPercent(colorAlpha / 255F);
+        mCurrentIndicatorColorView.changeColor(color);
+        mCurrentIndicatorColorView.changeAlpha(colorAlpha);
+        colorAlphaSliderView.invalidate();
+        mLastColorShowView.changeAlpha(lastColorAlpha);
+        mLastColorShowView.changeColor(lastColor);
+    }
+
+    private void updateColor(){
+        if (colorPickerListener != null) {
+            colorPickerListener.color(mCurrentIndicatorColorView.getColor(), mCurrentIndicatorColorView.getColorAlpha());
+        }
+    }
+
+    public void setColorPickerListener(ColorRectShowView.OnColorPickerListener colorPickerListener) {
+        this.colorPickerListener = colorPickerListener;
+    }
+
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+        if (event.getActionMasked() == MotionEvent.ACTION_UP){
+            updateColor();
+        }
+        return false;
+    }
+}

+ 74 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorRectPalette.java

@@ -0,0 +1,74 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * 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.
+ */
+
+package com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget;
+
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.View;
+
+class ColorRectPalette extends View {
+    private RectF rect = new RectF(0f, 0f, 0f, 0f);
+    private Paint backPaint = new Paint();
+    private Paint verticalPaint = new Paint();
+
+    public ColorRectPalette(Context context) {
+        this(context, null);
+    }
+
+    public ColorRectPalette(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public ColorRectPalette(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            setForceDarkAllowed(false);
+        }
+        backPaint.setAntiAlias(true);
+        backPaint.setStyle(Paint.Style.FILL);
+        verticalPaint.setAntiAlias(true);
+        verticalPaint.setStyle(Paint.Style.FILL);
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        rect = new RectF(0f, 0f, w, h);
+        backPaint.setShader(new LinearGradient(0f, 0f, w, 0f, generateStretchColorArray(),
+                null, Shader.TileMode.CLAMP));
+        verticalPaint.setShader(new LinearGradient(0f, 0f, 0f, h, Color.TRANSPARENT, Color.WHITE,
+                Shader.TileMode.CLAMP));
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        canvas.drawRect(rect, backPaint);
+        canvas.drawRect(rect, verticalPaint);
+    }
+
+    private int[] generateStretchColorArray() {
+        int[] colorArray = new int[361];
+        int count = 0;
+        int i = colorArray.length - 1;
+        while (i >= 0) {
+            colorArray[count] = Color.HSVToColor(new float[]{i, 1f, 1f});
+            i--;
+            count++;
+        }
+        return colorArray;
+    }
+}

+ 81 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorRectSelector.java

@@ -0,0 +1,81 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * 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.
+ */
+
+package com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget;
+
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PointF;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.compdfkit.tools.common.utils.viewutils.CDimensUtils;
+import com.compdfkit.tools.common.utils.viewutils.CViewUtils;
+
+class ColorRectSelector extends View {
+
+    //半径
+    public static float RADIUS = 30f;
+
+    //整体半径
+    public float radiusRectSelector;
+
+    //选择器宽度
+    public float levelOneWidth;
+    public float levelTwoWidth;
+
+    //Paint
+    private Paint levelOnePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    private Paint levelTwoPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    private PointF currentPoint = new PointF();
+
+    public ColorRectSelector(Context context) {
+        this(context, null);
+    }
+
+    public ColorRectSelector(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public ColorRectSelector(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    private void init() {
+
+        radiusRectSelector = RADIUS + CDimensUtils.px2dp(getContext(), 12);
+        levelOneWidth = CDimensUtils.px2dp(getContext(), 8);
+        levelTwoWidth = RADIUS + CDimensUtils.px2dp(getContext(), 10);
+
+        levelOnePaint.setColor(Color.BLACK);
+        levelOnePaint.setStyle(Paint.Style.STROKE);
+        levelOnePaint.setStrokeWidth(levelOneWidth);
+
+        levelTwoPaint.setColor(0x29FFFFFF);
+        levelTwoPaint.setStyle(Paint.Style.STROKE);
+        levelTwoPaint.setStrokeWidth(levelTwoWidth);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        canvas.drawCircle(currentPoint.x, currentPoint.y, RADIUS + (levelTwoWidth - levelOneWidth), levelTwoPaint);
+        canvas.drawCircle(currentPoint.x, currentPoint.y, RADIUS, levelOnePaint);
+    }
+
+    public void setCurrentPoint(PointF currentPoint) {
+        this.currentPoint = currentPoint;
+        invalidate();
+    }
+}

+ 100 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorRectShowView.java

@@ -0,0 +1,100 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * 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.
+ */
+
+package com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import com.compdfkit.tools.R;
+
+class ColorRectShowView extends View {
+    private Paint backPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    private RectF colorRectF = new RectF();
+
+    private Bitmap bgBitmap;
+
+    private Paint bitmapPaint = new Paint();
+
+    private ColorPickerData colorPickerData = new ColorPickerData(Color.WHITE, 255);
+
+    public ColorRectShowView(Context context) {
+        super(context);
+        init();
+    }
+
+    public ColorRectShowView(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public ColorRectShowView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    private void init() {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            setForceDarkAllowed(false);
+        }
+        bgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.tools_color_picker_bg_color_rect);
+    }
+
+
+    public void changeColor(int color) {
+        colorPickerData.color = color;
+        invalidate();
+    }
+
+    public void changeAlpha(int alpha) {
+        colorPickerData.alpha = alpha;
+        invalidate();
+    }
+
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        if (bgBitmap != null) {
+            colorRectF.set(0F, 0F, getWidth(), getHeight());
+            canvas.drawBitmap(bgBitmap, null, colorRectF, bitmapPaint);
+            canvas.drawRect(colorRectF, backPaint);
+        }
+
+    }
+
+    @Override
+    public void invalidate() {
+        backPaint.setColor(colorPickerData != null ? colorPickerData.color : Color.WHITE);
+        backPaint.setAlpha(colorPickerData != null ? colorPickerData.alpha : 255);
+        super.invalidate();
+    }
+
+    public int getColor(){
+        return colorPickerData.color;
+    }
+
+    public int getColorAlpha(){
+        return colorPickerData.alpha;
+    }
+
+    public interface OnColorPickerListener{
+        void color(int color, int colorAlpha);
+    }
+}

+ 202 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorRectView.java

@@ -0,0 +1,202 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * 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.
+ */
+
+package com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget;
+
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.PointF;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import androidx.annotation.Nullable;
+
+import com.compdfkit.tools.common.interfaces.COnColorChangeListener;
+import com.compdfkit.tools.common.utils.viewutils.CDimensUtils;
+import com.compdfkit.tools.common.views.pdfproperties.colorpicker.interfaces.CMotionEventUpdatable;
+
+public class ColorRectView extends FrameLayout implements CMotionEventUpdatable {
+
+    private PointF currentPoint = new PointF();
+
+    private int currentColor = Color.MAGENTA;
+
+    private boolean onlyUpdateOnTouchEventUp = false;
+
+    private COnColorChangeListener colorSelectListener;
+
+    private ColorRectSelector selector;
+
+    private CThrottledTouchEventHandler handler;
+
+    public ColorRectView(Context context) {
+        this(context, null);
+    }
+
+    public ColorRectView(Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public ColorRectView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        selector = new ColorRectSelector(context);
+        handler = new CThrottledTouchEventHandler(this);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            setForceDarkAllowed(false);
+        }
+
+        int padding = CDimensUtils.px2dp(context, 26);
+        ColorRectPalette palette = new ColorRectPalette(context);
+        palette.setPadding(padding, padding, padding, padding);
+        ViewGroup.LayoutParams paletteLayoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+        addView(palette, paletteLayoutParams);
+
+        ViewGroup.LayoutParams selectorLayoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+        addView(selector, selectorLayoutParams);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int maxWidth = MeasureSpec.getSize(widthMeasureSpec);
+        int maxHeight = MeasureSpec.getSize(heightMeasureSpec);
+        int mWidth = maxWidth;
+        int mHeight = maxHeight;
+        super.onMeasure(
+                MeasureSpec.makeMeasureSpec(mWidth, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(mHeight, MeasureSpec.EXACTLY)
+        );
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        setColor(currentColor);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        switch (event.getActionMasked()){
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_MOVE:
+                if (event.getX() - selector.radiusRectSelector <= 0){
+                    event.setLocation(selector.radiusRectSelector, event.getY());
+                } else if (event.getX() + selector.radiusRectSelector > getWidth()) {
+                    event.setLocation(getWidth() - selector.radiusRectSelector, event.getY());
+                } else if (event.getY() - selector.radiusRectSelector <= 0) {
+                    event.setLocation(event.getX(), selector.radiusRectSelector);
+                } else if (event.getY() + selector.radiusRectSelector > getHeight()) {
+                    event.setLocation(event.getX(), getHeight() - selector.radiusRectSelector);
+                }
+                handler.onTouchEvent(event);
+                return true;
+            case MotionEvent.ACTION_UP:
+                if (event.getX() - selector.radiusRectSelector <= 0){
+                    event.setLocation(selector.radiusRectSelector, event.getY());
+                } else if (event.getX() + selector.radiusRectSelector > getWidth()) {
+                    event.setLocation(getWidth() - selector.radiusRectSelector, event.getY());
+                } else if (event.getY() - selector.radiusRectSelector <= 0) {
+                    event.setLocation(event.getX(), selector.radiusRectSelector);
+                } else if (event.getY() + selector.radiusRectSelector > getHeight()) {
+                    event.setLocation(event.getX(), getHeight() - selector.radiusRectSelector);
+                }
+                update(event);
+                return true;
+            default:
+                return super.onTouchEvent(event);
+        }
+    }
+
+
+    @Override
+    public void update(MotionEvent event) {
+        if (event == null) {
+            return;
+        }
+        boolean isTouchUpEvent = event.getActionMasked() == MotionEvent.ACTION_UP;
+        if (!onlyUpdateOnTouchEventUp || isTouchUpEvent) {
+            if (colorSelectListener != null) {
+                colorSelectListener.color(getColorAtPoint(event.getX(), event.getY()));
+            }
+        }
+        updateSelector(event.getX(), event.getY());
+    }
+
+    private int getColorAtPoint(float eventX, float eventY){
+        float pointX = eventX;
+        if (eventX - selector.radiusRectSelector <= 0 ){
+            pointX = selector.radiusRectSelector;
+        } else if (eventX + selector.radiusRectSelector >= getWidth()) {
+            pointX = getWidth() - selector.radiusRectSelector;
+        }else {
+            pointX = eventX;
+        }
+        float x = 360F - pointX * 360F / getWidth();
+
+        float pointY = eventY;
+        if (eventY - selector.radiusRectSelector <= 0){
+            pointY = 0F;
+        } else if (eventY + selector.radiusRectSelector >= getHeight()) {
+            pointY = getHeight() - selector.radiusRectSelector;
+        } else {
+            pointY = eventY;
+        }
+        float y = 1F - (pointY / (getHeight() - selector.radiusRectSelector));
+
+        if (y == 0F){
+            return Color.WHITE;
+        }else {
+            return Color.HSVToColor(new float[]{x, y, 1F});
+        }
+    }
+
+
+    public void  setColor(int color) {
+        float[] hsv = new float[3];
+        Color.colorToHSV(color, hsv);
+        Color.HSVToColor(color, hsv);
+        updateSelector((getWidth() - (getWidth() * hsv[0]) / 360), ((1 - hsv[1]) * getHeight()));
+        currentColor = color;
+//        if (!onlyUpdateOnTouchEventUp){
+//            if (colorSelectListener != null) {
+//                colorSelectListener.color(currentColor);
+//            }
+//        }
+    }
+
+    private void updateSelector(float eventX,float eventY) {
+        if (eventX - selector.radiusRectSelector <= 0){
+            currentPoint.x = selector.radiusRectSelector;
+        } else if (eventX + selector.radiusRectSelector >= getWidth()) {
+            currentPoint.x = getWidth() + selector.radiusRectSelector;
+        } else {
+            currentPoint.x = eventX;
+        }
+
+        if (eventY - selector.radiusRectSelector <= 0){
+            currentPoint.y = selector.radiusRectSelector;
+        } else if (eventY + selector.radiusRectSelector >= getHeight()) {
+            currentPoint.y = getHeight() - selector.radiusRectSelector;
+        }else {
+            currentPoint.y = eventY;
+        }
+        selector.setCurrentPoint(currentPoint);
+    }
+
+    public void setOnlyUpdateOnTouchEventUp(boolean onlyUpdateOnTouchEventUp) {
+        this.onlyUpdateOnTouchEventUp = onlyUpdateOnTouchEventUp;
+    }
+
+    public void setColorSelectListener(COnColorChangeListener colorSelectListener) {
+        this.colorSelectListener = colorSelectListener;
+    }
+}

+ 206 - 0
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfproperties/colorpicker/widget/ColorSliderView.java

@@ -0,0 +1,206 @@
+/**
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
+ * <p>
+ * 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.
+ */
+
+package com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget;
+
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import com.compdfkit.tools.common.interfaces.COnColorChangeListener;
+import com.compdfkit.tools.common.utils.viewutils.CDimensUtils;
+import com.compdfkit.tools.common.views.pdfproperties.colorpicker.interfaces.CMotionEventUpdatable;
+
+class ColorSliderView extends View implements CMotionEventUpdatable {
+
+    private float circleWidth;
+
+    private float selectorRadiusPx;
+
+    private float selectorHalfWidth;
+
+    private int baseColor = Color.BLUE;
+
+    private Paint colorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    private Paint selectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    private Paint outPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+    private float currentValue = 1f;
+
+    private boolean onlyUpdateOnTouchEventUp = false;
+
+    private CThrottledTouchEventHandler handler;
+
+    private PointF currentPoint;
+
+    private COnColorChangeListener onColorLightChange;
+
+    private RectF roundRect = new RectF();
+
+
+    public ColorSliderView(Context context) {
+        this(context, null);
+    }
+
+    public ColorSliderView(Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public ColorSliderView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init(context);
+    }
+
+    private void init(Context context) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            setForceDarkAllowed(false);
+        }
+        handler = new CThrottledTouchEventHandler(this);
+        circleWidth = CDimensUtils.px2dp(context, 12);
+        selectorRadiusPx = CDimensUtils.px2dp(context, 80);
+        selectorHalfWidth = CDimensUtils.px2dp(context, 30);
+
+        currentPoint = new PointF(selectorHalfWidth, ((float) getHeight() / 2));
+
+        selectorPaint.setColor(Color.WHITE);
+        selectorPaint.setStyle(Paint.Style.STROKE);
+        selectorPaint.setStrokeWidth(circleWidth);
+
+        outPaint.setColor(0x29000000);
+        outPaint.setStyle(Paint.Style.STROKE);
+        outPaint.setStrokeWidth(CDimensUtils.px2dp(context, 2));
+    }
+
+    public void setBaseColor(int baseColor) {
+        this.baseColor = baseColor;
+        if (getWidth() != 0) {
+            configurePaint();
+            float[] hsv = new float[3];
+            Color.colorToHSV(this.baseColor, hsv);
+            currentValue = hsv[2];
+            currentPoint.x = selectorHalfWidth + ((float) getWidth() - 2 * selectorHalfWidth) * (1 - currentValue);
+            if (currentPoint.y == 0F) {
+                currentPoint.y = getHeight() / 2F;
+            }
+            invalidate();
+        }
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        configurePaint();
+        if (getWidth() != 0) {
+            configurePaint();
+            float[] hsv = new float[3];
+            Color.colorToHSV(baseColor, hsv);
+            currentValue = hsv[2];
+            currentPoint.x = selectorHalfWidth + ((float) getWidth() - 2 * selectorHalfWidth) * (1 - currentValue);
+            if (currentPoint.y == 0f) {
+                currentPoint.y = getHeight() / 2f;
+            }
+            invalidate();
+        }
+    }
+
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        roundRect.set(0F, 0F, (float) getWidth(), (float) getHeight());
+        canvas.drawRoundRect(roundRect, 90f, 90f, colorPaint);
+        canvas.drawCircle(currentPoint.x, ((float) getHeight() / 2), selectorRadiusPx, selectorPaint);
+        canvas.drawCircle(currentPoint.x,  ((float) getHeight() / 2), selectorRadiusPx + circleWidth, outPaint);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        switch (event.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_MOVE:
+                handler.onTouchEvent(event);
+                return true;
+            case MotionEvent.ACTION_UP:
+                update(event);
+                return true;
+            default:
+                return super.onTouchEvent(event);
+        }
+    }
+
+    private void configurePaint() {
+        float[] hsv = new float[3];
+        Color.colorToHSV(baseColor, hsv);
+        hsv[2] = 1f;
+        int startColor = Color.HSVToColor(hsv);
+        hsv[2] = 0f;
+        int endColor = Color.HSVToColor(hsv);
+        LinearGradient shader = new LinearGradient(0f, 0f, (float) getWidth(), (float) getHeight(), startColor, endColor, Shader.TileMode.MIRROR);
+        colorPaint.setShader(shader);
+    }
+
+
+    private void updateValue(float eventX_) {
+        float eventX = eventX_;
+        float left = selectorHalfWidth;
+        float right = (float) getWidth() - selectorHalfWidth;
+        if (eventX < left) {
+            eventX = left;
+        }
+        if (eventX > right) {
+            eventX = right;
+        }
+        currentValue = (eventX - left) / (right - left);
+        currentPoint.x = eventX;
+        currentPoint.y = getHeight() / 2F;
+        invalidate();
+    }
+
+    private int assembleColor() {
+        float[] hsv = new float[3];
+        Color.colorToHSV(baseColor, hsv);
+        hsv[2] = 1 - currentValue;
+        return Color.HSVToColor(hsv);
+    }
+
+
+    @Override
+    public void update(MotionEvent event) {
+        if (event == null) {
+            return;
+        }
+        updateValue(event.getX());
+        boolean isTouchUpEvent = event.getActionMasked() == MotionEvent.ACTION_UP;
+        if (!onlyUpdateOnTouchEventUp || isTouchUpEvent) {
+            if (onColorLightChange != null) {
+                onColorLightChange.color(assembleColor());
+            }
+        }
+    }
+
+    public void setOnColorLightChange(COnColorChangeListener onColorLightChange) {
+        this.onColorLightChange = onColorLightChange;
+    }
+
+    public void setOnlyUpdateOnTouchEventUp(boolean onlyUpdateOnTouchEventUp) {
+        this.onlyUpdateOnTouchEventUp = onlyUpdateOnTouchEventUp;
+    }
+}

+ 61 - 38
compdfkit-tools/src/main/java/com/compdfkit/tools/common/views/pdfview/CPDFViewCtrl.java

@@ -36,10 +36,17 @@ import com.compdfkit.tools.annotation.pdfproperties.pdfnote.CPDFtextAnnotImpl;
 import com.compdfkit.tools.common.utils.dialog.CGotoPageDialog;
 import com.compdfkit.tools.common.utils.viewutils.CDimensUtils;
 import com.compdfkit.tools.common.utils.viewutils.CViewUtils;
+import com.compdfkit.ui.proxy.CPDFBaseAnnotImpl;
+import com.compdfkit.ui.reader.CPDFAddAnnotCallback;
+import com.compdfkit.ui.reader.CPDFPageView;
 import com.compdfkit.ui.reader.CPDFReaderView;
 import com.compdfkit.ui.reader.IReaderViewCallback;
+import com.compdfkit.ui.reader.OnFocusedTypeChangedListener;
 import com.compdfkit.ui.widget.CPDFSlideBar;
 
+import java.util.ArrayList;
+import java.util.List;
+
 
 /**
  * compdfkit sdk CPDFReaderView ctrl view <br/>
@@ -93,13 +100,15 @@ import com.compdfkit.ui.widget.CPDFSlideBar;
  * <p/>
  * app:tools_enable_page_indicator="true|false"
  */
-public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback {
+public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback ,OnFocusedTypeChangedListener{
 
     private CPDFReaderView cPdfReaderView;
 
-    public int currentPageIndex = 0;
+    public CPDFPageIndicatorView indicatorView;
 
-    private CPDFSlideBar slideBar;
+    public CPDFSlideBar slideBar;
+
+    public int currentPageIndex = 0;
 
     private boolean enableSliderBar = true;
 
@@ -112,12 +121,27 @@ public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback
     @DrawableRes
     private int sliderBarIconResId = R.drawable.tools_ic_pdf_slider_bar;
 
-    private CPDFPageIndicatorView indicatorView;
-
     private boolean enablePageIndicator = true;
 
+    private int pageIndicatorMarginBottom = 16;
+
     private OnTapMainDocAreaCallback onTapMainDocAreaCallback;
 
+    private boolean isScrolling = false;
+
+    private Handler handler = new Handler(Looper.getMainLooper());
+
+    private ObjectAnimator pageIndicatorAnimator = null;
+
+    private List<OnFocusedTypeChangedListener> pdfViewFocusedListenerList = new ArrayList<>();
+
+    private Runnable hideIndicatorRunnable = () -> {
+        if (pageIndicatorAnimator != null) {
+            isScrolling = false;
+            pageIndicatorAnimator.reverse();
+        }
+    };
+
     public CPDFViewCtrl(@NonNull Context context) {
         this(context, null);
     }
@@ -132,7 +156,6 @@ public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback
         initCPDFReaderView();
     }
 
-
     private void initAttr(Context context, AttributeSet attributeSet) {
         try {
             TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.CPDFReaderView);
@@ -148,12 +171,18 @@ public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback
                 sliderBarThumbnailHeight = typedArray.getDimensionPixelOffset(R.styleable.CPDFReaderView_tools_slider_bar_thumbnail_height, 444);
                 sliderBarIconResId = typedArray.getResourceId(R.styleable.CPDFReaderView_tools_slider_bar_icon, R.drawable.tools_ic_pdf_slider_bar);
                 enablePageIndicator = typedArray.getBoolean(R.styleable.CPDFReaderView_tools_enable_page_indicator, true);
+                pageIndicatorMarginBottom = typedArray.getDimensionPixelOffset(R.styleable.CPDFReaderView_tools_page_indicator_margin_bottom, 16);
+                if (enableSliderBar) {
+                    slideBar = new CPDFSliderBarView(getContext());
+                }
+                if (enablePageIndicator){
+                    indicatorView = new CPDFPageIndicatorView(getContext());
+                }
                 typedArray.recycle();
             }
         } catch (Exception e) {
 
         }
-
     }
 
 
@@ -162,11 +191,10 @@ public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback
         cPdfReaderView.setDoublePageMode(false);
         cPdfReaderView.setReaderViewCallback(this);
         cPdfReaderView.setContextMenuShowListener(new CContextMenuHelper(cPdfReaderView));
+        cPdfReaderView.setOnFocusedTypeChangedListener(this);
         setAllowAddAndEditAnnot(false);
-        //note注释创建、点击操作类
-        cPdfReaderView.getAnnotImplRegistry().registAttachHelper(CPDFTextAnnotation.class, CPDFtextAnnotAttachHelper.class);
-        cPdfReaderView.getAnnotImplRegistry().registImpl(CPDFTextAnnotation.class, CPDFtextAnnotImpl.class);
-        setAllowAddAndEditAnnot(true);
+//        cPdfReaderView.getAnnotImplRegistry().registAttachHelper(CPDFTextAnnotation.class, CPDFtextAnnotAttachHelper.class);
+//        cPdfReaderView.getAnnotImplRegistry().registImpl(CPDFTextAnnotation.class, CPDFtextAnnotImpl.class);
         addView(cPdfReaderView);
     }
 
@@ -213,10 +241,6 @@ public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback
         }
     }
 
-    public com.compdfkit.ui.reader.CPDFReaderView getCPdfReaderView() {
-        return cPdfReaderView;
-    }
-
     public void changeAnnotationType(CPDFAnnotation.Type type) {
         cPdfReaderView.setTouchMode(CPDFReaderView.TouchMode.ADD_ANNOT);
         cPdfReaderView.setCurrentFocusedType(type);
@@ -227,6 +251,18 @@ public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback
         cPdfReaderView.setCurrentFocusedType(CPDFAnnotation.Type.UNKNOWN);
     }
 
+    public com.compdfkit.ui.reader.CPDFReaderView getCPdfReaderView() {
+        return cPdfReaderView;
+    }
+
+    @Override
+    public void onTypeChanged(CPDFAnnotation.Type type) {
+        if (pdfViewFocusedListenerList != null) {
+            for (OnFocusedTypeChangedListener onFocusedTypeChangedListener : pdfViewFocusedListenerList) {
+                onFocusedTypeChangedListener.onTypeChanged(type);
+            }
+        }
+    }
 
     @Override
     public void onTapMainDocArea() {
@@ -269,17 +305,16 @@ public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback
         if (!enableSliderBar) {
             return;
         }
-        CPDFSliderBarView cpdfSliderBarView = new CPDFSliderBarView(getContext());
+        CPDFSliderBarView cpdfSliderBarView = (CPDFSliderBarView) slideBar;
         cpdfSliderBarView.initWithPDFView(this);
         cpdfSliderBarView.initSliderBar(slideBarPosition, sliderBarThumbnailWidth, sliderBarThumbnailHeight);
         cpdfSliderBarView.setSlideBarBitmap(sliderBarIconResId);
         setSliderBar(cpdfSliderBarView);
     }
 
-    public void setSliderBar(CPDFSlideBar cpdfSlideBar) {
+    private void setSliderBar(CPDFSlideBar cpdfSlideBar) {
         enableSliderBar = true;
         slideBar = cpdfSlideBar;
-
         LinearLayout linearLayout = new LinearLayout(getContext());
         LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
         linearLayout.setLayoutParams(layoutParams);
@@ -292,8 +327,6 @@ public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback
         addView(linearLayout);
     }
 
-    ObjectAnimator pageIndicatorAnimator = null;
-
     /**
      * Add a page indicator in the lower left corner of the page.
      * After clicking, a page number jump input box will pop up, and you can jump to the corresponding PDF page
@@ -301,16 +334,15 @@ public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback
      *
      * @see CPDFPageIndicatorView
      */
-    public void addPageIndicator() {
+    private void addPageIndicator() {
         if (!enablePageIndicator) {
             return;
         }
-        indicatorView = new CPDFPageIndicatorView(getContext());
         RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
         layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
         layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
         int margin = CDimensUtils.dp2px(getContext(), 16);
-        layoutParams.setMargins(margin, 0, 0, margin);
+        layoutParams.setMargins(margin, 0, 0, pageIndicatorMarginBottom+margin);
         indicatorView.setLayoutParams(layoutParams);
         indicatorView.setAlpha(0F);
         addView(indicatorView);
@@ -319,8 +351,7 @@ public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback
         indicatorView.setTotalPage(totalPageCount);
         indicatorView.setPageIndicatorClickListener(pageIndex -> {
             CGotoPageDialog dialog = new CGotoPageDialog(getContext());
-            dialog.setHintInputText(getContext().getString(R.string.tools_search_header_page) +
-                    String.format(" (%d/%d)", 1, totalPageCount));
+            dialog.setHintInputText(getContext().getString(R.string.tools_search_header_page) + String.format(" (%d/%d)", 1, totalPageCount));
             dialog.setOnSetPDFDisplayPageIndexListener(page -> {
                 if (page <= totalPageCount && page > 0) {
                     cPdfReaderView.setDisplayPageIndex(page - 1, true);
@@ -328,26 +359,13 @@ public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback
             });
             dialog.show();
         });
-
         pageIndicatorAnimator = ObjectAnimator.ofFloat(indicatorView, "alpha", 0F, 1F);
         pageIndicatorAnimator.setDuration(100);
         pageIndicatorAnimator.setInterpolator(new FastOutLinearInInterpolator());
         showPageIndicator();
-        Log.e("CPDFView", "init addPageIndicator");
         hidePageIndicator();
     }
 
-    private boolean isScrolling = false;
-
-    private Handler handler = new Handler(Looper.getMainLooper());
-
-    private Runnable hideIndicatorRunnable = () -> {
-        if (pageIndicatorAnimator != null) {
-            isScrolling = false;
-            pageIndicatorAnimator.reverse();
-        }
-    };
-
     private void hidePageIndicator() {
         handler.postDelayed(hideIndicatorRunnable, 3000);
     }
@@ -358,10 +376,15 @@ public class CPDFViewCtrl extends RelativeLayout implements IReaderViewCallback
         }
     }
 
+    public void addOnPDFFocusedTypeChangeListener(OnFocusedTypeChangedListener listener){
+        pdfViewFocusedListenerList.add(listener);
+    }
+
     public void setOnTapMainDocAreaCallback(OnTapMainDocAreaCallback onTapMainDocAreaCallback) {
         this.onTapMainDocAreaCallback = onTapMainDocAreaCallback;
     }
 
+
     public interface OnTapMainDocAreaCallback {
         void onTapMainDocArea();
     }

+ 3 - 3
compdfkit-tools/src/main/java/com/compdfkit/tools/viewer/pdfbookmark/CPDFBookmarkFragment.java

@@ -25,7 +25,7 @@ import com.compdfkit.core.common.CPDFDate;
 import com.compdfkit.core.document.CPDFBookmark;
 import com.compdfkit.core.utils.TTimeUtil;
 import com.compdfkit.tools.R;
-import com.compdfkit.tools.common.interfaces.OnSetPDFDisplayPageIndexListener;
+import com.compdfkit.tools.common.interfaces.COnSetPDFDisplayPageIndexListener;
 import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
 import com.compdfkit.tools.viewer.pdfbookmark.adapter.CPDFBookmarkListAdapter;
 import com.compdfkit.tools.viewer.pdfbookmark.dialog.CEditBookmarkDialog;
@@ -42,7 +42,7 @@ public class CPDFBookmarkFragment extends Fragment {
 
     private CPDFViewCtrl pdfView;
 
-    private OnSetPDFDisplayPageIndexListener displayPageIndexListener;
+    private COnSetPDFDisplayPageIndexListener displayPageIndexListener;
 
     public static CPDFBookmarkFragment newInstance() {
         return new CPDFBookmarkFragment();
@@ -62,7 +62,7 @@ public class CPDFBookmarkFragment extends Fragment {
     }
 
 
-    public void setPDFDisplayPageIndexListener(OnSetPDFDisplayPageIndexListener displayPageIndexListener) {
+    public void setPDFDisplayPageIndexListener(COnSetPDFDisplayPageIndexListener displayPageIndexListener) {
         this.displayPageIndexListener = displayPageIndexListener;
     }
 

+ 3 - 3
compdfkit-tools/src/main/java/com/compdfkit/tools/viewer/pdfbookmark/adapter/CPDFBookmarkListAdapter.java

@@ -15,7 +15,7 @@ import androidx.recyclerview.widget.RecyclerView;
 
 import com.compdfkit.core.document.CPDFBookmark;
 import com.compdfkit.tools.R;
-import com.compdfkit.tools.common.interfaces.OnSetPDFDisplayPageIndexListener;
+import com.compdfkit.tools.common.interfaces.COnSetPDFDisplayPageIndexListener;
 
 import java.util.List;
 
@@ -23,7 +23,7 @@ public class CPDFBookmarkListAdapter extends ListAdapter<CPDFBookmark, CPDFBookm
 
     public static final String REFRESH_ITEM = "refresh_item";
 
-    private OnSetPDFDisplayPageIndexListener displayPageIndexListener;
+    private COnSetPDFDisplayPageIndexListener displayPageIndexListener;
 
     private OnBookmarkCallback editBookmarkClickListener;
 
@@ -98,7 +98,7 @@ public class CPDFBookmarkListAdapter extends ListAdapter<CPDFBookmark, CPDFBookm
         }
     }
 
-    public void setDisplayPageIndexListener(OnSetPDFDisplayPageIndexListener displayPageIndexListener) {
+    public void setDisplayPageIndexListener(COnSetPDFDisplayPageIndexListener displayPageIndexListener) {
         this.displayPageIndexListener = displayPageIndexListener;
     }
 

+ 3 - 3
compdfkit-tools/src/main/java/com/compdfkit/tools/viewer/pdfoutline/CPDFOutlineFragment.java

@@ -22,7 +22,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.compdfkit.tools.R;
-import com.compdfkit.tools.common.interfaces.OnSetPDFDisplayPageIndexListener;
+import com.compdfkit.tools.common.interfaces.COnSetPDFDisplayPageIndexListener;
 import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
 import com.compdfkit.tools.viewer.pdfoutline.adapter.COutlineListAdapter;
 import com.compdfkit.tools.viewer.pdfoutline.bean.COutlineData;
@@ -39,7 +39,7 @@ public class CPDFOutlineFragment extends Fragment {
 
     private RecyclerView rvOutlineRecyclerView;
 
-    private OnSetPDFDisplayPageIndexListener outlineCallback;
+    private COnSetPDFDisplayPageIndexListener outlineCallback;
 
     private CPDFViewCtrl pdfView;
 
@@ -101,7 +101,7 @@ public class CPDFOutlineFragment extends Fragment {
      *
      * @param outlineClickListener The listener to set.
      */
-    public void setOutlineClickListener(OnSetPDFDisplayPageIndexListener outlineClickListener) {
+    public void setOutlineClickListener(COnSetPDFDisplayPageIndexListener outlineClickListener) {
         this.outlineCallback = outlineClickListener;
     }
 }

+ 3 - 3
compdfkit-tools/src/main/java/com/compdfkit/tools/viewer/pdfoutline/adapter/COutlineListAdapter.java

@@ -20,7 +20,7 @@ import androidx.constraintlayout.widget.ConstraintLayout;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.compdfkit.tools.R;
-import com.compdfkit.tools.common.interfaces.OnSetPDFDisplayPageIndexListener;
+import com.compdfkit.tools.common.interfaces.COnSetPDFDisplayPageIndexListener;
 import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
 import com.compdfkit.tools.viewer.pdfoutline.bean.COutlineData;
 import com.compdfkit.tools.viewer.pdfoutline.data.COutlineDatas;
@@ -51,7 +51,7 @@ public class COutlineListAdapter extends RecyclerView.Adapter<COutlineListAdapte
 
     private ArrayList<COutlineData> list = new ArrayList<>();
 
-    private OnSetPDFDisplayPageIndexListener outlineClickListener;
+    private COnSetPDFDisplayPageIndexListener outlineClickListener;
 
     /**
      * set outline list data
@@ -185,7 +185,7 @@ public class COutlineListAdapter extends RecyclerView.Adapter<COutlineListAdapte
         }
     }
 
-    public void setOutlineClickListener(OnSetPDFDisplayPageIndexListener outlineClickListener) {
+    public void setOutlineClickListener(COnSetPDFDisplayPageIndexListener outlineClickListener) {
         this.outlineClickListener = outlineClickListener;
     }
 }

+ 3 - 3
compdfkit-tools/src/main/java/com/compdfkit/tools/viewer/pdfthumbnail/CPDFThumbnailFragment.java

@@ -25,7 +25,7 @@ import androidx.recyclerview.widget.RecyclerView;
 
 import com.compdfkit.core.document.CPDFDocument;
 import com.compdfkit.tools.R;
-import com.compdfkit.tools.common.interfaces.OnSetPDFDisplayPageIndexListener;
+import com.compdfkit.tools.common.interfaces.COnSetPDFDisplayPageIndexListener;
 import com.compdfkit.tools.common.utils.glide.CPDFWrapper;
 import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
 import com.compdfkit.tools.viewer.pdfthumbnail.adpater.CPDFThumbnailListAdapter;
@@ -65,7 +65,7 @@ public class CPDFThumbnailFragment extends Fragment {
 
     private RecyclerView rvThumbnailRecyclerView;
 
-    private OnSetPDFDisplayPageIndexListener displayPageIndexListener;
+    private COnSetPDFDisplayPageIndexListener displayPageIndexListener;
 
     private CPDFViewCtrl pdfView;
 
@@ -115,7 +115,7 @@ public class CPDFThumbnailFragment extends Fragment {
 
     }
 
-    public void setPDFDisplayPageIndexListener(OnSetPDFDisplayPageIndexListener displayPageIndexListener) {
+    public void setPDFDisplayPageIndexListener(COnSetPDFDisplayPageIndexListener displayPageIndexListener) {
         this.displayPageIndexListener = displayPageIndexListener;
     }
 }

+ 3 - 3
compdfkit-tools/src/main/java/com/compdfkit/tools/viewer/pdfthumbnail/adpater/CPDFThumbnailListAdapter.java

@@ -23,7 +23,7 @@ import com.bumptech.glide.Glide;
 import com.bumptech.glide.load.engine.DiskCacheStrategy;
 import com.compdfkit.core.document.CPDFDocument;
 import com.compdfkit.tools.R;
-import com.compdfkit.tools.common.interfaces.OnSetPDFDisplayPageIndexListener;
+import com.compdfkit.tools.common.interfaces.COnSetPDFDisplayPageIndexListener;
 import com.compdfkit.tools.common.utils.glide.CPDFWrapper;
 
 /**
@@ -37,7 +37,7 @@ public class CPDFThumbnailListAdapter extends RecyclerView.Adapter<CPDFThumbnail
 
     private int currentPageIndex;
 
-    private OnSetPDFDisplayPageIndexListener displayPageIndexListener;
+    private COnSetPDFDisplayPageIndexListener displayPageIndexListener;
 
     public CPDFThumbnailListAdapter(CPDFDocument cDdfDocument, int currentPageIndex) {
         this.cPdfDocument = cDdfDocument;
@@ -72,7 +72,7 @@ public class CPDFThumbnailListAdapter extends RecyclerView.Adapter<CPDFThumbnail
         return cPdfDocument == null ? 0 : cPdfDocument.getPageCount();
     }
 
-    public void setPDFDisplayPageIndexListener(OnSetPDFDisplayPageIndexListener listener) {
+    public void setPDFDisplayPageIndexListener(COnSetPDFDisplayPageIndexListener listener) {
         this.displayPageIndexListener = listener;
     }
 

+ 7 - 0
compdfkit-tools/src/main/res/anim/tools_slide_in_right.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate android:fromXDelta="50%p" android:toXDelta="0"
+        android:duration="@android:integer/config_mediumAnimTime"/>
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+        android:duration="@android:integer/config_mediumAnimTime" />
+</set>

+ 7 - 0
compdfkit-tools/src/main/res/anim/tools_slide_out_left.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate android:fromXDelta="0" android:toXDelta="-50%p"
+        android:duration="@android:integer/config_mediumAnimTime"/>
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+        android:duration="@android:integer/config_mediumAnimTime" />
+</set>

BIN
compdfkit-tools/src/main/res/drawable/tools_color_picker_bg_color_alpha.png


BIN
compdfkit-tools/src/main/res/drawable/tools_color_picker_bg_color_rect.png


+ 9 - 0
compdfkit-tools/src/main/res/drawable/tools_common_oval_ripple.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="?attr/colorControlHighlight">
+    <item android:id="@android:id/mask">
+        <shape android:shape="oval">
+            <solid android:color="?android:attr/colorBackground" />
+        </shape>
+    </item>
+</ripple>

+ 5 - 0
compdfkit-tools/src/main/res/drawable/tools_ic_close.xml

@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#000000"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
+</vector>

+ 65 - 18
compdfkit-tools/src/main/res/layout/tools_annot_style_dialog_fragment.xml

@@ -1,38 +1,85 @@
 <?xml version="1.0" encoding="utf-8"?>
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
-    android:background="@drawable/tools_annot_style_dialog_window_bg"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:layout_gravity="bottom"
+    android:animateLayoutChanges="true"
+    android:background="@drawable/tools_annot_style_dialog_window_bg">
 
-
-    <com.compdfkit.tools.common.views.CToolBar
-        android:id="@+id/tool_bar"
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_tool_bar"
         android:layout_width="match_parent"
-        android:background="@android:color/transparent"
         android:layout_height="?android:attr/actionBarSize"
+        app:layout_constraintBottom_toTopOf="@id/cl"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:tools_toolbar_title=" " />
+        app:layout_constraintStart_toStartOf="parent">
+
+        <androidx.appcompat.widget.AppCompatTextView
+            android:id="@+id/tv_tool_bar_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textColor="?android:attr/textColorPrimary"
+            android:textSize="16sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:text="PDF View" />
+
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_tool_bar_previous"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_margin="10dp"
+            android:background="@drawable/tools_common_oval_ripple"
+            android:padding="4dp"
+            android:visibility="gone"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintDimensionRatio="1:1"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/tools_ic_back"
+            app:tint="?android:attr/colorAccent" />
+
+        <androidx.appcompat.widget.AppCompatImageView
+            android:id="@+id/iv_tool_bar_close"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_margin="10dp"
+            android:background="@drawable/tools_common_oval_ripple"
+            android:padding="4dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintDimensionRatio="1:1"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/tools_ic_close"
+            app:tint="?android:attr/colorAccent" />
 
 
-    <com.compdfkit.tools.common.utils.view.CNestedScrollableHost
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/tool_bar"
-        app:layout_constraintVertical_bias="0">
+        app:layout_constraintEnd_toEndOf="parent">
+
 
         <androidx.viewpager2.widget.ViewPager2
             android:id="@+id/view_pager"
+            android:animateLayoutChanges="true"
             android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            app:layout_constraintTop_toBottomOf="@id/tool_bar"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"/>
+            android:layout_height="wrap_content"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent" />
+
 
-    </com.compdfkit.tools.common.utils.view.CNestedScrollableHost>
+    </androidx.constraintlayout.widget.ConstraintLayout>
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 0
compdfkit-tools/src/main/res/layout/tools_annot_tool_bar.xml

@@ -30,6 +30,7 @@
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintHorizontal_bias="1"
         app:layout_constraintStart_toEndOf="@id/rv_annotation"
+        android:paddingHorizontal="4dp"
         app:layout_constraintTop_toTopOf="parent">
 
 

+ 17 - 0
compdfkit-tools/src/main/res/layout/tools_color_pick_fragment.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+
+    <com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget.ColorPickerView
+        android:id="@+id/color_picker_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 61 - 0
compdfkit-tools/src/main/res/layout/tools_color_pick_view.xml

@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingBottom="20dp"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+
+    <com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget.ColorRectShowView
+        android:id="@+id/id_bottom_customize_cv_indicator"
+        android:layout_width="30dp"
+        android:layout_height="60dp"
+        android:layout_marginStart="20dp"
+        android:layout_marginTop="20dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget.ColorRectShowView
+        android:id="@+id/id_bottom_customize_cv_last"
+        android:layout_width="30dp"
+        android:layout_height="60dp"
+        android:layout_marginTop="5dp"
+        app:layout_constraintStart_toStartOf="@+id/id_bottom_customize_cv_indicator"
+        app:layout_constraintEnd_toEndOf="@+id/id_bottom_customize_cv_indicator"
+        app:layout_constraintTop_toBottomOf="@+id/id_bottom_customize_cv_indicator" />
+
+    <com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget.ColorRectView
+        android:id="@+id/id_bottom_customize_v_color_set"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_marginStart="10dp"
+        android:layout_marginEnd="20dp"
+        app:layout_constraintBottom_toBottomOf="@+id/id_bottom_customize_cv_last"
+        app:layout_constraintStart_toEndOf="@+id/id_bottom_customize_cv_indicator"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/id_bottom_customize_cv_indicator" />
+
+    <com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget.ColorSliderView
+        android:id="@+id/id_customize_color_slider"
+        android:layout_width="0dp"
+        android:layout_height="30dp"
+        android:layout_marginStart="20dp"
+        android:layout_marginTop="20dp"
+        android:layout_marginEnd="20dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/id_bottom_customize_v_color_set" />
+
+    <com.compdfkit.tools.common.views.pdfproperties.colorpicker.widget.ColorAlphaSliderView
+        android:id="@+id/id_customize_color_alpha_slider"
+        android:layout_width="0dp"
+        android:layout_height="30dp"
+        android:layout_marginStart="20dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginEnd="20dp"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/id_customize_color_slider" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 3 - 2
compdfkit-tools/src/main/res/layout/tools_properties_markup_style_fragment.xml

@@ -23,10 +23,11 @@
         app:layout_constraintTop_toBottomOf="@id/iv_markup_sample" />
 
     <com.compdfkit.tools.common.views.pdfproperties.sliderbar.CSliderBar
+        android:id="@+id/slider_bar"
         android:layout_width="match_parent"
-        app:tools_slider_bar_value_show_type="percentage"
+        android:layout_height="wrap_content"
         android:max="255"
         app:layout_constraintTop_toBottomOf="@id/color_list_view"
-        android:layout_height="wrap_content"/>
+        app:tools_slider_bar_value_show_type="percentage" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 26 - 0
compdfkit-tools/src/main/res/layout/tools_properties_note_style_fragment.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingBottom="16dp">
+
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/iv_markup_sample"
+        android:layout_width="match_parent"
+        android:layout_height="80dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+
+    <com.compdfkit.tools.common.views.pdfproperties.colorlist.CColorListView
+        android:id="@+id/color_list_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/iv_markup_sample" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 1
viewer-ctrl-demo/src/main/res/menu/viewer_pdf_more.xml

@@ -2,7 +2,7 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
 
     <item
-        android:id="@+id/menu_id_more"
+        android:id="@+id/menu_id_document_info"
         android:title="@string/tools_document_info" />
     <item
         android:id="@+id/menu_id_reader_settings"

+ 1 - 0
compdfkit-tools/src/main/res/values/tools_attrs.xml

@@ -27,6 +27,7 @@
         <attr name="tools_slider_bar_thumbnail_height" format="dimension"/>
         <attr name="tools_slider_bar_icon" format="reference"/>
         <attr name="tools_enable_page_indicator" format="boolean"/>
+        <attr name="tools_page_indicator_margin_bottom" format="dimension"/>
     </declare-styleable>
 
     <declare-styleable name="CColorListView" tools:ignore="ResourceName">

+ 4 - 1
compdfkit-tools/src/main/res/values/tools_strings.xml

@@ -12,6 +12,8 @@
 
     <string name="tools_thumbnail">Thumbnail</string>
     <string name="tools_outline">Outline</string>
+    <string name="tools_bookmarks">Bookmarks</string>
+    <string name="tools_annotations">Annotations</string>
     <string name="tools_more">More</string>
     <string name="tools_document_info">Document Info</string>
     <string name="tools_reader_settings">Reader Settings</string>
@@ -68,12 +70,13 @@
     <string name="tools_annot_underline">Underline</string>
     <string name="tools_annot_strikeout">StrikeOut</string>
     <string name="tools_annot_squiggly">Squiggly</string>
+    <string name="tools_annot_note">Note</string>
 
     <string name="tools_menu_pdfview">PDFView</string>
     <string name="tools_menu_annotation">Annotation</string>
     <string name="tools_menu_edit">Edit</string>
     <string name="tools_menu_form">Form</string>
     <string name="tools_menu_page_edit">PageEdit</string>
-
+    <string name="tools_custom_color">Custom Color</string>
 
 </resources>

+ 2 - 0
compdfkit-tools/src/main/res/values/tools_styles.xml

@@ -81,6 +81,8 @@
 
     <style name="tools_bottom_sheet_style_wrapper" parent="Widget.Design.BottomSheet.Modal">
         <item name="android:background">@android:color/transparent</item>
+        <item name="android:maxWidth">@dimen/material_bottom_sheet_max_width</item>
+
     </style>
 
 

+ 11 - 18
viewer-ctrl-demo/src/main/java/com/compdfkit/demo/viewer/PDFViewerSampleActivity.java

@@ -18,6 +18,7 @@ import androidx.appcompat.widget.PopupMenu;
 import com.compdfkit.demo.viewer.databinding.ViewerPdfSampleActivityBinding;
 import com.compdfkit.tools.common.utils.task.CExtractAssetFileTask;
 import com.compdfkit.tools.common.utils.animation.CFillScreenManager;
+import com.compdfkit.tools.common.views.CPDFToolBar;
 import com.compdfkit.tools.common.views.pdfbota.CPDFBOTA;
 import com.compdfkit.tools.common.views.pdfbota.CPDFBotaDialogFragment;
 import com.compdfkit.tools.common.views.pdfbota.CPDFBotaFragmentTabs;
@@ -87,24 +88,16 @@ public class PDFViewerSampleActivity extends AppCompatActivity {
             botaDialogFragment.setBotaDialogTabs(tabs);
             botaDialogFragment.show(getSupportFragmentManager(), "boTaDialogFragment");
         });
-
-        binding.pdfToolBar.setMoreBtnClickListener(v -> {
-            //Show the PDF settings dialog fragment
-            PopupMenu popupMenu = new PopupMenu(this, v);
-            popupMenu.inflate(R.menu.viewer_pdf_more);
-            popupMenu.setOnMenuItemClickListener(item -> {
-                if (item.getItemId() == R.id.menu_id_more){
-                    CPDFDocumentInfoDialogFragment infoDialogFragment = CPDFDocumentInfoDialogFragment.newInstance();
-                    infoDialogFragment.initWithPDFView(binding.pdfView);
-                    infoDialogFragment.show(getSupportFragmentManager(), "documentInfoDialogFragment");
-                } else if (item.getItemId() == R.id.menu_id_reader_settings) {
-                    CPDFDisplaySettingDialogFragment displaySettingDialogFragment =  CPDFDisplaySettingDialogFragment.newInstance();
-                    displaySettingDialogFragment.initWithPDFView(binding.pdfView);
-                    displaySettingDialogFragment.show(getSupportFragmentManager(), "displaySettingsDialog");
-                }
-                return true;
-            });
-            popupMenu.show();
+        binding.pdfToolBar.setMoreMenuListener(menu -> {
+            if (menu == CPDFToolBar.MoreMenu.DocumentInfo){
+                CPDFDocumentInfoDialogFragment infoDialogFragment = CPDFDocumentInfoDialogFragment.newInstance();
+                infoDialogFragment.initWithPDFView(binding.pdfView);
+                infoDialogFragment.show(getSupportFragmentManager(), "documentInfoDialogFragment");
+            }else {
+                CPDFDisplaySettingDialogFragment displaySettingDialogFragment =  CPDFDisplaySettingDialogFragment.newInstance();
+                displaySettingDialogFragment.initWithPDFView(binding.pdfView);
+                displaySettingDialogFragment.show(getSupportFragmentManager(), "displaySettingsDialog");
+            }
         });
     }