@@ -41,6 +41,15 @@ class CodeView : RelativeLayout {
41
41
private val vShadowBottomLine: View
42
42
private val vShadowBottomContent: View
43
43
44
+ internal var colorTheme: ColorThemeData
45
+ set(colorTheme) {
46
+ field = colorTheme
47
+ }
48
+
49
+ init {
50
+ colorTheme = ColorTheme .SOLARIZED_LIGHT .with ()
51
+ }
52
+
44
53
/* *
45
54
* Core view to draw code by lines.
46
55
*/
@@ -57,8 +66,9 @@ class CodeView : RelativeLayout {
57
66
*/
58
67
private var state: ViewState
59
68
set(newState) {
60
- if (newState == ViewState .PRESENTED )
69
+ if (newState == ViewState .PRESENTED ) {
61
70
hidePlaceholder()
71
+ }
62
72
field = newState
63
73
}
64
74
@@ -86,6 +96,8 @@ class CodeView : RelativeLayout {
86
96
/* *
87
97
* Code view state to control build flow.
88
98
*/
99
+ // todo: remove states and tasks
100
+ // todo: or sort task positions (first we need to set adapter, then other actions and call highlight task on finish)
89
101
enum class ViewState {
90
102
BUILD ,
91
103
PREPARE ,
@@ -100,19 +112,20 @@ class CodeView : RelativeLayout {
100
112
* @return Result of state check
101
113
*/
102
114
fun isBuilding () = state == ViewState .BUILD
115
+
103
116
fun isPrepared () = state == ViewState .PREPARE
104
117
fun isPresented () = state == ViewState .PRESENTED
105
118
106
119
/* *
107
120
* Accessor/mutator to reduce frequently used actions.
108
121
*/
109
- var adapter: AbstractCodeAdapter <* >
122
+ var adapter: AbstractCodeAdapter <* >?
110
123
get() {
111
124
return rvCodeContent.adapter as AbstractCodeAdapter <* >
112
125
}
113
126
set(adapter) {
127
+ rvCodeContent.adapter = adapter
114
128
delayed { // prevent UI overhead & initialization inconsistency
115
- rvCodeContent.adapter = adapter
116
129
state = ViewState .PRESENTED
117
130
}
118
131
}
@@ -157,13 +170,15 @@ class CodeView : RelativeLayout {
157
170
*/
158
171
159
172
// default color theme provided by enum
160
- fun setColorTheme (colorTheme : ColorTheme ) = addTask {
161
- adapter.colorTheme = colorTheme.with ()
173
+ fun colorTheme (colorTheme : ColorTheme ): CodeView {
174
+ this .colorTheme = colorTheme.with ()
175
+ return this
162
176
}
163
177
164
178
// custom color theme provided by user
165
- fun setColorTheme (colorTheme : ColorThemeData ) = addTask {
166
- adapter.colorTheme = colorTheme
179
+ fun colorTheme (colorTheme : ColorThemeData ): CodeView {
180
+ this .colorTheme = colorTheme
181
+ return this
167
182
}
168
183
169
184
/* *
@@ -172,19 +187,19 @@ class CodeView : RelativeLayout {
172
187
*
173
188
* @param language Language to highlight
174
189
*/
175
- fun highlightCode (language : String ) = addTask {
176
- adapter.highlightCode(language ) {
177
- refreshAnimated( )
190
+ fun highlight (language : String? = null) {
191
+ if (adapter == null ) {
192
+ throw IllegalStateException ( " Please set adapter or use codeContent() before highlight() " )
178
193
}
179
- }
180
194
181
- /* *
182
- * Highlight code with trying to classify by code snippet.
183
- * It shows not highlighted code & then when classified refreshes view.
184
- */
185
- fun highlightCode () = addTask {
186
- adapter.highlightCode {
187
- refreshAnimated()
195
+ adapter?.highlight(language) {
196
+ animate().setDuration(Utils .DELAY * 2 )// * 2 to wait notifyDataSetChanged
197
+ .alpha(.1f )
198
+
199
+ delayed {
200
+ animate().alpha(1f )
201
+ adapter?.notifyDataSetChanged()
202
+ }
188
203
}
189
204
}
190
205
@@ -194,15 +209,24 @@ class CodeView : RelativeLayout {
194
209
*
195
210
* @param listener Code line click listener
196
211
*/
197
- fun setCodeListener (listener : OnCodeLineClickListener ) = addTask {
198
- adapter.codeListener = listener
212
+ fun codeListener (listener : OnCodeLineClickListener ): CodeView {
213
+ if (adapter == null ) {
214
+ throw IllegalStateException (" Please set adapter or use codeContent() before highlight()" )
215
+ }
216
+
217
+ adapter?.codeListener = listener
218
+ return this
199
219
}
200
220
201
221
/* *
202
222
* Remove code listener.
203
223
*/
204
224
fun removeCodeListener () = addTask {
205
- adapter.codeListener = null
225
+ if (adapter == null ) {
226
+ throw IllegalStateException (" Please set adapter or use codeContent() before highlight()" )
227
+ }
228
+
229
+ adapter?.codeListener = null
206
230
}
207
231
208
232
/* *
@@ -222,7 +246,7 @@ class CodeView : RelativeLayout {
222
246
*
223
247
* @param content Code content
224
248
*/
225
- fun setCodeContent (content : String ) {
249
+ fun codeContent (content : String ): CodeView {
226
250
when (state) {
227
251
ViewState .BUILD ->
228
252
build(content)
@@ -233,6 +257,8 @@ class CodeView : RelativeLayout {
233
257
ViewState .PRESENTED ->
234
258
update(content)
235
259
}
260
+
261
+ return this
236
262
}
237
263
238
264
/* *
@@ -249,8 +275,9 @@ class CodeView : RelativeLayout {
249
275
measurePlaceholder(linesCount)
250
276
state = ViewState .PREPARE
251
277
278
+ rvCodeContent.adapter = CodeWithNotesAdapter (context, content, colorTheme)
279
+
252
280
delayed {
253
- rvCodeContent.adapter = CodeWithNotesAdapter (context, content)
254
281
processBuildTasks()
255
282
setupShadows()
256
283
hidePlaceholder()
@@ -266,7 +293,7 @@ class CodeView : RelativeLayout {
266
293
private fun update (content : String ) {
267
294
state = ViewState .PREPARE
268
295
measurePlaceholder(extractLines(content).size)
269
- adapter.updateCodeContent(content)
296
+ adapter? .updateCodeContent(content)
270
297
hidePlaceholder()
271
298
state = ViewState .PRESENTED
272
299
}
@@ -277,7 +304,7 @@ class CodeView : RelativeLayout {
277
304
* Border shadows will shown if presented full code listing.
278
305
* It helps user to see what part of content are scrolled & hidden.
279
306
*/
280
- private fun setupShadows () = setShadowsVisible(! adapter.isFullShowing)
307
+ private fun setupShadows () = setShadowsVisible(! adapter? .isFullShowing!! )
281
308
282
309
/* *
283
310
* Placeholder fills space at start and stretched to marked up view size
@@ -287,15 +314,11 @@ class CodeView : RelativeLayout {
287
314
*/
288
315
private fun measurePlaceholder (linesCount : Int ) {
289
316
val lineHeight = dpToPx(context, 24 )
290
- val topPadding = dpToPx(context, 8 )
291
-
292
- // double padding (top & bottom), one is enough for single line view
293
- val padding = (if (linesCount > 1 ) 2 else 1 ) * topPadding
317
+ val verticalPadding = dpToPx(context, 8 )
294
318
295
- val height = linesCount * lineHeight + padding
319
+ val height = linesCount * lineHeight + verticalPadding
296
320
297
- vPlaceholder.layoutParams = LayoutParams (
298
- LayoutParams .MATCH_PARENT , height)
321
+ vPlaceholder.layoutParams = LayoutParams (LayoutParams .MATCH_PARENT , height)
299
322
300
323
vPlaceholder.alpha = 1f
301
324
}
@@ -306,14 +329,6 @@ class CodeView : RelativeLayout {
306
329
.setDuration(350 )
307
330
.alpha(0f )
308
331
.didAnimated { vPlaceholder.alpha = 0f }
309
-
310
- private fun refreshAnimated () = animate()
311
- .setDuration(150 )
312
- .alpha(.2f )
313
- .didAnimated {
314
- adapter.notifyDataSetChanged()
315
- animate().alpha(1f )
316
- }
317
332
}
318
333
319
334
/* *
0 commit comments