@@ -24,14 +24,6 @@ class StatusView @JvmOverloads constructor(
2424) : View(context, attrs, defStyleAttr) {
2525
2626
27- /*
28- TODO
29- Display status above|bottom
30- Text Appearance?
31- LTR Support
32- Orientation draw vertical too
33-
34- */
3527
3628 companion object {
3729 const val CIRCLE_COLOR_TYPE_FILL = 1
@@ -343,7 +335,7 @@ class StatusView @JvmOverloads constructor(
343335
344336 /* *
345337 * This contains list of LabelInfo which stores static layout and text.
346- * To the caller it is a list of string and custom getter setters have been made accordingly
338+ * To the caller. It is a list of string and custom getter setters have been made accordingly
347339 *
348340 */
349341 private var statusData: MutableList <StatusInfo > by OnLayoutProp (mutableListOf ())
@@ -372,19 +364,30 @@ class StatusView @JvmOverloads constructor(
372364 */
373365 private var drawingData = mutableListOf<Item >()
374366 private var currentStatusRadius: Float by OnLayoutProp (circleRadius)
375- private var lineLengthComputed = 0.0f
367+ private var lineLengthComputed = 0.0f // actual linelength that is calculated and set
376368
377369
378370
379371
380372 // To store the data of each circle
381373 private class Item (val textData : LabelItemText ? , val circleItem : CircleItem , val lineItem : LineItem ? , val labelData : StatusItemText ? =null )
382374
375+ // Stores drawing data about labels to be drawn inside circles i.e the count of step
383376 private class LabelItemText (val text : String? = null , val paint : Paint ? = null , val x : Float = 0.0f , val y : Float = 0.0f , val drawableItem : DrawableItem ? = null )
377+
378+ // Stores drawing data for statuses to be drawn below the circle
384379 private class StatusItemText (val x : Float = 0.0f , val y : Float = 0.0f , val staticLayout : StaticLayout ? = null )
380+
381+ // Stores drawing data for every circle
385382 private class CircleItem (val center : PointF , val radius : Float , val strokePaint : Paint ? , val fillPaint : Paint ? )
383+
384+ // Stores drawing data for every line to be drawn between circles
386385 private class LineItem (val start : PointF , val end : PointF , val paint : Paint )
386+
387+ // Stores drawable draw info
387388 private class DrawableItem (val rect : Rect , val drawable : Drawable )
389+
390+ // Stores information about every status text and its dimension properties
388391 private class StatusInfo (val text : String , var width : Float =0.0f , var height : Float =0.0f , var staticLayout : StaticLayout ? = null )
389392
390393
@@ -398,15 +401,10 @@ class StatusView @JvmOverloads constructor(
398401
399402 statusCount = a.getInt(R .styleable.StatusView_statusCount , statusCount)
400403 currentCount = a.getInt(R .styleable.StatusView_currentCount , INVALID_STATUS_COUNT )
401-
402404 circleRadius = a.getDimension(R .styleable.StatusView_circleRadius , circleRadius)
403405 lineLength = a.getDimension(R .styleable.StatusView_lineLength , lineLength)
404-
405-
406406 circleStrokeWidth = a.getDimension(R .styleable.StatusView_circleStrokeWidth , circleStrokeWidth)
407407 lineStrokeWidth = a.getDimension(R .styleable.StatusView_lineWidth , lineStrokeWidth)
408-
409-
410408 completeDrawable = a.getDrawable(R .styleable.StatusView_complete_drawable )
411409 incompleteDrawable = a.getDrawable(R .styleable.StatusView_incomplete_drawable )
412410 currentDrawable = a.getDrawable(R .styleable.StatusView_current_drawable )
@@ -415,24 +413,20 @@ class StatusView @JvmOverloads constructor(
415413 lineGap = a.getDimension(R .styleable.StatusView_lineGap , lineGap)
416414 minMarginStatusText = a.getDimension(R .styleable.StatusView_minStatusMargin , minMarginStatusText)
417415 labelTopMargin = a.getDimension(R .styleable.StatusView_labelTopMargin , labelTopMargin)
418-
419-
420416 lineColor = a.getColor(R .styleable.StatusView_lineColor , lineColor)
421417 circleFillColor = a.getColor(R .styleable.StatusView_circleColor , circleFillColor)
422418 circleStrokeColor = a.getColor(R .styleable.StatusView_circleStrokeColor , circleStrokeColor)
423419 textColorStatus = a.getColor(R .styleable.StatusView_textColor , textColorStatus)
424420 textColorLabels = a.getColor(R .styleable.StatusView_textColorLabels , textColorLabels)
425421 textSizeStatus = a.getDimension(R .styleable.StatusView_textSize , textSizeStatus)
426422 textSizeLabels = a.getDimension(R .styleable.StatusView_textSizeLabels , textSizeLabels)
427-
428423 circleColorType = a.getInteger(R .styleable.StatusView_circleColorType , circleColorType)
429424 textColorLabelsIncomplete = a.getColor(R .styleable.StatusView_textColorLabelsIncomplete , textColorStatus)
430425 textColorLabelCurrent = a.getColor(R .styleable.StatusView_textColorLabelsCurrent , textColorLabelCurrent)
431426 lineColorIncomplete = a.getColor(R .styleable.StatusView_lineColorIncomplete , lineColorIncomplete)
432427 lineColorCurrent= a.getColor(R .styleable.StatusView_lineColorCurrent , lineColorCurrent)
433428 circleFillColorIncomplete = a.getColor(R .styleable.StatusView_circleColorIncomplete , circleFillColor)
434429 circleStrokeColorIncomplete = a.getColor(R .styleable.StatusView_circleStrokeColorIncomplete , circleStrokeColor)
435-
436430 circleFillColorCurrent = a.getColor(R .styleable.StatusView_circleColorCurrent , circleFillColorIncomplete)
437431 currentStatusZoom = a.getFloat(R .styleable.StatusView_currentStatusZoom , currentStatusZoom)
438432 alignStatusWithCurrent = a.getBoolean(R .styleable.StatusView_alignStatusWithCurrent , alignStatusWithCurrent)
@@ -586,7 +580,7 @@ class StatusView @JvmOverloads constructor(
586580
587581
588582 lineLengthComputed = lineLength
589- var extraWidth = if (obeyLineLength){
583+ var extraWidth = if (obeyLineLength){// extra width required by status at extreme positions
590584 setWidthDataForObeyingLineLength()
591585 }else {
592586 setWidthDataForObeyingStatusText()
@@ -601,7 +595,8 @@ class StatusView @JvmOverloads constructor(
601595 extraWidth * = 2
602596 }
603597
604- return ((statusCount * (2 * (circleRadius + (circleStrokeWidth/ 2 )))) + ((statusCount - 1 ) * ( lineLengthComputed + (lineGap * 2 ))) + extraWidth).toInt()
598+ return ((statusCount * (2 * (circleRadius + (circleStrokeWidth/ 2 )))) +
599+ ((statusCount - 1 ) * ( lineLengthComputed + (lineGap * 2 ))) + extraWidth).toInt()
605600 }
606601
607602
@@ -626,23 +621,16 @@ class StatusView @JvmOverloads constructor(
626621 val desiredWidth = paddingLeft + paddingRight + suggestedMinimumWidth
627622 val desiredHeight = paddingTop + paddingBottom + suggestedMinimumHeight
628623
629- val measureSpecWidth = MeasureSpec .getMode(widthMeasureSpec)
630- val measureSpecHeight = MeasureSpec .getMode(heightMeasureSpec)
631- /* if(measureSpecHeight!=MeasureSpec.AT_MOST || measureSpecWidth!=MeasureSpec.AT_MOST){
624+ /* val measureSpecWidth = MeasureSpec.getMode(widthMeasureSpec)
625+ val measureSpecHeight = MeasureSpec.getMode(heightMeasureSpec)
626+ */ /* if(measureSpecHeight!=MeasureSpec.AT_MOST || measureSpecWidth!=MeasureSpec.AT_MOST){
632627 throw IllegalStateException("Width and height should be wrap_content")
633- }*/
634-
635-
636-
628+ }*/ /*
629+ */
637630 val measuredWidth = resolveSize(desiredWidth, widthMeasureSpec)
638631 val measuredHeight = resolveSize(desiredHeight, heightMeasureSpec)
639632
640-
641-
642633 setMeasuredDimension(measuredWidth, measuredHeight)
643-
644-
645-
646634 }
647635
648636 override fun onLayout (changed : Boolean , left : Int , top : Int , right : Int , bottom : Int ) {
@@ -702,14 +690,12 @@ class StatusView @JvmOverloads constructor(
702690 */
703691 private fun setDrawingDimensions () {
704692
705- /* *
706- * For keeping reference where last point was drawn
707- */
708- val lastPoint = PointF ()
693+
694+ val lastPoint = PointF ()// For keeping reference where last point was drawn
709695 lastPoint.x = paddingLeft.toFloat() + (circleStrokeWidth / 2 )
710696 lastPoint.y = paddingTop.toFloat() + (circleRadius + (circleStrokeWidth / 2 ))
711697 if (isShowingCurrentStatus()) lastPoint.y + = currentStatusRadius- circleRadius
712- for (i in 0 until statusCount) {
698+ for (pos in 0 until statusCount) {
713699
714700 var circleStrokePaint: Paint ?
715701 var circleFillPaint : Paint ?
@@ -718,14 +704,14 @@ class StatusView @JvmOverloads constructor(
718704 var itemDrawable: Drawable ?
719705
720706 var circleRadius = this .circleRadius
721- if (isShowingCurrentStatus() && i == (currentCount- 1 )){
707+ if (isShowingCurrentStatus() && pos == (currentCount- 1 )){
722708 circleRadius = currentStatusRadius
723709 circleStrokePaint = mCircleStrokePaintCurrent
724710 circleFillPaint = mCircleFillPaintCurrent
725711 textPaintLabel = mTextPaintLabelCurrent
726712 linePaint = mLinePaintCurrent
727713 itemDrawable = currentDrawable
728- }else if (isShowingIncompleteStatus() && i in (currentCount).. statusCount) {
714+ }else if (isShowingIncompleteStatus() && pos in (currentCount).. statusCount) {
729715 circleStrokePaint = mCircleStrokePaintIncomplete
730716 circleFillPaint = mCircleFillPaintIncomplete
731717 textPaintLabel = mTextPaintLabelsIncomplete
@@ -747,10 +733,9 @@ class StatusView @JvmOverloads constructor(
747733 var labelItemText: StatusView .StatusItemText ? = null
748734
749735
750- if (i == 0 ){
736+ if (pos == 0 ){
751737 if (statusData.size> 0 ){
752- val minWidthForExtreme = 2 * circleRadius + circleStrokeWidth
753- lastPoint.x+ = Math .max(0.0f , (statusData[0 ].width - minWidthForExtreme)/ 2 )
738+ lastPoint.x+ = Math .max(0.0f , (statusData[0 ].width - minStatusWidthExtremes(pos))/ 2 )
754739 }
755740 }else {
756741 lastPoint.x + = lineGap
@@ -762,9 +747,9 @@ class StatusView @JvmOverloads constructor(
762747 val circleItem = CircleItem (PointF ((lastPoint.x + circleRadius), lastPoint.y), circleRadius, circleStrokePaint, circleFillPaint)
763748 lastPoint.x + = ((circleRadius) * 2.0f ) + (circleStrokeWidth / 2 )
764749
765- if (i < statusData.size){
750+ if (pos < statusData.size){
766751 val radii = if (isShowingCurrentStatus() && alignStatusWithCurrent) currentStatusRadius else circleRadius
767- labelItemText = StatusItemText (circleItem.center.x, circleItem.center.y + radii + circleStrokeWidth/ 2 + labelTopMargin, statusData[i ].staticLayout)
752+ labelItemText = StatusItemText (circleItem.center.x, circleItem.center.y + radii + circleStrokeWidth/ 2 + labelTopMargin, statusData[pos ].staticLayout)
768753 }
769754
770755
@@ -778,7 +763,7 @@ class StatusView @JvmOverloads constructor(
778763 statusItemText = LabelItemText (drawableItem = DrawableItem (drawableRect, itemDrawable))
779764
780765 } else if (drawLabels) {
781- val text: String = (i + 1 ).toString()
766+ val text: String = (pos + 1 ).toString()
782767 val measuringRect = Rect ()
783768 textPaintLabel.getTextBounds(text, 0 , text.length, measuringRect)
784769 statusItemText = LabelItemText (text, textPaintLabel, circleItem.center.x, circleItem.center.y - measuringRect.exactCenterY())
@@ -794,15 +779,13 @@ class StatusView @JvmOverloads constructor(
794779
795780
796781 /* *
797- * @param lineLength lineLength of StatusView
798- * @param circleRadius circleRadius Of StatusView
799782 *
800- * For non-extreme statuses:
801- * Function sets the width value to circleRadius + linelength/2 (left side) + linelength/2 (rightSide)
783+ For non-extreme statuses:
784+ * Function sets the width value to minStatusWidth
802785 *
803786 * For extreme statuses:
804- * It calculates value using findAdjustWidthForExtremes() as assigning the same width as
805- * non-extreme may end up giving extraPadding to the view
787+ * It calculates min of extreme width required in bounds of lineLength as
788+ * directly adding minStatusWidth may end up adding extra padding to view
806789 */
807790 private fun setWidthDataForObeyingLineLength ():Float {
808791 var adjacentExtraWidthForView = 0.0f
@@ -811,7 +794,7 @@ class StatusView @JvmOverloads constructor(
811794
812795 val item = statusData[pos]
813796 when (pos) {
814- 0 , statusCount - 1 -> {
797+ 0 , statusCountIndex() -> {
815798
816799 val minStatusWidthExtremes = minStatusWidthExtremes(pos)
817800 val minStatusWidth = minStatusWidth(pos)
@@ -835,6 +818,12 @@ class StatusView @JvmOverloads constructor(
835818 }
836819
837820
821+ /* *
822+ * Sets required width in status data for every status
823+ * This method increases linelength if required i.e
824+ * it makes sure every line of status word does not cross over to next line
825+ *
826+ */
838827 private fun setWidthDataForObeyingStatusText (): Float {
839828 var extraWidth = 0.0f
840829
@@ -847,6 +836,8 @@ class StatusView @JvmOverloads constructor(
847836 }
848837
849838 widestLineData.subordinateWidestStatus?.run {
839+ // in case increasing linelength as per widest Status does not satisfy statusWidth for second widest
840+ // This can occur if widestStatus belongs to currentStatus and has a zoomed radius
850841 val minStatusWidth = minStatusWidth(pos)
851842
852843 if (width > minStatusWidth) {
@@ -855,11 +846,11 @@ class StatusView @JvmOverloads constructor(
855846 }
856847
857848
858- var addPadding = false
849+ var addMinStatusMargin = false
859850 for (pos in 0 until statusData.size) {
860851 val item = statusData[pos]
861852 when (pos) {
862- 0 , (statusCount - 1 ) -> {
853+ 0 , statusCountIndex( ) -> {
863854
864855 item.width = if (pos == 0 ) {
865856 widestLineData.extremeLeftStatusWidth
@@ -876,14 +867,16 @@ class StatusView @JvmOverloads constructor(
876867 }
877868 else -> item.width = widestLineData.widestStatus.width
878869 }
879- if (minMarginStatusText> 0 && ! addPadding && pos in 1 until statusData.size){
880- if (minStatusWidth(pos)+ minStatusWidth(pos- 1 ) - (item.width+ statusData[pos- 1 ].width)< minMarginStatusText){
881- addPadding = true
870+
871+ if (minMarginStatusText> 0 && ! addMinStatusMargin && pos in 1 until statusData.size){
872+ if (minStatusWidth(pos)+ minStatusWidth(pos- 1 ) - (item.width+ statusData[pos- 1 ].width)< minMarginStatusText){
873+ addMinStatusMargin = true
882874 }
883875
884876 }
885877 }
886- if (addPadding){
878+ if (addMinStatusMargin){
879+ // add additional padding only if it is required
887880 lineLengthComputed+ = minMarginStatusText
888881 }
889882 return extraWidth
@@ -912,7 +905,7 @@ class StatusView @JvmOverloads constructor(
912905 }
913906
914907 /* *
915- * Maximum width that a text would need
908+ * Maximum width that a text would need to be drawn
916909 */
917910 private fun getTextWidth (paint : Paint , text : String ):Float {
918911 return paint.measureText(text)
@@ -947,11 +940,29 @@ class StatusView @JvmOverloads constructor(
947940 }
948941
949942
943+ /* *
944+ * This class stores info for widest Status info length which helps in deciding correct line length of StatusView
945+ * @param widestStatus (widest line in all the texts)
946+ * @param subordinateWidestStatus second Widest Status this is only set if widest status belongs to currentStatus
947+ * @param extremeLeftStatusWidth Widest line in status at extreme left
948+ * @param extremeRightStatusWidth Widest line in status at extreme right
949+ */
950950 class StatusTextWidthInfo (var widestStatus : StatusWidth , var subordinateWidestStatus : StatusWidth ? =null ,
951951 var extremeLeftStatusWidth : Float =0.0f , var extremeRightStatusWidth : Float =0.0f )
952952
953+ /* *
954+ * Stores Status Width Data
955+ * @param width widestStatus
956+ * @param pos Status position
957+ */
953958 class StatusWidth (var width : Float = 0.0f , var pos : Int =-1 )
954959
960+ /* *
961+ * Calculates parameters described in StatusTextWidthInfo
962+ * @param list List of string for all statuses
963+ * @param paint Paint required to draw the statuses
964+ *
965+ */
955966 private fun getStatusTextWidthInfo (list : List <String >, paint : TextPaint ):StatusTextWidthInfo {
956967
957968 val widestStatus = StatusWidth ()
@@ -995,6 +1006,11 @@ class StatusView @JvmOverloads constructor(
9951006
9961007 }
9971008
1009+ /* *
1010+ * @param text Status Text
1011+ * @param paint Text paint for the text
1012+ * @return widest line in a particular status
1013+ */
9981014 private fun getStatusWidth (text : String , paint : TextPaint ):Float {
9991015
10001016 val arr: List <String > = text.split(' \n ' )
@@ -1020,13 +1036,19 @@ class StatusView @JvmOverloads constructor(
10201036 }
10211037
10221038
1039+ /* *
1040+ * actual position in list for currentCount
1041+ */
10231042 private fun currentCountIndex () = currentCount- 1
10241043
1044+ /* *
1045+ * actual position in list for statusCount
1046+ */
10251047 private fun statusCountIndex () = statusCount- 1
10261048
10271049
10281050 /* *
1029- * Delegate property used to requestLayout if any value changed
1051+ * Delegate property used to requestLayout on value set after executing a custom function
10301052 */
10311053 inner class OnLayoutProp <T > (private var field : T , private inline var func : ()-> Unit ={}){
10321054 operator fun setValue (thisRef : Any? ,p : KProperty <* >,v : T ) {
@@ -1046,7 +1068,7 @@ class StatusView @JvmOverloads constructor(
10461068 }
10471069
10481070 /* *
1049- * Delegate Property used to invalidate a layout after executing a custom function
1071+ * Delegate Property used to invalidate on value set after executing a custom function
10501072 */
10511073 inner class OnValidateProp <T > (private var field : T , private inline var func : ()-> Unit ={}){
10521074 operator fun setValue (thisRef : Any? ,p : KProperty <* >,v : T ) {
0 commit comments