Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ class CodeContentAdapter : RecyclerView.Adapter<CodeContentAdapter.ViewHolder> {
/**
* Split code content by lines. If listing must not be shown full it shows
* only necessary lines & rest are dropped (and stores in named variable).
*
* @param isShowFull Show full listing?
* @param shortcutNote Note will shown below code for listing shortcut
*/
private fun initCodeContent(isShowFull: Boolean,
shortcutNote: String = mContext.getString(R.string.show_all)) {
Expand Down
49 changes: 42 additions & 7 deletions codeview/src/main/java/io/github/kbiakov/codeview/CodeView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import android.view.ViewPropertyAnimator
import android.widget.RelativeLayout
import io.github.kbiakov.codeview.highlight.ColorTheme
import io.github.kbiakov.codeview.highlight.ColorThemeData
import io.github.kbiakov.codeview.highlight.color
import java.util.*

/**
Expand Down Expand Up @@ -135,6 +136,8 @@ class CodeView : RelativeLayout {
/**
* Specify color theme: syntax colors (need to highlighting) & related to
* code view (numeration color & background, content backgrounds).
*
* @param colorTheme Default or custom color theme
*/

// default color theme provided by enum
Expand All @@ -150,6 +153,8 @@ class CodeView : RelativeLayout {
/**
* Highlight code by defined programming language.
* It holds the placeholder on the view until code is highlighted.
*
* @param language Language to highlight
*/
fun highlightCode(language: String) = addTask {
adapter.highlightCode(language)
Expand All @@ -166,15 +171,19 @@ class CodeView : RelativeLayout {
}

/**
* Useful in some cases if you want to listen user line selection.
* (May be you want to show alert when user click on code line, who knows?) ¯\_(ツ)_/¯
* Useful in some cases if you want to listen user line clicks.
* (May be you want to show alert, who knows?) ¯\_(ツ)_/¯
*
* @param listener Code line click listener
*/
fun setCodeListener(listener: OnCodeLineClickListener) = addTask {
adapter.codeListener = listener
}

/**
* Control shadows visibility to provide more sensitive UI.
*
* @param isVisible Shadows visibility
*/
fun setShadowsVisible(isVisible: Boolean = true) = addTask {
val visibility = if (isVisible) View.VISIBLE else GONE
Expand All @@ -185,17 +194,19 @@ class CodeView : RelativeLayout {

/**
* Update code content if view was built or, finally, build code view.
*
* @param content Code content
*/
fun setCodeContent(content: String) {
when (state) {
ViewState.BUILD ->
build(content)
ViewState.PREPARE ->
Thread.delayed {
adapter.updateCodeContent(content)
update(content)
}
ViewState.PRESENTED ->
adapter.updateCodeContent(content)
update(content)
}
}

Expand All @@ -222,6 +233,19 @@ class CodeView : RelativeLayout {
}
}

/**
* Hot view updating.
*
* @param content Code content
*/
private fun update(content: String) {
state = ViewState.PREPARE
measurePlaceholder(extractLines(content).size)
adapter.updateCodeContent(content)
hidePlaceholder()
state = ViewState.PRESENTED
}

// - Setup actions

/**
Expand All @@ -232,15 +256,22 @@ class CodeView : RelativeLayout {

/**
* Placeholder fills space at start and stretched to marked up view size
* (by extracting code lines) because at this point it's not built yet.
* (by code lines count) because at this point it's not built yet.
*
* @param linesCount Count of lines to measure space for placeholder
*/
private fun measurePlaceholder(linesCount: Int) {
val lineHeight = dpToPx(context, 24)
val topMargin = dpToPx(context, 8)
val height = linesCount * lineHeight + 2 * topMargin
val topPadding = dpToPx(context, 8)

// double padding (top & bottom) for big view, one is enough for small
val padding = (if (linesCount > 1) 2 else 1) * topPadding

val height = linesCount * lineHeight + padding

vPlaceholder.layoutParams = RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, height)
vPlaceholder.visibility = View.VISIBLE
}

// - Animations
Expand Down Expand Up @@ -270,11 +301,15 @@ interface OnCodeLineClickListener {

/**
* Extension for delayed block call.
*
* @param body Operation body
*/
fun Thread.delayed(body: () -> Unit) = Handler().postDelayed(body, 150)

/**
* More readable form for animation listener (hi, iOS & Cocoa Touch!).
*
* @param handler Handler body
*/
fun ViewPropertyAnimator.didAnimated(handler: () -> Unit) =
setListener(object : AnimatorListenerAdapter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ object CodeClassifier {
* At this point all files with code listings prepared to process
* by classifier. This operation often is very expensive & should
* be performed asynchronously when app starts.
*
* @param context Context
*/
fun train(context: Context) {
Files.ls(context, TRAINING_SET_FOLDER).forEach { language ->
Expand All @@ -53,6 +55,9 @@ object CodeClassifier {

/**
* Try to define what language is used in code snippet.
*
* @param snippet Code snippet
* @return Code language
*/
fun classify(snippet: String): String {
val feature = classifier.classify(spaceSplit(snippet))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ object CodeHighlighter {
* @param codeLanguage Programming language
* @param rawSource Code source by one string
* @param colorTheme Color theme (see below)
* @return Highlighted code. String with necessary inserted color tags.
* @return Highlighted code, string with necessary inserted color tags
*/
fun highlight(codeLanguage: String, rawSource: String, colorTheme: ColorThemeData): String {
val source = rawSource.escapeLT()
Expand All @@ -46,6 +46,10 @@ object CodeHighlighter {

/**
* Parse user input by extracting highlighted content.
*
* @param codeContent Code content
* @param result Syntax unit
* @return Parsed content to highlight
*/
private fun parseContent(codeContent: String, result: ParseResult): String {
val length = result.offset + result.length
Expand All @@ -55,12 +59,19 @@ object CodeHighlighter {

/**
* Color accessor from built color map for selected color theme.
*
* @param colorsMap Colors map built from color theme
* @param result Syntax unit
* @return Color for syntax unit
*/
private fun getColor(colorsMap: HashMap<String, String>, result: ParseResult) =
colorsMap[result.styleKeys[0]] ?: colorsMap["pln"]

/**
* Build fast accessor (as map) for selected color theme.
*
* @param colorTheme Color theme
* @return Colors map built from color theme
*/
private fun buildColorsMap(colorTheme: ColorThemeData) =
object : HashMap<String, String>() {
Expand Down Expand Up @@ -155,7 +166,7 @@ data class ColorThemeData(
val noteColor: Int)

/**
* Colors for highlighting code spots.
* Colors for highlighting code units.
*/
data class SyntaxColors(
val type: Int = 0x859900,
Expand Down
3 changes: 1 addition & 2 deletions codeview/src/main/res/layout/item_code_line.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
android:id="@+id/tv_line_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/tv_line_num"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_toRightOf="@+id/tv_line_num"
android:gravity="center_vertical"
android:fontFamily="monospace"
android:singleLine="true"
Expand Down
16 changes: 8 additions & 8 deletions codeview/src/main/res/layout/layout_code_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
<io.github.kbiakov.codeview.BidirectionalScrollView
android:id="@+id/v_scroll"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:fillViewport="true">

<android.support.v7.widget.RecyclerView
android:id="@+id/rv_code_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
tools:listitem="@layout/item_code_line"/>

</io.github.kbiakov.codeview.BidirectionalScrollView>
Expand All @@ -24,27 +25,26 @@
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:background="@drawable/shadow_right"
android:visibility="invisible"/>
android:visibility="gone"/>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="16dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
android:orientation="horizontal"
android:visibility="gone">

<View
android:id="@+id/v_shadow_bottom_line"
android:layout_width="24dp"
android:layout_height="match_parent"
android:background="@drawable/shadow_bottom_line"
android:visibility="invisible"/>
android:background="@drawable/shadow_bottom_line"/>

<View
android:id="@+id/v_shadow_bottom_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/shadow_bottom_content"
android:visibility="invisible"/>
android:background="@drawable/shadow_bottom_content"/>

</LinearLayout>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {

// use chaining to build view
codeView.highlightCode("js")
//.setColorTheme(ColorTheme.SOLARIZED_LIGHT.withBgContent(myColor))
.setColorTheme(ColorTheme.SOLARIZED_LIGHT)
.setCodeContent(getString(R.string.listing_js));

// do not use chaining for built view
// (you can, but follow it should be performed sequentially)
codeView.setCodeContent(getString(R.string.listing_java));
codeView.setColorTheme(ColorTheme.DEFAULT);
codeView.highlightCode("java");
}
}
2 changes: 1 addition & 1 deletion example/src/main/res/layout/activity_listings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<io.github.kbiakov.codeview.CodeView
android:id="@+id/code_view"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

</RelativeLayout>