@@ -3,18 +3,20 @@ package io.github.kbiakov.codeview
33import android.animation.Animator
44import android.animation.AnimatorListenerAdapter
55import android.content.Context
6- import android.os.Handler
76import android.support.v7.widget.LinearLayoutManager
87import android.support.v7.widget.RecyclerView
98import android.util.AttributeSet
109import android.view.LayoutInflater
1110import android.view.View
1211import android.view.ViewPropertyAnimator
1312import android.widget.RelativeLayout
13+ import io.github.kbiakov.codeview.adapters.AbstractCodeAdapter
14+ import io.github.kbiakov.codeview.Thread.delayed
15+ import io.github.kbiakov.codeview.adapters.CodeWithNotesAdapter
1416import io.github.kbiakov.codeview.highlight.ColorTheme
1517import io.github.kbiakov.codeview.highlight.ColorThemeData
16- import io.github.kbiakov.codeview.highlight.color
1718import java.util.*
19+ import kotlin.reflect.KClass
1820
1921/* *
2022 * @class CodeView
@@ -33,7 +35,7 @@ import java.util.*
3335 *
3436 * @author Kirill Biakov
3537 */
36- class CodeView : RelativeLayout {
38+ class CodeView < T > : RelativeLayout {
3739
3840 private val vPlaceholder: View
3941 private val vShadowRight: View
@@ -56,6 +58,9 @@ class CodeView : RelativeLayout {
5658 */
5759 private var state: ViewState
5860
61+ /* *
62+ * Default constructor.
63+ */
5964 constructor (context: Context , attrs: AttributeSet ) : super (context, attrs) {
6065 val inflater = context.getSystemService(Context .LAYOUT_INFLATER_SERVICE ) as LayoutInflater
6166 inflater.inflate(R .layout.layout_code_view, this , true )
@@ -69,13 +74,13 @@ class CodeView : RelativeLayout {
6974 rvCodeContent.layoutManager = LinearLayoutManager (context)
7075 rvCodeContent.isNestedScrollingEnabled = true
7176
72- tasks = LinkedList ()
73-
7477 state = ViewState .BUILD
78+
79+ tasks = LinkedList ()
7580 }
7681
7782 /* *
78- * Code view states .
83+ * Code view state to control build flow .
7984 */
8085 enum class ViewState {
8186 BUILD ,
@@ -84,24 +89,64 @@ class CodeView : RelativeLayout {
8489 }
8590
8691 /* *
87- * Public getter for accessing view state.
88- * It may be useful if code view state is unknown.
89- * If code view was built it is not safe to use operations chaining.
92+ * Public getters for checking view state.
93+ * May be useful when code view state is unknown.
94+ * If view was built it is unsafe to use operations chaining.
95+ *
96+ * @return Result of state check
9097 */
91- fun getState () = state
98+ fun isBuilding () = state == ViewState .BUILD
99+ fun isPrepared () = state == ViewState .PREPARE
100+ fun isPresented () = state == ViewState .PRESENTED
101+
102+ /* *
103+ * TODO
104+ */
105+ private var AdapterClass : KClass <out AbstractCodeAdapter <T >>? = null
106+
107+ fun registerAdapterClass (adapterClass : KClass <out AbstractCodeAdapter <T >>) {
108+ if (state == ViewState .BUILD )
109+ AdapterClass = adapterClass
110+ else throw RuntimeException (" CodeView is already registered with " +
111+ " ${AdapterClass ?.simpleName} class name. Please, check the build flow." )
112+ }
113+
114+ fun registerAdapterClass (adapterClass : Class <out AbstractCodeAdapter <T >>) =
115+ registerAdapterClass(adapterClass.kotlin)
92116
93117 /* *
94118 * Accessor/mutator to reduce frequently used actions.
95119 */
96- var adapter: CodeContentAdapter
120+ private var adapter: AbstractCodeAdapter < T >
97121 get() {
98- return rvCodeContent.adapter as CodeContentAdapter
122+ return rvCodeContent.adapter as AbstractCodeAdapter < T >
99123 }
100124 set(adapter) {
101125 rvCodeContent.adapter = adapter
102126 state = ViewState .PRESENTED
103127 }
104128
129+ /* *
130+ * TODO
131+ */
132+ private fun createAdapter (content : String ) =
133+ (AdapterClass ? : CodeWithNotesAdapter ::class )
134+ .constructors
135+ .first()
136+ .call(context, content)
137+
138+ /* *
139+ * TODO
140+ */
141+ private fun setupInitAdapter (content : String ) {
142+ try {
143+ rvCodeContent.adapter = createAdapter(content)
144+ } catch (e: IllegalArgumentException ) {
145+ throw IllegalArgumentException (" You're registered ${AdapterClass ?.simpleName} , " +
146+ " but default constructor with 2 params (context & code content) not found." )
147+ }
148+ }
149+
105150 // - Build processor
106151
107152 /* *
@@ -111,12 +156,12 @@ class CodeView : RelativeLayout {
111156 *
112157 * @param task Task to process
113158 */
114- private fun addTask (task : () -> Unit ): CodeView {
159+ private fun addTask (task : () -> Unit ): CodeView < T > {
115160 when (state) {
116161 ViewState .BUILD ->
117162 tasks.add(task)
118163 ViewState .PREPARE ->
119- Thread . delayed(task)
164+ delayed(body = task)
120165 ViewState .PRESENTED ->
121166 task()
122167 }
@@ -193,22 +238,22 @@ class CodeView : RelativeLayout {
193238 }
194239
195240 /* *
196- * Add notes to code snippet.
241+ * Add entities to code snippet as footer .
197242 *
198- * @param notes Map of notes (line number -> list of notes )
243+ * @param entities Map of entities (line number -> list of entities )
199244 */
200- fun addLineNotes ( notes : HashMap <Int , List <String >>) = addTask {
201- adapter.lineNotes = notes
245+ fun addFooterEntities ( entities : HashMap <Int , List <T >>) = addTask {
246+ adapter.footerEntities = entities
202247 }
203248
204249 /* *
205- * Add note to code line.
250+ * Add footer entity to code line.
206251 *
207252 * @param num Line number
208- * @param note Note content
253+ * @param entity Entity content
209254 */
210- fun addLineNote (num : Int , note : String ) = addTask {
211- adapter.addLineNote (num, note )
255+ fun addFooterEntity (num : Int , entity : T ) = addTask {
256+ adapter.addFooterEntity (num, entity )
212257 }
213258
214259 /* *
@@ -221,7 +266,7 @@ class CodeView : RelativeLayout {
221266 ViewState .BUILD ->
222267 build(content)
223268 ViewState .PREPARE ->
224- Thread . delayed {
269+ delayed {
225270 update(content)
226271 }
227272 ViewState .PRESENTED ->
@@ -243,8 +288,8 @@ class CodeView : RelativeLayout {
243288 measurePlaceholder(linesCount)
244289 state = ViewState .PREPARE
245290
246- Thread . delayed {
247- rvCodeContent.adapter = CodeContentAdapter (context, content)
291+ delayed {
292+ setupInitAdapter( content)
248293 processBuildTasks()
249294 setupShadows()
250295 hidePlaceholder()
@@ -288,8 +333,8 @@ class CodeView : RelativeLayout {
288333
289334 val height = linesCount * lineHeight + padding
290335
291- vPlaceholder.layoutParams = RelativeLayout . LayoutParams (
292- RelativeLayout . LayoutParams .MATCH_PARENT , height)
336+ vPlaceholder.layoutParams = LayoutParams (
337+ LayoutParams .MATCH_PARENT , height)
293338 vPlaceholder.visibility = View .VISIBLE
294339 }
295340
@@ -318,13 +363,6 @@ interface OnCodeLineClickListener {
318363 fun onCodeLineClicked (n : Int , line : String )
319364}
320365
321- /* *
322- * Extension for delayed block call.
323- *
324- * @param body Operation body
325- */
326- fun Thread.delayed (body : () -> Unit ) = Handler ().postDelayed(body, 150 )
327-
328366/* *
329367 * More readable form for animation listener (hi, iOS & Cocoa Touch!).
330368 *
0 commit comments