Просмотр исходного кода

Implement annotation functions

Highllight
Strik
Underlin
Ink
Wayne 5 лет назад
Родитель
Сommit
f744533a1f
42 измененных файлов с 979 добавлено и 7 удалено
  1. 130 7
      reader/src/main/java/com/kdanmobile/reader/ReaderActivity.kt
  2. 52 0
      reader/src/main/java/com/kdanmobile/reader/ReaderViewModel.kt
  3. 10 0
      reader/src/main/java/com/kdanmobile/reader/Utils.kt
  4. 5 0
      reader/src/main/java/com/kdanmobile/reader/annotationattribute/AnnotationAttribute.kt
  5. 9 0
      reader/src/main/java/com/kdanmobile/reader/annotationattribute/InkAttribute.kt
  6. 265 0
      reader/src/main/java/com/kdanmobile/reader/view/AnnotationPropertySettingView.kt
  7. 23 0
      reader/src/main/java/com/kdanmobile/reader/view/AnnotationPropertySettingWindow.kt
  8. 30 0
      reader/src/main/java/com/kdanmobile/reader/view/ColorOpacityDisplayerView.kt
  9. 82 0
      reader/src/main/java/com/kdanmobile/reader/view/WaveLineView.java
  10. BIN
      reader/src/main/res/drawable-hdpi/ic_freehand_triangle.png
  11. BIN
      reader/src/main/res/drawable-hdpi/panel_property_color_preview.png
  12. BIN
      reader/src/main/res/drawable-xhdpi/panel_property_color_preview.png
  13. 5 0
      reader/src/main/res/drawable-xxhdpi/bg_annotation_property_setting_window.xml
  14. BIN
      reader/src/main/res/drawable-xxhdpi/ic_freehand_triangle.png
  15. BIN
      reader/src/main/res/drawable-xxhdpi/seekbar_back.png
  16. BIN
      reader/src/main/res/drawable-xxhdpi/seekbar_fill.png
  17. BIN
      reader/src/main/res/drawable-xxhdpi/seekbar_handle_small_d.png
  18. BIN
      reader/src/main/res/drawable-xxhdpi/seekbar_handle_small_disable.png
  19. BIN
      reader/src/main/res/drawable-xxhdpi/seekbar_handle_small_p.png
  20. 12 0
      reader/src/main/res/drawable-xxhdpi/seekbar_img.xml
  21. 13 0
      reader/src/main/res/drawable-xxhdpi/seekbar_thumb_ttpod_small.xml
  22. BIN
      reader/src/main/res/drawable/ink_brush_1.png
  23. BIN
      reader/src/main/res/drawable/ink_brush_2.png
  24. BIN
      reader/src/main/res/drawable/panel_property_color_previewbg.png
  25. 11 0
      reader/src/main/res/drawable/reader_annotation_property_color_border.xml
  26. 11 0
      reader/src/main/res/drawable/reader_annotation_property_color_border_select.xml
  27. 42 0
      reader/src/main/res/layout/view_color_opacity_displayer.xml
  28. 231 0
      reader/src/main/res/layout/view_reader_annotation_property.xml
  29. 2 0
      reader/src/main/res/values-de/strings.xml
  30. 2 0
      reader/src/main/res/values-es/strings.xml
  31. 2 0
      reader/src/main/res/values-fr/strings.xml
  32. 2 0
      reader/src/main/res/values-it/strings.xml
  33. 2 0
      reader/src/main/res/values-ja/strings.xml
  34. 2 0
      reader/src/main/res/values-ko/strings.xml
  35. 2 0
      reader/src/main/res/values-pt/strings.xml
  36. 2 0
      reader/src/main/res/values-ru/strings.xml
  37. 2 0
      reader/src/main/res/values-zh-rTW/strings.xml
  38. 2 0
      reader/src/main/res/values-zh/strings.xml
  39. 11 0
      reader/src/main/res/values/colors.xml
  40. 8 0
      reader/src/main/res/values/dimens.xml
  41. 3 0
      reader/src/main/res/values/strings.xml
  42. 6 0
      reader/src/main/res/values/styles.xml

+ 130 - 7
reader/src/main/java/com/kdanmobile/reader/ReaderActivity.kt

@@ -8,12 +8,13 @@ import android.os.Build
 import android.support.v7.app.AppCompatActivity
 import android.os.Bundle
 import android.support.constraint.ConstraintSet
-import android.view.Menu
-import android.view.MotionEvent
-import android.view.View
+import android.view.*
+import android.widget.PopupWindow
 import android.widget.Toast
 import com.kdanmobile.kmpdfkit.pdfcommon.KMPDFReaderView
 import com.kdanmobile.reader.Utils.applyConstraintSet
+import com.kdanmobile.reader.view.AnnotationPropertySettingView
+import com.kdanmobile.reader.view.AnnotationPropertySettingWindow
 import kotlinx.android.synthetic.main.activity_reader.*
 import kotlin.Exception
 
@@ -43,6 +44,10 @@ open class ReaderActivity : AppCompatActivity() {
         viewModel.fileNameLiveData.observe(this, Observer { tv_readerActivity_title.text = it })
         viewModel.annotationModeLiveData.observe(this, Observer(this::onAnnotationModeUpdate))
         viewModel.isCopyModeLiveData.observe(this, Observer (this::onIsCopyModeUpdate))
+        viewModel.highLightAttributeLiveData.observe(this, Observer {
+            if (it == null) return@Observer
+            view_readerActivity_highLightStroke.setBackgroundColor(it.color)
+        })
         viewModel.isOpenedFileLiveData.value?.also { isOpened ->
             if (isOpened) return@also
             val filePath = intent.getStringExtra(KEY_FILE_ABSOLUTE)
@@ -198,9 +203,127 @@ open class ReaderActivity : AppCompatActivity() {
 
     private fun setupRightToolbar() {
         iv_readerActivity_copy.setOnClickListener { viewModel.onClickCopyBtn() }
-        iv_readerActivity_highLight.setOnClickListener { viewModel.onClickHighlightBtn() }
-        iv_readerActivity_strike.setOnClickListener { viewModel.onClickStrikeBtn() }
-        iv_readerActivity_underline.setOnClickListener { viewModel.onClickUnderlineBtn() }
-        iv_readerActivity_ink.setOnClickListener { viewModel.onClickInkBtn() }
+        iv_readerActivity_highLight.apply {
+            setOnClickListener { viewModel.onClickHighlightBtn() }
+            setOnLongClickListener { btn ->
+                viewModel.onLongClickHighlightBtn()
+                val context = this@ReaderActivity
+                AnnotationPropertySettingWindow(context, true).also { window ->
+                    viewModel.highLightAttributeLiveData.value?.let { attr ->
+                        window.annotationPropertySettingView.color = attr.color
+                        window.annotationPropertySettingView.alpha = attr.alpha
+                    }
+                    window.annotationPropertySettingView.onPropertyChangeListener = object : AnnotationPropertySettingView.OnPropertyChangeListener {
+                        override fun onPropertyChange(annotationPropertySettingView: AnnotationPropertySettingView) {
+                            val color = annotationPropertySettingView.color
+                            val alpha = annotationPropertySettingView.alpha
+                            viewModel.setHighLightAttributes(color, alpha)
+                        }
+                    }
+                    val contentView = window.contentView.apply {
+                        val w = Utils.makeDropDownMeasureSpec(window.width)
+                        val y = Utils.makeDropDownMeasureSpec(window.height)
+                        measure(w, y)
+                    }
+                    val space = resources.getDimension(R.dimen.reader_annotation_property_setting_window_right_toolbar_space)
+                    val xOff = (-contentView.measuredWidth - space).toInt()
+                    val yOff = -btn.height
+                    window.showAsDropDown(btn, xOff, yOff)
+                }
+                return@setOnLongClickListener true
+            }
+        }
+        iv_readerActivity_strike.apply {
+            setOnClickListener { viewModel.onClickStrikeBtn() }
+            setOnLongClickListener { btn ->
+                viewModel.onLongClickStrikeBtn()
+                val context = this@ReaderActivity
+                AnnotationPropertySettingWindow(context, true).also { window ->
+                    viewModel.strikeAttributeLiveData.value?.let { attr ->
+                        window.annotationPropertySettingView.color = attr.color
+                        window.annotationPropertySettingView.alpha = attr.alpha
+                    }
+                    window.annotationPropertySettingView.onPropertyChangeListener = object : AnnotationPropertySettingView.OnPropertyChangeListener {
+                        override fun onPropertyChange(annotationPropertySettingView: AnnotationPropertySettingView) {
+                            val color = annotationPropertySettingView.color
+                            val alpha = annotationPropertySettingView.alpha
+                            viewModel.setStrikeOutAttributes(color, alpha)
+                        }
+                    }
+                    val contentView = window.contentView.apply {
+                        val w = Utils.makeDropDownMeasureSpec(window.width)
+                        val y = Utils.makeDropDownMeasureSpec(window.height)
+                        measure(w, y)
+                    }
+                    val space = resources.getDimension(R.dimen.reader_annotation_property_setting_window_right_toolbar_space)
+                    val xOff = (-contentView.measuredWidth - space).toInt()
+                    val yOff = -btn.height
+                    window.showAsDropDown(btn, xOff, yOff)
+                }
+                return@setOnLongClickListener true
+            }
+        }
+        iv_readerActivity_underline.apply {
+            setOnClickListener { viewModel.onClickUnderlineBtn() }
+            setOnLongClickListener { btn ->
+                viewModel.onLongClickUnderlinBtn()
+                val context = this@ReaderActivity
+                AnnotationPropertySettingWindow(context, true).also { window ->
+                    viewModel.underLineAttributeLiveData.value?.let {  attr ->
+                        window.annotationPropertySettingView.color = attr.color
+                        window.annotationPropertySettingView.alpha = attr.alpha
+                    }
+                    window.annotationPropertySettingView.onPropertyChangeListener = object : AnnotationPropertySettingView.OnPropertyChangeListener {
+                        override fun onPropertyChange(annotationPropertySettingView: AnnotationPropertySettingView) {
+                            val color = annotationPropertySettingView.color
+                            val alpha = annotationPropertySettingView.alpha
+                            viewModel.setUnderLineAttributes(color, alpha)
+                        }
+                    }
+                    val contentView = window.contentView.apply {
+                        val w = Utils.makeDropDownMeasureSpec(window.width)
+                        val y = Utils.makeDropDownMeasureSpec(window.height)
+                        measure(w, y)
+                    }
+                    val space = resources.getDimension(R.dimen.reader_annotation_property_setting_window_right_toolbar_space)
+                    val xOff = (-contentView.measuredWidth - space).toInt()
+                    val yOff = -btn.height
+                    window.showAsDropDown(btn, xOff, yOff)
+                }
+                return@setOnLongClickListener true
+            }
+        }
+        iv_readerActivity_ink.apply {
+            setOnClickListener { viewModel.onClickInkBtn() }
+            setOnLongClickListener { btn ->
+                viewModel.onLongClickInkBtn()
+                val context = this@ReaderActivity
+                AnnotationPropertySettingWindow(context, false).also { window ->
+                    viewModel.inkAttributeLiveData.value?.let { attr ->
+                        window.annotationPropertySettingView.color = attr.color
+                        window.annotationPropertySettingView.thickness = attr.width.toInt()
+                        window.annotationPropertySettingView.alpha = attr.alpha
+                    }
+                    window.annotationPropertySettingView.onPropertyChangeListener = object : AnnotationPropertySettingView.OnPropertyChangeListener {
+                        override fun onPropertyChange(annotationPropertySettingView: AnnotationPropertySettingView) {
+                            val color = annotationPropertySettingView.color
+                            val alpha = annotationPropertySettingView.alpha
+                            val thickness = (annotationPropertySettingView.thickness).toFloat()
+                            viewModel.setInkAttributes(color, alpha, thickness)
+                        }
+                    }
+                    val contentView = window.contentView.apply {
+                        val w = Utils.makeDropDownMeasureSpec(window.width)
+                        val y = Utils.makeDropDownMeasureSpec(window.height)
+                        measure(w, y)
+                    }
+                    val space = resources.getDimension(R.dimen.reader_annotation_property_setting_window_right_toolbar_space)
+                    val xOff = (-contentView.measuredWidth - space).toInt()
+                    val yOff = -contentView.measuredHeight
+                    window.showAsDropDown(btn, xOff, yOff)
+                }
+                return@setOnLongClickListener true
+            }
+        }
     }
 }

+ 52 - 0
reader/src/main/java/com/kdanmobile/reader/ReaderViewModel.kt

@@ -3,14 +3,18 @@ package com.kdanmobile.reader
 import android.arch.lifecycle.MutableLiveData
 import android.arch.lifecycle.ViewModel
 import android.content.Context
+import android.graphics.Color
 import android.net.Uri
 import com.kdanmobile.kmpdfkit.annotation.bean.*
 import com.kdanmobile.kmpdfkit.globaldata.Config
 import com.kdanmobile.kmpdfkit.manager.KMPDFFactory
 import com.kdanmobile.kmpdfkit.manager.controller.KMPDFDocumentController
 import com.kdanmobile.kmpdfkit.pdfcommon.KMPDFReaderView
+import com.kdanmobile.reader.annotationattribute.AnnotationAttribute
+import com.kdanmobile.reader.annotationattribute.InkAttribute
 
 class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMsg: String) : ViewModel() {
+
     enum class ViewDirection(val mode: Config.PDFViewMode) {
         VerticalSinglePageContinues(Config.PDFViewMode.VERTICAL_SINGLE_PAGE_CONTINUES),
         VerticalSinglePage(Config.PDFViewMode.VERTICAL_SINGLE_PAGE),
@@ -25,6 +29,18 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
         Ink,
     }
 
+    companion object {
+        val DEFAULT_HIGHLIGHT_COLOR = Color.parseColor("#ffdc1b")
+        val DEFAULT_STRIKE_COLOR = Color.parseColor("#dd0202")
+        val DEFAULT_UNDERLINE_COLOR = Color.parseColor("#dd0202")
+        val DEFAULT_INK_COLOR = Color.parseColor("#dd0202")
+        const val DEFAULT_HIGHLIGHT_ALPHA = 127
+        const val DEFAULT_STRIKE_ALPHA = 255
+        const val DEFAULT_UNDERLINE_ALPHA = 255
+        const val DEFAULT_INK_ALPHA = 255
+        const val DEFAULT_INK_WIDTH = 1f
+    }
+
     var viewDirection = ViewDirection.VerticalSinglePageContinues
         set(value) {
             field = value
@@ -35,6 +51,18 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
             field = value
             updateCrop()
         }
+    val highLightAttributeLiveData = MutableLiveData<AnnotationAttribute>().apply {
+        value = AnnotationAttribute(DEFAULT_HIGHLIGHT_COLOR, DEFAULT_HIGHLIGHT_ALPHA)
+    }
+    val strikeAttributeLiveData = MutableLiveData<AnnotationAttribute>().apply {
+        value = AnnotationAttribute(DEFAULT_STRIKE_COLOR, DEFAULT_STRIKE_ALPHA)
+    }
+    var underLineAttributeLiveData = MutableLiveData<AnnotationAttribute>().apply {
+        value = AnnotationAttribute(DEFAULT_UNDERLINE_COLOR, DEFAULT_UNDERLINE_ALPHA)
+    }
+    var inkAttributeLiveData = MutableLiveData<InkAttribute>().apply {
+        value = InkAttribute(DEFAULT_INK_COLOR, DEFAULT_INK_ALPHA, DEFAULT_INK_WIDTH)
+    }
 
     private var isVerified = false
 
@@ -99,6 +127,11 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
         }
     }
 
+    fun onLongClickHighlightBtn() {
+        if (isCopyModeLiveData.value == true) stopCopyTextMode()
+        startHighLightEditMode()
+    }
+
     fun onClickStrikeBtn() {
         if (isCopyModeLiveData.value == true) stopCopyTextMode()
         if (annotationModeLiveData.value == AnnotationMode.Strike) {
@@ -108,6 +141,11 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
         }
     }
 
+    fun onLongClickStrikeBtn() {
+        if (isCopyModeLiveData.value == true) stopCopyTextMode()
+        startStrikeOutEditMode()
+    }
+
     fun onClickUnderlineBtn() {
         if (isCopyModeLiveData.value == true) stopCopyTextMode()
         if (annotationModeLiveData.value == AnnotationMode.Underline) {
@@ -117,6 +155,11 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
         }
     }
 
+    fun onLongClickUnderlinBtn() {
+        if (isCopyModeLiveData.value == true) stopCopyTextMode()
+        startUnderLineEditMode()
+    }
+
     fun onClickInkBtn() {
         if (isCopyModeLiveData.value == true) stopCopyTextMode()
         if (annotationModeLiveData.value == AnnotationMode.Ink) {
@@ -126,6 +169,11 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
         }
     }
 
+    fun onLongClickInkBtn() {
+        if (isCopyModeLiveData.value == true) stopCopyTextMode()
+        startInkEditMode()
+    }
+
     private fun startCopyTextMode() {
         kmpdfDocumentController?.startCopyText()
         isCopyModeLiveData.postValue(true)
@@ -137,6 +185,7 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
     }
 
     fun setHighLightAttributes(color: Int, alpha: Int) {
+        highLightAttributeLiveData.postValue(AnnotationAttribute(color, alpha))
         kmpdfFactory?.setAnnotationAttribute(KMPDFHighlightAnnotationBean("", color, alpha))
         kmpdfFactory?.annotConfig?.apply {
             markerPenColor_hightlight = color
@@ -150,6 +199,7 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
     }
 
     fun setStrikeOutAttributes(color: Int, alpha: Int) {
+        strikeAttributeLiveData.postValue(AnnotationAttribute(color, alpha))
         kmpdfFactory?.setAnnotationAttribute(KMPDFStrikeoutAnnotationBean("", color, alpha))
         kmpdfFactory?.annotConfig?.apply {
             markerPenColor_strikeout = color
@@ -163,6 +213,7 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
     }
 
     fun setUnderLineAttributes(color: Int, alpha: Int) {
+        underLineAttributeLiveData.postValue(AnnotationAttribute(color, alpha))
         kmpdfFactory?.setAnnotationAttribute(KMPDFUnderlineAnnotationBean("", color, alpha))
         kmpdfFactory?.annotConfig?.apply {
             markerPenColor_underline = color
@@ -176,6 +227,7 @@ class ReaderViewModel(private val pdfSdkLicense: String, private val pdfSdkRsaMs
     }
 
     fun setInkAttributes(color: Int, alpha: Int, width: Float) {
+        inkAttributeLiveData.postValue(InkAttribute(color, alpha, width))
         kmpdfFactory?.apply {
             setAnnotationAttribute(KMPDFInkAnnotationBean("", color, width, alpha))
             annotConfig?.apply {

+ 10 - 0
reader/src/main/java/com/kdanmobile/reader/Utils.kt

@@ -14,6 +14,7 @@ import android.support.v7.widget.AppCompatImageButton
 import android.support.v7.widget.AppCompatImageView
 import android.transition.TransitionManager
 import android.view.View
+import android.view.ViewGroup
 import android.widget.ImageView
 
 object Utils {
@@ -65,4 +66,13 @@ object Utils {
         constraintSet.clone(context, layoutResId)
         this.applyConstraintSet(constraintSet)
     }
+
+    fun makeDropDownMeasureSpec(measureSpec: Int): Int {
+        val mode = if (measureSpec == ViewGroup.LayoutParams.WRAP_CONTENT) {
+            View.MeasureSpec.UNSPECIFIED
+        } else {
+            View.MeasureSpec.EXACTLY
+        }
+        return View.MeasureSpec.makeMeasureSpec(View.MeasureSpec.getSize(measureSpec), mode)
+    }
 }

+ 5 - 0
reader/src/main/java/com/kdanmobile/reader/annotationattribute/AnnotationAttribute.kt

@@ -0,0 +1,5 @@
+package com.kdanmobile.reader.annotationattribute
+
+import android.support.annotation.IntRange
+
+open class AnnotationAttribute(open var color: Int, @IntRange(from = 0, to = 255) open var alpha: Int)

+ 9 - 0
reader/src/main/java/com/kdanmobile/reader/annotationattribute/InkAttribute.kt

@@ -0,0 +1,9 @@
+package com.kdanmobile.reader.annotationattribute
+
+import android.support.annotation.IntRange
+import com.kdanmobile.reader.annotationattribute.AnnotationAttribute
+
+data class InkAttribute(
+        override var color: Int,
+        @IntRange(from = 0, to = 255) override var alpha: Int,
+        var width: Float) : AnnotationAttribute(color, alpha)

+ 265 - 0
reader/src/main/java/com/kdanmobile/reader/view/AnnotationPropertySettingView.kt

@@ -0,0 +1,265 @@
+package com.kdanmobile.reader.view
+
+import android.content.Context
+import android.support.annotation.IntRange
+import android.support.v4.graphics.ColorUtils
+import android.util.AttributeSet
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.PopupWindow
+import android.widget.SeekBar
+import com.kdanmobile.reader.R
+import com.kdanmobile.reader.Utils
+import kotlinx.android.synthetic.main.view_reader_annotation_property.view.*
+
+class AnnotationPropertySettingView @JvmOverloads constructor(
+        context: Context,
+        attrs: AttributeSet? = null,
+        defStyleAttr: Int = 0
+) : LinearLayout(context, attrs, defStyleAttr) {
+
+    companion object {
+        const val BRUSH_DEFAULT_THICKNESS_FOUNTAIN = 5
+        const val BRUSH_DEFAULT_THICKNESS_MARKER = 16
+        const val DEFAULT_OPACITY = 50
+        const val DEFAULT_THICKNESS = 5
+    }
+
+    enum class Brush(val size: Int) {
+        Fountain(BRUSH_DEFAULT_THICKNESS_FOUNTAIN),
+        Marker(BRUSH_DEFAULT_THICKNESS_MARKER),
+    }
+
+    private enum class Color(val colorResId: Int) {
+        Color1(R.color.reader_annotation_color_1),
+        Color2(R.color.reader_annotation_color_2),
+        Color3(R.color.reader_annotation_color_3),
+        Color4(R.color.reader_annotation_color_4),
+        Color5(R.color.reader_annotation_color_5),
+        Color6(R.color.reader_annotation_color_6),
+        Color7(R.color.reader_annotation_color_7),
+        Color8(R.color.reader_annotation_color_8),
+        Color9(R.color.reader_annotation_color_9),
+        Color10(R.color.reader_annotation_color_10),
+    }
+
+    init {
+        inflate(context, R.layout.view_reader_annotation_property, this)
+    }
+    var isSimpleMode = true
+        set(value) {
+            field = value
+            update()
+        }
+    var onPropertyChangeListener: OnPropertyChangeListener? = null
+    private val colorBtnMap = HashMap<Color, ImageView>().apply {
+        put(Color.Color1, iv_readerAnnotationProperty_color1)
+        put(Color.Color2, iv_readerAnnotationProperty_color2)
+        put(Color.Color3, iv_readerAnnotationProperty_color3)
+        put(Color.Color4, iv_readerAnnotationProperty_color4)
+        put(Color.Color5, iv_readerAnnotationProperty_color5)
+        put(Color.Color6, iv_readerAnnotationProperty_color6)
+        put(Color.Color7, iv_readerAnnotationProperty_color7)
+        put(Color.Color8, iv_readerAnnotationProperty_color8)
+        put(Color.Color9, iv_readerAnnotationProperty_color9)
+        put(Color.Color10, iv_readerAnnotationProperty_color10)
+    }
+    var thickness: Int = DEFAULT_THICKNESS
+        set(value) {
+            field = value
+            updateThickness()
+        }
+    /**
+     * 1~255
+     */
+    var alpha: Int
+        get() {
+            return Math.round(opacity.toFloat() / 100 * 255)
+        }
+        set(value) {
+            val progress = Math.round(value.toFloat() / 255 * 100)
+            seekBar_readerAnnotationProperty_opacity.progress = progress
+        }
+    /**
+     * 1~100
+     */
+    var opacity: Int = DEFAULT_OPACITY
+        private set
+    var color: Int
+        get() {
+            return context.resources.getColor(colorEnum.colorResId)
+        }
+        set(value) {
+            Color.values().forEach {
+                val c = context.resources.getColor(it.colorResId)
+                if (c == value) {
+                    colorEnum = it
+                    return
+                }
+            }
+        }
+    private var colorEnum: Color = Color.Color1
+        set(value) {
+            field = value
+            updateColor()
+            updateColorButtons()
+            onPropertyChangeListener?.onPropertyChange(this)
+        }
+    val colorWithAlpha: Int
+        get() {
+            return  ColorUtils.setAlphaComponent(color, alpha)
+        }
+    var brush = Brush.Fountain
+        set(value) {
+            if (field == value) return
+            field = value
+            thickness = brush.size
+            update()
+        }
+    init {
+        setupOpacitySeekBar()
+        setupThicknessSeekBar()
+        setupColorButtons()
+        setupBrushes()
+        update()
+    }
+
+    private fun setupBrushes() {
+        iv_readerAnnotationProperty_brush1.setOnClickListener {
+            brush = Brush.Fountain
+        }
+        iv_readerAnnotationProperty_brush2.setOnClickListener {
+            brush = Brush.Marker
+        }
+    }
+
+    private fun setupThicknessSeekBar() {
+        seekBar_readerAnnotationProperty_thickness.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+            override fun onProgressChanged(p0: SeekBar?, progress: Int, p2: Boolean) {
+                thickness = progress
+                updateThickness()
+            }
+
+            override fun onStartTrackingTouch(p0: SeekBar?) {
+            }
+
+            override fun onStopTrackingTouch(p0: SeekBar?) {
+                onPropertyChangeListener?.onPropertyChange(this@AnnotationPropertySettingView)
+            }
+        })
+    }
+
+    private fun setupColorButtons() {
+        colorBtnMap.values.forEach {
+            it.setOnClickListener(this::onClickColorBtn)
+        }
+    }
+
+    private fun setupOpacitySeekBar() {
+        seekBar_readerAnnotationProperty_opacity.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
+            val colorDisplayerView = ColorOpacityDisplayerView(context)
+            val windowW = ViewGroup.LayoutParams.WRAP_CONTENT
+            val windowH = ViewGroup.LayoutParams.WRAP_CONTENT
+            val window = PopupWindow(colorDisplayerView, windowW, windowH).apply {
+                animationStyle = android.R.style.Animation
+            }
+            val contentView = window.contentView.apply {
+                val w = Utils.makeDropDownMeasureSpec(window.width)
+                val h = Utils.makeDropDownMeasureSpec(window.height)
+                measure(w, h)
+            }
+
+            override fun onProgressChanged(seekBar: SeekBar, progress: Int, p2: Boolean) {
+                opacity = progress
+                val x = calculateOffsetX(seekBar)
+                val y = calculateOffsetY(seekBar)
+                window.update(seekBar, x, y, window.width, window.height)
+                updateOpacity()
+                colorDisplayerView.color = colorWithAlpha
+            }
+
+            override fun onStartTrackingTouch(seekBar: SeekBar) {
+                val x = calculateOffsetX(seekBar)
+                val y = calculateOffsetY(seekBar)
+                colorDisplayerView.color = colorWithAlpha
+                window.showAsDropDown(seekBar, x, y)
+            }
+
+            override fun onStopTrackingTouch(p0: SeekBar?) {
+                window.dismiss()
+                onPropertyChangeListener?.onPropertyChange(this@AnnotationPropertySettingView)
+            }
+
+            private fun calculateOffsetX(seekBar: SeekBar): Int {
+                val seekBarLineWidth = seekBar.width - seekBar.paddingLeft - seekBar.paddingRight
+                val progress = seekBar.progress.toFloat() / seekBar.max.toFloat()
+                return (seekBar.paddingLeft + seekBarLineWidth * progress - contentView.measuredWidth / 2).toInt()
+            }
+
+            private fun calculateOffsetY(seekBar: SeekBar): Int {
+                return -seekBar.height - contentView.measuredHeight
+            }
+        })
+    }
+
+    private fun onClickColorBtn(view: View) {
+        colorBtnMap.entries.forEach {
+            if (it.value == view) {
+                colorEnum = it.key
+                return
+            }
+        }
+    }
+
+    private fun update() {
+        updateOpacity()
+        updateThickness()
+        updateColor()
+        updateColorButtons()
+        group_readerAnnotationProperty_brushMode.visibility = if (isSimpleMode) View.GONE else View.VISIBLE
+        group_readerAnnotationProperty_brushMode.post {
+            when (brush) {
+                Brush.Fountain -> {
+                    iv_readerAnnotationProperty_triangle1.visibility = View.VISIBLE
+                    iv_readerAnnotationProperty_triangle2.visibility = View.INVISIBLE
+                }
+                Brush.Marker -> {
+                    iv_readerAnnotationProperty_triangle1.visibility = View.INVISIBLE
+                    iv_readerAnnotationProperty_triangle2.visibility = View.VISIBLE
+                }
+            }
+        }
+    }
+
+    private fun updateOpacity() {
+        seekBar_readerAnnotationProperty_opacity.progress = opacity
+        tv_readerAnnotationProperty_opacityValue.text = opacity.toString()
+        waveLineView_readerAnnotationProperty.setColor(colorWithAlpha)
+    }
+
+    private fun updateThickness() {
+        seekBar_readerAnnotationProperty_thickness.progress = thickness
+        tv_readerAnnotationProperty_thicknessValue.text = thickness.toString()
+        waveLineView_readerAnnotationProperty.setThickness(thickness.toFloat())
+    }
+
+    private fun updateColor() {
+        waveLineView_readerAnnotationProperty.setColor(colorWithAlpha)
+    }
+
+    private fun updateColorButtons() {
+        colorBtnMap.entries.forEach {
+            if (it.key == colorEnum) {
+                it.value.setImageResource(R.drawable.reader_annotation_property_color_border_select)
+            } else {
+                it.value.setImageResource(R.drawable.reader_annotation_property_color_border)
+            }
+        }
+    }
+
+    interface OnPropertyChangeListener {
+        fun onPropertyChange(annotationPropertySettingView: AnnotationPropertySettingView)
+    }
+}

+ 23 - 0
reader/src/main/java/com/kdanmobile/reader/view/AnnotationPropertySettingWindow.kt

@@ -0,0 +1,23 @@
+package com.kdanmobile.reader.view
+
+import android.content.Context
+import android.os.Build
+import android.widget.PopupWindow
+import com.kdanmobile.reader.BuildConfig
+import com.kdanmobile.reader.R
+
+class AnnotationPropertySettingWindow(context: Context, isSimpleMode: Boolean) : PopupWindow(context) {
+    val annotationPropertySettingView: AnnotationPropertySettingView
+
+    init {
+        isOutsideTouchable = true
+        isFocusable = true
+        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
+            elevation = context.resources.getDimension(R.dimen.reader_annotation_property_setting_window_elevation)
+        }
+        setBackgroundDrawable(context.resources.getDrawable(R.drawable.bg_annotation_property_setting_window))
+        annotationPropertySettingView = AnnotationPropertySettingView(context)
+        annotationPropertySettingView.isSimpleMode = isSimpleMode
+        contentView = annotationPropertySettingView
+    }
+}

+ 30 - 0
reader/src/main/java/com/kdanmobile/reader/view/ColorOpacityDisplayerView.kt

@@ -0,0 +1,30 @@
+package com.kdanmobile.reader.view
+
+import android.content.Context
+import android.graphics.Color
+import android.support.constraint.ConstraintLayout
+import android.support.v4.graphics.ColorUtils
+import android.util.AttributeSet
+import android.view.View
+import com.kdanmobile.reader.R
+import kotlinx.android.synthetic.main.view_color_opacity_displayer.view.*
+
+class ColorOpacityDisplayerView @JvmOverloads constructor(
+        context: Context,
+        attrs: AttributeSet? = null,
+        defStyleAttr: Int = 0
+) : ConstraintLayout(context, attrs, defStyleAttr) {
+    init {
+        View.inflate(context, R.layout.view_color_opacity_displayer, this)
+    }
+
+    var color = Color.BLACK
+        set(value) {
+            field = value
+            update()
+        }
+
+    private fun update() {
+        view_colorOpacityDisplayer_color.setBackgroundColor(color)
+    }
+}

+ 82 - 0
reader/src/main/java/com/kdanmobile/reader/view/WaveLineView.java

@@ -0,0 +1,82 @@
+package com.kdanmobile.reader.view;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Paint.Cap;
+import android.graphics.Paint.Style;
+import android.graphics.Path;
+import android.support.annotation.NonNull;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * @类名:WaveLineView
+ * @类描述:自定义控件实现波浪线
+ * @作者:zhouguifang
+ * @创建时间:2015-7-7-上午11:35:01
+ * @修改人:
+ * @修改时间:
+ * @修改备注:
+ * @版本:
+ * @Copyright:(c)-2015kdan mobile
+ */
+public class WaveLineView extends View {
+	private Paint paint;
+	private Path path;
+	private int color = 0xffff0000;
+	private float thickness = 20;
+	private float bili = 1.f / 6;
+
+	public WaveLineView(Context context, AttributeSet attrs) {
+		super(context, attrs);
+		paint = new Paint();
+		paint.setColor(color);
+		paint.setAntiAlias(true);
+		paint.setStrokeCap(Cap.ROUND);
+		paint.setStyle(Style.STROKE);
+		paint.setStrokeWidth(20f);
+	}
+
+	public void setThickness(float thickness) {
+		this.thickness = thickness;
+		invalidate();
+	}
+
+	public void setColor(int color) {
+		this.color = color;
+		invalidate();
+	}
+
+	@Override
+	public void draw(@NonNull Canvas canvas) {
+		super.draw(canvas);
+		if (getWidth() > 0) {
+			if (path == null) {
+				int w = getWidth();
+				int h = getHeight();
+				path = new Path();
+				path.moveTo(0, h / 2f);
+				path.lineTo((w * 30) / 360, (h / 2) - (h * bili * 0.5f));
+				path.lineTo((w * 45) / 360, (h / 2) - (h * bili * 0.707f));
+				path.lineTo((w * 60) / 360, (h / 2) - (h * bili * 0.866f));
+				path.lineTo((w * 90) / 360, (h / 2) - (h * bili * 1.0f));
+				path.lineTo((w * 120) / 360, (h / 2) - (h * bili * 0.866f));
+				path.lineTo((w * 135) / 360, (h / 2) - (h * bili * 0.707f));
+				path.lineTo((w * 150) / 360, (h / 2) - (h * bili * 0.5f));
+				path.lineTo((w * 180) / 360, (h / 2) - (h * bili * 0.0f));
+				path.lineTo((w * 210) / 360, (h / 2) + (h * bili * 0.5f));
+				path.lineTo((w * 225) / 360, (h / 2) + (h * bili * 0.707f));
+				path.lineTo((w * 240) / 360, (h / 2) + (h * bili * 0.866f));
+				path.lineTo((w * 270) / 360, (h / 2) + (h * bili * 1.0f));
+				path.lineTo((w * 300) / 360, (h / 2) + (h * bili * 0.866f));
+				path.lineTo((w * 315) / 360, (h / 2) + (h * bili * 0.707f));
+				path.lineTo((w * 330) / 360, (h / 2) + (h * bili * 0.5f));
+				path.lineTo((w * 360) / 360, (h / 2) + (h * bili * 0.0f));
+			}
+			paint.setColor(color);
+			paint.setStrokeWidth(thickness);
+			canvas.drawPath(path, paint);
+		}
+	}
+}

BIN
reader/src/main/res/drawable-hdpi/ic_freehand_triangle.png


BIN
reader/src/main/res/drawable-hdpi/panel_property_color_preview.png


BIN
reader/src/main/res/drawable-xhdpi/panel_property_color_preview.png


+ 5 - 0
reader/src/main/res/drawable-xxhdpi/bg_annotation_property_setting_window.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#f5f5f5"/>
+    <corners android:radius="4dp"/>
+</shape>

BIN
reader/src/main/res/drawable-xxhdpi/ic_freehand_triangle.png


BIN
reader/src/main/res/drawable-xxhdpi/seekbar_back.png


BIN
reader/src/main/res/drawable-xxhdpi/seekbar_fill.png


BIN
reader/src/main/res/drawable-xxhdpi/seekbar_handle_small_d.png


BIN
reader/src/main/res/drawable-xxhdpi/seekbar_handle_small_disable.png


BIN
reader/src/main/res/drawable-xxhdpi/seekbar_handle_small_p.png


+ 12 - 0
reader/src/main/res/drawable-xxhdpi/seekbar_img.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+	<!-- 背景图 -->
+	<item android:id="@android:id/background"
+		  android:drawable="@drawable/seekbar_back" />
+	<!--全部能量图  -->
+	<!-- <item android:id="@+android:id/SecondaryProgress"
+		  android:drawable="@drawable/back" /> -->
+	<!-- 进和能量图 -->
+	<item android:id="@android:id/progress" 
+	      android:drawable="@drawable/seekbar_fill" />
+</layer-list>

+ 13 - 0
reader/src/main/res/drawable-xxhdpi/seekbar_thumb_ttpod_small.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+	<!-- 按下状态 -->
+	<item android:state_pressed="true" android:drawable="@drawable/seekbar_handle_small_p" />
+
+	<!-- 普通无焦点状态 -->
+	<item android:state_enabled="true" android:state_focused="false" android:state_pressed="false"
+		android:drawable="@drawable/seekbar_handle_small_d" />
+
+	<!-- disable状态 -->
+	<item android:state_enabled="false" android:state_focused="false"
+		android:drawable="@drawable/seekbar_handle_small_disable" />
+</selector> 

BIN
reader/src/main/res/drawable/ink_brush_1.png


BIN
reader/src/main/res/drawable/ink_brush_2.png


BIN
reader/src/main/res/drawable/panel_property_color_previewbg.png


+ 11 - 0
reader/src/main/res/drawable/reader_annotation_property_color_border.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle" >
+
+    <stroke
+        android:width="2dp"
+        android:color="#afafaf" />
+
+    <solid android:color="#0000"/>
+    
+</shape>

+ 11 - 0
reader/src/main/res/drawable/reader_annotation_property_color_border_select.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle" >
+
+    <stroke
+        android:width="4dp"
+        android:color="#33b5e5" />
+
+    <solid android:color="#0000"/>
+    
+</shape>

+ 42 - 0
reader/src/main/res/layout/view_color_opacity_displayer.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    tools:parentTag="android.support.constraint.ConstraintLayout"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+    <View
+        android:id="@+id/view_colorOpacityDisplayer_transparentBg"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_marginLeft="8dp"
+        android:layout_marginRight="8dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginBottom="16dp"
+        android:background="@drawable/panel_property_color_previewbg"
+        app:layout_constraintLeft_toLeftOf="@id/view_colorOpacityDisplayer_displayer"
+        app:layout_constraintRight_toRightOf="@id/view_colorOpacityDisplayer_displayer"
+        app:layout_constraintTop_toTopOf="@id/view_colorOpacityDisplayer_displayer"
+        app:layout_constraintBottom_toBottomOf="@id/view_colorOpacityDisplayer_displayer"
+        />
+    <View
+        android:id="@+id/view_colorOpacityDisplayer_color"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:background="#8f00"
+        app:layout_constraintLeft_toLeftOf="@id/view_colorOpacityDisplayer_transparentBg"
+        app:layout_constraintRight_toRightOf="@id/view_colorOpacityDisplayer_transparentBg"
+        app:layout_constraintTop_toTopOf="@id/view_colorOpacityDisplayer_transparentBg"
+        app:layout_constraintBottom_toBottomOf="@id/view_colorOpacityDisplayer_transparentBg"
+        />
+    <View
+        android:id="@+id/view_colorOpacityDisplayer_displayer"
+        android:layout_width="@dimen/reader_color_displayer_width"
+        android:layout_height="@dimen/reader_color_displayer_height"
+        android:background="@drawable/panel_property_color_preview"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        />
+</merge>

+ 231 - 0
reader/src/main/res/layout/view_reader_annotation_property.xml

@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.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="240dp"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <android.support.constraint.Group
+        android:id="@+id/group_readerAnnotationProperty_brushMode"
+        app:constraint_referenced_ids="tv_readerAnnotationProperty_thicknessName, seekBar_readerAnnotationProperty_thickness, tv_readerAnnotationProperty_thicknessValue, waveLineView_readerAnnotationProperty, iv_readerAnnotationProperty_triangle1, iv_readerAnnotationProperty_triangle2, iv_readerAnnotationProperty_brush1, iv_readerAnnotationProperty_brush2"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <com.kdanmobile.reader.view.WaveLineView
+        android:id="@+id/waveLineView_readerAnnotationProperty"
+        android:layout_marginLeft="8dp"
+        android:layout_marginRight="8dp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        android:layout_width="0dp"
+        android:layout_height="60dp" />
+
+    <TextView
+        android:id="@+id/tv_readerAnnotationProperty_thicknessName"
+        android:text="@string/pdfReader_ppw_thickness"
+        android:textSize="16sp"
+        android:layout_marginLeft="8dp"
+        android:layout_marginRight="8dp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="@id/seekBar_readerAnnotationProperty_thickness"
+        app:layout_constraintBottom_toBottomOf="@id/seekBar_readerAnnotationProperty_thickness"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:id="@+id/tv_readerAnnotationProperty_opacityName"
+        android:text="@string/pdfReader_ppw_opacity"
+        android:textSize="16sp"
+        android:layout_marginLeft="8dp"
+        android:layout_marginRight="8dp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintTop_toTopOf="@id/seekBar_readerAnnotationProperty_opacity"
+        app:layout_constraintBottom_toBottomOf="@id/seekBar_readerAnnotationProperty_opacity"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <android.support.constraint.Barrier
+        android:id="@+id/barrier_readerAnnotationProperty_thicknessOpacityText"
+        app:constraint_referenced_ids="tv_readerAnnotationProperty_thicknessName, tv_readerAnnotationProperty_opacityName"
+        app:barrierDirection="right"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <SeekBar
+        android:id="@+id/seekBar_readerAnnotationProperty_thickness"
+        android:layout_marginTop="8dp"
+        app:layout_constraintLeft_toRightOf="@id/barrier_readerAnnotationProperty_thicknessOpacityText"
+        app:layout_constraintRight_toLeftOf="@id/barrier_readerAnnotationProperty_thicknessOpacityValue"
+        app:layout_constraintTop_toBottomOf="@id/waveLineView_readerAnnotationProperty"
+        android:layout_width="0dp"
+        android:layout_height="32dp"
+        android:min="1"
+        android:max="16"
+        android:maxHeight="1dp"
+        android:minHeight="1dp"
+        android:paddingLeft="10dp"
+        android:paddingRight="10dp"
+        android:progress="3"
+        android:progressDrawable="@drawable/seekbar_img"
+        android:scrollbarStyle="insideOverlay"
+        android:thumb="@drawable/seekbar_thumb_ttpod_small"
+        android:thumbOffset="7dp" />
+
+    <SeekBar
+        android:id="@+id/seekBar_readerAnnotationProperty_opacity"
+        android:layout_marginTop="8dp"
+        app:layout_constraintLeft_toRightOf="@id/barrier_readerAnnotationProperty_thicknessOpacityText"
+        app:layout_constraintRight_toLeftOf="@id/barrier_readerAnnotationProperty_thicknessOpacityValue"
+        app:layout_constraintTop_toBottomOf="@id/seekBar_readerAnnotationProperty_thickness"
+        android:layout_width="0dp"
+        android:layout_height="32dp"
+        android:min="1"
+        android:max="100"
+        android:progress="50"
+        android:maxHeight="1dp"
+        android:minHeight="1dp"
+        android:paddingLeft="10dp"
+        android:paddingRight="10dp"
+        android:progressDrawable="@drawable/seekbar_img"
+        android:scrollbarStyle="insideOverlay"
+        android:thumb="@drawable/seekbar_thumb_ttpod_small"
+        />
+
+    <android.support.constraint.Barrier
+        android:id="@+id/barrier_readerAnnotationProperty_thicknessOpacityValue"
+        app:constraint_referenced_ids="tv_readerAnnotationProperty_thicknessValue, tv_readerAnnotationProperty_opacityValue"
+        app:barrierDirection="left"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:id="@+id/tv_readerAnnotationProperty_thicknessValue"
+        tools:text="0"
+        android:textSize="16sp"
+        android:gravity="center"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@id/seekBar_readerAnnotationProperty_thickness"
+        app:layout_constraintBottom_toBottomOf="@id/seekBar_readerAnnotationProperty_thickness"
+        android:layout_marginRight="8dp"
+        android:layout_width="32dp"
+        android:layout_height="wrap_content" />
+
+    <TextView
+        android:id="@+id/tv_readerAnnotationProperty_opacityValue"
+        tools:text="0"
+        android:textSize="16sp"
+        android:gravity="center"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="@id/seekBar_readerAnnotationProperty_opacity"
+        app:layout_constraintBottom_toBottomOf="@id/seekBar_readerAnnotationProperty_opacity"
+        android:layout_marginRight="8dp"
+        android:layout_width="32dp"
+        android:layout_height="wrap_content" />
+
+    <HorizontalScrollView
+        android:id="@+id/viewGroup_readerAnnotationProperty_color"
+        app:layout_constraintTop_toBottomOf="@id/seekBar_readerAnnotationProperty_opacity"
+        android:layout_marginTop="16dp"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content">
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:orientation="horizontal">
+
+            <ImageView
+                style="@style/AnnotationPropertyColorImageView"
+                android:id="@+id/iv_readerAnnotationProperty_color1"
+                android:background="@color/reader_annotation_color_1" />
+
+            <ImageView
+                style="@style/AnnotationPropertyColorImageView"
+                android:id="@+id/iv_readerAnnotationProperty_color2"
+                android:background="@color/reader_annotation_color_2" />
+
+            <ImageView
+                style="@style/AnnotationPropertyColorImageView"
+                android:id="@+id/iv_readerAnnotationProperty_color3"
+                android:background="@color/reader_annotation_color_3" />
+
+            <ImageView
+                style="@style/AnnotationPropertyColorImageView"
+                android:id="@+id/iv_readerAnnotationProperty_color4"
+                android:background="@color/reader_annotation_color_4" />
+
+            <ImageView
+                style="@style/AnnotationPropertyColorImageView"
+                android:id="@+id/iv_readerAnnotationProperty_color5"
+                android:background="@color/reader_annotation_color_5" />
+
+            <ImageView
+                style="@style/AnnotationPropertyColorImageView"
+                android:id="@+id/iv_readerAnnotationProperty_color6"
+                android:background="@color/reader_annotation_color_6" />
+
+            <ImageView
+                style="@style/AnnotationPropertyColorImageView"
+                android:id="@+id/iv_readerAnnotationProperty_color7"
+                android:background="@color/reader_annotation_color_7" />
+
+            <ImageView
+                style="@style/AnnotationPropertyColorImageView"
+                android:id="@+id/iv_readerAnnotationProperty_color8"
+                android:background="@color/reader_annotation_color_8" />
+
+            <ImageView
+                style="@style/AnnotationPropertyColorImageView"
+                android:id="@+id/iv_readerAnnotationProperty_color9"
+                android:background="@color/reader_annotation_color_9" />
+
+            <ImageView
+                style="@style/AnnotationPropertyColorImageView"
+                android:id="@+id/iv_readerAnnotationProperty_color10"
+                android:background="@color/reader_annotation_color_10" />
+        </LinearLayout>
+    </HorizontalScrollView>
+
+    <ImageView
+        android:id="@+id/iv_readerAnnotationProperty_triangle1"
+        android:src="@drawable/ic_freehand_triangle"
+        app:layout_constraintTop_toBottomOf="@id/viewGroup_readerAnnotationProperty_color"
+        app:layout_constraintLeft_toLeftOf="@id/iv_readerAnnotationProperty_brush1"
+        app:layout_constraintRight_toRightOf="@id/iv_readerAnnotationProperty_brush1"
+        android:layout_width="24dp"
+        android:layout_height="24dp"/>
+    <ImageView
+        android:id="@+id/iv_readerAnnotationProperty_brush1"
+        android:src="@drawable/ink_brush_1"
+        android:adjustViewBounds="true"
+        app:layout_constraintTop_toBottomOf="@id/iv_readerAnnotationProperty_triangle1"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toLeftOf="@id/iv_readerAnnotationProperty_brush2"
+        android:layout_marginLeft="8dp"
+        android:layout_marginRight="8dp"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content" />
+    <ImageView
+        android:id="@+id/iv_readerAnnotationProperty_triangle2"
+        android:src="@drawable/ic_freehand_triangle"
+        app:layout_constraintTop_toBottomOf="@id/viewGroup_readerAnnotationProperty_color"
+        app:layout_constraintLeft_toLeftOf="@id/iv_readerAnnotationProperty_brush2"
+        app:layout_constraintRight_toRightOf="@id/iv_readerAnnotationProperty_brush2"
+        android:layout_width="24dp"
+        android:layout_height="24dp" />
+    <ImageView
+        android:id="@+id/iv_readerAnnotationProperty_brush2"
+        android:src="@drawable/ink_brush_2"
+        android:adjustViewBounds="true"
+        app:layout_constraintTop_toTopOf="@id/iv_readerAnnotationProperty_brush1"
+        app:layout_constraintBottom_toBottomOf="@id/iv_readerAnnotationProperty_brush1"
+        app:layout_constraintLeft_toRightOf="@id/iv_readerAnnotationProperty_brush1"
+        app:layout_constraintRight_toRightOf="parent"
+        android:layout_marginLeft="8dp"
+        android:layout_marginRight="8dp"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content" />
+</android.support.constraint.ConstraintLayout>

+ 2 - 0
reader/src/main/res/values-de/strings.xml

@@ -5,4 +5,6 @@
     <string name="reader_more_menu_share">"Teilen  "</string>
     <string name="reader_more_menu_text_reflow">Text Rückfluss</string>
     <string name="reader_more_menu_print">Drucken</string>
+    <string name="pdfReader_ppw_thickness">Größe</string>
+    <string name="pdfReader_ppw_opacity">Deckkraft</string>
 </resources>

+ 2 - 0
reader/src/main/res/values-es/strings.xml

@@ -5,4 +5,6 @@
     <string name="reader_more_menu_share">Compartir</string>
     <string name="reader_more_menu_text_reflow">Herramienta de marcado</string>
     <string name="reader_more_menu_print">Borrar firma</string>
+    <string name="pdfReader_ppw_thickness">Tamaño</string>
+    <string name="pdfReader_ppw_opacity">Opacidad</string>
 </resources>

+ 2 - 0
reader/src/main/res/values-fr/strings.xml

@@ -5,4 +5,6 @@
     <string name="reader_more_menu_share">Partager</string>
     <string name="reader_more_menu_text_reflow">Text Reflow</string>
     <string name="reader_more_menu_print">Imprimer</string>
+    <string name="pdfReader_ppw_thickness">Taille</string>
+    <string name="pdfReader_ppw_opacity">Opacité</string>
 </resources>

+ 2 - 0
reader/src/main/res/values-it/strings.xml

@@ -5,4 +5,6 @@
     <string name="reader_more_menu_share">Condividere</string>
     <string name="reader_more_menu_text_reflow">Testo riflusso</string>
     <string name="reader_more_menu_print">Stampa</string>
+    <string name="pdfReader_ppw_thickness">Dimensione</string>
+    <string name="pdfReader_ppw_opacity">Opacità</string>
 </resources>

+ 2 - 0
reader/src/main/res/values-ja/strings.xml

@@ -5,4 +5,6 @@
     <string name="reader_more_menu_print">印刷</string>
     <string name="reader_more_menu_file_info">ファイル内容</string>
     <string name="reader_more_menu_user_guide">ユーザーガイド</string>
+    <string name="pdfReader_ppw_thickness">サイズ</string>
+    <string name="pdfReader_ppw_opacity">透明度</string>
 </resources>

+ 2 - 0
reader/src/main/res/values-ko/strings.xml

@@ -5,4 +5,6 @@
     <string name="reader_more_menu_share">공유</string>
     <string name="reader_more_menu_text_reflow">텍스트 리플로우</string>
     <string name="reader_more_menu_print">인쇄</string>
+    <string name="pdfReader_ppw_thickness">크기</string>
+    <string name="pdfReader_ppw_opacity">투명도</string>
 </resources>

+ 2 - 0
reader/src/main/res/values-pt/strings.xml

@@ -5,4 +5,6 @@
     <string name="reader_more_menu_share">Compartilhar</string>
     <string name="reader_more_menu_text_reflow">Refluxo de texto</string>
     <string name="reader_more_menu_print">Imprimir</string>
+    <string name="pdfReader_ppw_thickness">Tamanho</string>
+    <string name="pdfReader_ppw_opacity">Opacidade</string>
 </resources>

+ 2 - 0
reader/src/main/res/values-ru/strings.xml

@@ -5,4 +5,6 @@
     <string name="reader_more_menu_share">Поделиться</string>
     <string name="reader_more_menu_text_reflow">Перенаправить Текст</string>
     <string name="reader_more_menu_print">Печать</string>
+    <string name="pdfReader_ppw_thickness">Размер</string>
+    <string name="pdfReader_ppw_opacity">Прозрачность</string>
 </resources>

+ 2 - 0
reader/src/main/res/values-zh-rTW/strings.xml

@@ -6,4 +6,6 @@
     <string name="reader_more_menu_file_info">文件資訊</string>
     <string name="reader_more_menu_user_guide">使用指南</string>
     <string name="reader_copy_text_success">已複製到剪貼簿中!</string>
+    <string name="pdfReader_ppw_thickness">大小</string>
+    <string name="pdfReader_ppw_opacity">透明度</string>
 </resources>

+ 2 - 0
reader/src/main/res/values-zh/strings.xml

@@ -6,4 +6,6 @@
     <string name="reader_more_menu_file_info">文件信息</string>
     <string name="reader_more_menu_user_guide">使用导航</string>
     <string name="reader_copy_text_success">已复制到剪切板!</string>
+    <string name="pdfReader_ppw_thickness">厚度</string>
+    <string name="pdfReader_ppw_opacity">透明度</string>
 </resources>

+ 11 - 0
reader/src/main/res/values/colors.xml

@@ -11,6 +11,17 @@
     <color name="reader_bottom_toolbar_bottom_color_press">@color/picton_blue</color>
     <color name="reader_right_toolbar_selected_bg">#6633B5E5</color>
 
+    <color name="reader_annotation_color_1">#000000</color>
+    <color name="reader_annotation_color_2">#296dd2</color>
+    <color name="reader_annotation_color_3">#57d214</color>
+    <color name="reader_annotation_color_4">#ffdc1b</color>
+    <color name="reader_annotation_color_5">#ff7e00</color>
+    <color name="reader_annotation_color_6">#fe866a</color>
+    <color name="reader_annotation_color_7">#d11bff</color>
+    <color name="reader_annotation_color_8">#ff1b89</color>
+    <color name="reader_annotation_color_9">#dd0202</color>
+    <color name="reader_annotation_color_10">#ffffff</color>
+
     <color name="highlight_default_color">#FFFF00</color>
     <color name="strike_default_color">#FF0000</color>
     <color name="underline_default_color">#FF0000</color>

+ 8 - 0
reader/src/main/res/values/dimens.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <dimen name="reader_annotation_property_setting_window_right_toolbar_space">8dp</dimen>
+    <dimen name="reader_annotation_property_setting_window_elevation">2dp</dimen>
+
+    <dimen name="reader_color_displayer_width">54dp</dimen>
+    <dimen name="reader_color_displayer_height">60dp</dimen>
+</resources>

+ 3 - 0
reader/src/main/res/values/strings.xml

@@ -7,4 +7,7 @@
     <string name="reader_more_menu_file_info">File Info</string>
     <string name="reader_more_menu_user_guide">User Guide</string>
     <string name="reader_copy_text_success">It has been copied to the clipboard!</string>
+
+    <string name="pdfReader_ppw_thickness">Size</string>
+    <string name="pdfReader_ppw_opacity">Opacity</string>
 </resources>

+ 6 - 0
reader/src/main/res/values/styles.xml

@@ -34,4 +34,10 @@
         <item name="android:padding">12dp</item>
         <item name="android:background">?android:attr/selectableItemBackground</item>
     </style>
+    <style name="AnnotationPropertyColorImageView">
+        <item name="android:layout_width">24dp</item>
+        <item name="android:layout_height">24dp</item>
+        <item name="android:layout_margin">8dp</item>
+        <item name="android:src">@drawable/reader_annotation_property_color_border</item>
+    </style>
 </resources>