diff --git a/README.md b/README.md
index c6e5ac1..933149a 100644
--- a/README.md
+++ b/README.md
@@ -152,6 +152,54 @@ or specify them in your application theme (`styles.xml` in dem app) for to apply
```
+# APIs
+
+All styling attributes can also be specified using code. Since `KodeEditorLayout`
+is just a wrapper to extend the `CodeEditorView` with line numbers and the minimap to use
+some of those methods you need to access the matching property of the `KodeEditorLayout` first.
+
+## KodeEditorLayout
+
+| Name | Description | Type |
+|------|-------------|------|
+| text | Sets the given text in the editor. | String |
+| setText(@StringRes) | Sets the given string resource as the text in the editor. | Int |
+| syntaxHighlighter | Gets/Sets the active syntax highlighter. Use `null` to disable highlighting altogether. | SyntaxHighlighter? |
+| editable | Gets/Sets if the editor content is editable. | Boolean |
+
+### Line numbers
+
+| Name | Description | Type |
+|------|-------------|------|
+| showDivider | Gets/Sets if the divider between line numbers and code editor is shown. | Boolean |
+
+### Minimap
+
+| Name | Description | Type |
+|------|-------------|------|
+| showMinimap | Gets/Sets if the minimap is shown. | Boolean |
+| minimapMaxDimension | Gets/Sets the maximum dimension of the minimap in pixels. | Float |
+| minimapBorderWidth | Gets/Sets the minimap border size in in pixels. | Number |
+| minimapBorderColor | Gets/Sets the minimap border color. | @ColorInt |
+| minimapIndicatorColor | Gets/Sets the minimap indicator color. | @ColorInt |
+
+## CodeEditorView
+
+To acces these API methods use the `codeEditorLayout.codeEditorView` property.
+
+| Name | Description | Type |
+|------|-------------|------|
+| text | Sets the given text in the editor. | String |
+| setText(@StringRes) | Sets the given string resource as the text in the editor. | Int |
+| getLineCount() | Returns the current line count. | Long |
+| syntaxHighlighter | Gets/Sets the active syntax highlighter. Use `null` to disable highlighting altogether. | SyntaxHighlighter? |
+| editable | Gets/Sets if the editor content is editable. | Boolean |
+| hasSelection | True when a range is selected. | Boolean |
+| selectionStart | The start index of the current selection. | Int |
+| selectionEnd | The end index of the current selection. | Int |
+| selectionChangedListener | Gets/Sets the Listener for selection changes. | SelectionChangedListener? |
+
+
# Contributing
GitHub is for social coding: if you want to write code, I encourage contributions through pull requests from forks
diff --git a/app/src/main/java/de/markusressel/kodeeditor/MainActivity.kt b/app/src/main/java/de/markusressel/kodeeditor/MainActivity.kt
index 0c938b7..cf2e73b 100644
--- a/app/src/main/java/de/markusressel/kodeeditor/MainActivity.kt
+++ b/app/src/main/java/de/markusressel/kodeeditor/MainActivity.kt
@@ -2,9 +2,11 @@ package de.markusressel.kodeeditor
import android.graphics.Color
import android.os.Bundle
+import android.support.annotation.RawRes
import android.support.v7.app.AppCompatActivity
import com.github.kittinunf.fuel.Fuel
import de.markusressel.kodeeditor.library.extensions.dpToPx
+import de.markusressel.kodeeditor.library.view.SelectionChangedListener
import de.markusressel.kodehighlighter.language.markdown.MarkdownSyntaxHighlighter
import kotlinx.android.synthetic.main.activity_main.*
@@ -25,6 +27,10 @@ class MainActivity : AppCompatActivity() {
minimapMaxDimension = 150.dpToPx(context)
}
+ codeEditorLayout.codeEditorView.selectionChangedListener = object : SelectionChangedListener {
+ override fun onSelectionChanged(start: Int, end: Int, hasSelection: Boolean) {}
+ }
+
initEditorText()
}
@@ -35,7 +41,8 @@ class MainActivity : AppCompatActivity() {
if (error != null || text == null) {
// fallback if no network is available
- codeEditorLayout.setText(R.string.demo_text)
+ val sampleText = readResourceFileAsText(R.raw.sample_text)
+ codeEditorLayout.text = sampleText
} else {
codeEditorLayout.text = text
}
@@ -43,4 +50,8 @@ class MainActivity : AppCompatActivity() {
}
}
+ private fun readResourceFileAsText(@RawRes resourceId: Int): String {
+ return resources.openRawResource(resourceId).bufferedReader().readText()
+ }
+
}
diff --git a/app/src/main/res/raw/sample_text b/app/src/main/res/raw/sample_text
new file mode 100644
index 0000000..89d96dc
--- /dev/null
+++ b/app/src/main/res/raw/sample_text
@@ -0,0 +1,186 @@
+# KodeEditor
+A simple code editor with syntax highlighting and pinch to zoom
+
+![Editing](https://thumbs.gfycat.com/TalkativeGrandIchthyosaurs-size_restricted.gif)
+![Scroll and zoom](https://thumbs.gfycat.com/BouncyLividBlackbear-size_restricted.gif)
+![Minimap](https://thumbs.gfycat.com/VigorousDimFrog-size_restricted.gif)
+
+# Build Status
+
+| Master | Dev |
+|--------|-----|
+| [![Master](https://travis-ci.org/markusressel/KodeEditor.svg?branch=master)](https://travis-ci.org/markusressel/KodeEditor/branches) | [![Master](https://travis-ci.org/markusressel/KutePreferences.svg?branch=dev)](https://travis-ci.org/markusressel/KodeEditor/branches) |
+| [![codebeat badge](https://codebeat.co/badges/f7fa8602-1d15-457e-904d-cb585e984952)](https://codebeat.co/projects/github-com-markusressel-kodeeditor-master) | [![codebeat badge](https://codebeat.co/badges/19447977-bc96-4519-90b1-e532139ae1a5)](https://codebeat.co/projects/github-com-markusressel-kodeeditor-dev) |
+
+# Features
+* Pinch-To-Zoom
+* Line numbers
+* Syntax highlighting
+ * import languages you need
+ * or simply create your own highlighter using **regex** or other techniques
+ * themes
+* "Minimap" style document overview
+* Written entirely in Kotlin
+
+# How to use
+Have a look at the demo app (`app` module) for a complete sample.
+
+## Gradle
+To use this library just include it in your dependencies using
+
+ repositories {
+ ...
+ maven { url "https://jitpack.io" }
+ }
+
+in your project build.gradle file and
+
+```
+dependencies {
+ ...
+
+ def codeEditorVersion = "v2.1.0"
+ implementation("com.github.markusressel.KodeEditor:library:${codeEditorVersion}")
+}
+```
+
+in your desired module ```build.gradle``` file.
+
+## Add to your layout
+
+To use this editor simply add something similar to this to your desired layout xml file:
+
+```
+
+```
+
+## Syntax highlighting
+
+### Language Autodetection
+
+Currently there is no auto detection for the language used in a document.
+You have to manage the syntax highlighter yourself and call the `setSyntaxHighlighter` method when appropriate.
+
+### Integrated syntax highlighters
+
+Have a look at the [KodeHighlighter section about this](https://github.com/markusressel/KodeHighlighter).
+
+### Writing a custom syntax highlighter
+
+Have a look at the [KodeHighlighter section about this](https://github.com/markusressel/KodeHighlighter).
+
+## Styling
+
+KodeEditor can be styled in multiple ways:
+
+1. xml attributes on KodeEditor
+1. theme attributes in your custom theme
+1. methods on the view object itself
+
+### Theme Attributes
+
+| Name | Description | Type | Default |
+|---------------------------|------------------------------------------|----------|----------------------------------------|
+| ke_lineNumbers_textColor | Specifies the text color of line numbers | Color | `android.R.attr.textColorPrimary` |
+| ke_lineNumbers_backgroundColor | Specifies the background color of the line numbers view | Color | `android.R.attr.windowBackground` |
+| ke_divider_enabled | Specifies if a divider should be drawn between line numbers and the actual code editor content | Boolean | `true` |
+| ke_divider_color | Specifies the color of the divider (has no effect if `ke_divider_enabled` is set to `false`) | Color | `android.R.attr.textColorPrimary` |
+| ke_editor_backgroundColor | Specifies the background color of the code editor view | Color | `android.R.attr.windowBackground` |
+| ke_editor_maxZoom | Specifies the maximum zoom level of the editor | Float | `10` |
+| ke_minimap_enabled | Enables the minimap | Boolean | `true` |
+| ke_minimap_maxDimension | Specifies the maximum dimension of the minimap for both axis | Dimension | `150dp` |
+| ke_minimap_borderColor | Specifies the border color of the minimap | Color | `Color.BLACK` |
+| ke_minimap_indicatorColor | Specifies the color of the minimap indicator | Color | `Color.RED` |
+
+You can either use those attributes directly on the view in your layout like this:
+
+```
+
+```
+
+or specify them in your application theme (`styles.xml` in dem app) for to apply a style globally:
+
+```
+
+
+
+
+
+
+```
+
+# Contributing
+
+GitHub is for social coding: if you want to write code, I encourage contributions through pull requests from forks
+of this repository. Create GitHub tickets for bugs and new features and comment on the ones that you are interested in.
+
+# License
+
+```
+MIT License
+
+Copyright (c) 2018 Markus Ressel
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+```
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ebe81d1..a96ba16 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,983 +1,3 @@
KodeEditor
-
-
-
-
diff --git a/library/src/main/java/de/markusressel/kodeeditor/library/view/CodeEditText.kt b/library/src/main/java/de/markusressel/kodeeditor/library/view/CodeEditText.kt
index f138a4d..b8a8ca4 100644
--- a/library/src/main/java/de/markusressel/kodeeditor/library/view/CodeEditText.kt
+++ b/library/src/main/java/de/markusressel/kodeeditor/library/view/CodeEditText.kt
@@ -40,6 +40,11 @@ constructor(context: Context,
initSyntaxHighlighter()
}
+ /**
+ * Listener for selection changes
+ */
+ var selectionChangedListener: SelectionChangedListener? = null
+
private var highlightingTimeout = 50L to TimeUnit.MILLISECONDS
private var highlightingDisposable: Disposable? = null
@@ -115,6 +120,11 @@ constructor(context: Context,
?: Log.w(TAG, "No syntax highlighter is set!")
}
+ override fun onSelectionChanged(selStart: Int, selEnd: Int) {
+ super.onSelectionChanged(selStart, selEnd)
+ selectionChangedListener?.onSelectionChanged(selStart, selEnd, hasSelection())
+ }
+
companion object {
const val TAG = "CodeEditText"
}
diff --git a/library/src/main/java/de/markusressel/kodeeditor/library/view/CodeEditorView.kt b/library/src/main/java/de/markusressel/kodeeditor/library/view/CodeEditorView.kt
index 0d3d9f1..0f2f49d 100644
--- a/library/src/main/java/de/markusressel/kodeeditor/library/view/CodeEditorView.kt
+++ b/library/src/main/java/de/markusressel/kodeeditor/library/view/CodeEditorView.kt
@@ -2,11 +2,13 @@ package de.markusressel.kodeeditor.library.view
import android.content.Context
import android.graphics.Color
+import android.support.annotation.CallSuper
import android.support.annotation.StringRes
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.TextView
import com.otaliastudios.zoom.ZoomApi
import com.otaliastudios.zoom.ZoomLayout
import de.markusressel.kodeeditor.library.R
@@ -21,7 +23,7 @@ import de.markusressel.kodehighlighter.core.SyntaxHighlighter
*/
open class CodeEditorView
@JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
- : ZoomLayout(context, attrs, defStyleAttr) {
+ : ZoomLayout(context, attrs, defStyleAttr), SelectionChangedListener {
/**
* The actual text editor content
@@ -48,6 +50,11 @@ open class CodeEditorView
}
}
+ /**
+ * Listener for selection changes
+ */
+ var selectionChangedListener: SelectionChangedListener? = null
+
/**
* The current text
*/
@@ -58,6 +65,27 @@ open class CodeEditorView
codeTextView.text = value
}
+ /** The start index of the current selection */
+ val selectionStart: Int
+ get() {
+ val activeView: TextView = if (editable) codeEditText else codeTextView
+ return activeView.selectionStart
+ }
+
+ /** The end index of the current selection */
+ val selectionEnd: Int
+ get() {
+ val activeView: TextView = if (editable) codeEditText else codeTextView
+ return activeView.selectionEnd
+ }
+
+ /** True when a range is selected */
+ val hasSelection: Boolean
+ get() {
+ val activeView: TextView = if (editable) codeEditText else codeTextView
+ return activeView.hasSelection()
+ }
+
/**
* Set the text in the editor
*
@@ -118,9 +146,11 @@ open class CodeEditorView
codeEditText.post {
codeEditText.setSelection(0)
}
+ codeEditText.selectionChangedListener = this
codeTextView = findViewById(R.id.cev_editor_codeTextView)
codeTextView.setViewBackgroundWithoutResettingPadding(null)
+ codeTextView.selectionChangedListener = this
}
private var firstInit = true
@@ -166,6 +196,15 @@ open class CodeEditorView
}
}
+ /**
+ * Called when the selection changes.
+ * Override this if you are interested in such events.
+ */
+ @CallSuper
+ override fun onSelectionChanged(start: Int, end: Int, hasSelection: Boolean) {
+ selectionChangedListener?.onSelectionChanged(start, end, hasSelection)
+ }
+
companion object {
const val TAG = "CodeEditorView"
diff --git a/library/src/main/java/de/markusressel/kodeeditor/library/view/CodeTextView.kt b/library/src/main/java/de/markusressel/kodeeditor/library/view/CodeTextView.kt
index 2822352..aed0de2 100644
--- a/library/src/main/java/de/markusressel/kodeeditor/library/view/CodeTextView.kt
+++ b/library/src/main/java/de/markusressel/kodeeditor/library/view/CodeTextView.kt
@@ -42,6 +42,11 @@ constructor(context: Context,
initSyntaxHighlighter()
}
+ /**
+ * Listener for selection changes
+ */
+ var selectionChangedListener: SelectionChangedListener? = null
+
private var highlightingTimeout = 50L to TimeUnit.MILLISECONDS
private var highlightingDisposable: Disposable? = null
@@ -119,6 +124,11 @@ constructor(context: Context,
}
}
+ override fun onSelectionChanged(selStart: Int, selEnd: Int) {
+ super.onSelectionChanged(selStart, selEnd)
+ selectionChangedListener?.onSelectionChanged(selStart, selEnd, hasSelection())
+ }
+
companion object {
const val TAG = "CodeTextView"
}
diff --git a/library/src/main/java/de/markusressel/kodeeditor/library/view/SelectionChangedListener.kt b/library/src/main/java/de/markusressel/kodeeditor/library/view/SelectionChangedListener.kt
new file mode 100644
index 0000000..6b372ea
--- /dev/null
+++ b/library/src/main/java/de/markusressel/kodeeditor/library/view/SelectionChangedListener.kt
@@ -0,0 +1,17 @@
+package de.markusressel.kodeeditor.library.view
+
+/**
+ * Interface for a listener of selection changes
+ */
+interface SelectionChangedListener {
+
+ /**
+ * Called when the selection changes
+ *
+ * @param start selection start index
+ * @param end selection end index
+ * @param hasSelection true when a range is selected (start != end)
+ */
+ fun onSelectionChanged(start: Int, end: Int, hasSelection: Boolean)
+
+}
\ No newline at end of file