Implement collapsible habit groups

pull/2020/head
Dharanish 1 year ago
parent d9213ed239
commit 811b818590

@ -47,7 +47,7 @@ class AddButtonView(
private inner class Drawer {
private val rect = RectF()
private val highContrastColor = sres.getColor(R.attr.contrast100)
private val highContrastColor = sres.getColor(R.attr.contrast80)
private val paint = TextPaint().apply {
typeface = getFontAwesome()

@ -0,0 +1,101 @@
package org.isoron.uhabits.activities.habits.list.views
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import android.text.TextPaint
import android.view.View
import org.isoron.uhabits.R
import org.isoron.uhabits.activities.habits.list.ListHabitsActivity
import org.isoron.uhabits.core.models.HabitGroup
import org.isoron.uhabits.core.models.ModelObservable
import org.isoron.uhabits.utils.getFontAwesome
import org.isoron.uhabits.utils.sp
import org.isoron.uhabits.utils.sres
import org.isoron.uhabits.utils.toMeasureSpec
class CollapseButtonView(
context: Context,
var habitGroup: HabitGroup?
) : View(context),
View.OnClickListener,
ModelObservable.Listener {
private var drawer = Drawer()
var collapsed = false
init {
setOnClickListener(this)
}
override fun onClick(v: View) {
collapsed = !collapsed
habitGroup!!.collapsed = collapsed
drawer.rotate()
invalidate()
(context as ListHabitsActivity).component.listHabitsMenu.behavior.onPreferencesChanged()
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
drawer.draw(canvas)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val height = resources.getDimensionPixelSize(R.dimen.checkmarkHeight)
val width = resources.getDimensionPixelSize(R.dimen.checkmarkWidth)
super.onMeasure(
width.toMeasureSpec(MeasureSpec.EXACTLY),
height.toMeasureSpec(MeasureSpec.EXACTLY)
)
}
private inner class Drawer {
private val rect = RectF()
private val highContrastColor = sres.getColor(R.attr.contrast100)
private var rotationAngle = 0f
private var offset_y = 0.4f
private var offset_x = 0f
private val paint = TextPaint().apply {
typeface = getFontAwesome()
isAntiAlias = true
textAlign = Paint.Align.CENTER
}
fun rotate() {
if (rotationAngle == 0f) {
rotationAngle = 90f
offset_y = 0f
offset_x = -0.4f
} else {
rotationAngle = 0f
offset_y = 0.4f
offset_x = 0f
}
}
fun draw(canvas: Canvas) {
paint.color = highContrastColor
val id = R.string.fa_angle_down
paint.textSize = sp(12.0f)
paint.strokeWidth = 0f
paint.style = Paint.Style.FILL
val label = resources.getString(id)
val em = paint.measureText("m")
rect.set(0f, 0f, width.toFloat(), height.toFloat())
rect.offset(offset_x * em, offset_y * em)
canvas.save() // Save the current state of the canvas
canvas.rotate(rotationAngle, rect.centerX(), rect.centerY()) // Rotate the canvas
canvas.drawText(label, rect.centerX(), rect.centerY(), paint)
canvas.restore()
}
}
override fun onModelChange() {}
}

@ -42,6 +42,7 @@ class HabitGroupCardView(
field = newHabitGroup
if (newHabitGroup != null) copyAttributesFrom(newHabitGroup)
addButtonView.habitGroup = newHabitGroup
collapseButtonView.habitGroup = newHabitGroup
}
var score
@ -52,6 +53,7 @@ class HabitGroupCardView(
}
var addButtonView: AddButtonView
var collapseButtonView: CollapseButtonView
private var innerFrame: LinearLayout
private var label: TextView
private var scoreRing: RingView
@ -81,6 +83,7 @@ class HabitGroupCardView(
}
addButtonView = AddButtonView(context, habitGroup)
collapseButtonView = CollapseButtonView(context, habitGroup)
innerFrame = LinearLayout(context).apply {
gravity = Gravity.CENTER_VERTICAL
@ -91,6 +94,7 @@ class HabitGroupCardView(
addView(scoreRing)
addView(label)
addView(addButtonView)
addView(collapseButtonView)
setOnTouchListener { v, event ->
v.background.setHotspot(event.x, event.y)
@ -142,6 +146,12 @@ class HabitGroupCardView(
scoreRing.apply {
setColor(c)
}
if (collapseButtonView.collapsed) {
addButtonView.visibility = GONE
} else {
addButtonView.visibility = VISIBLE
}
}
private fun updateBackground(isSelected: Boolean) {

@ -25,6 +25,8 @@
<string translatable="false" name="fa_check">&#xf00c;</string>
<string translatable="false" name="fa_times">&#xf00d;</string>
<string translatable="false" name="fa_plus">&#xf067;</string>
<string translatable="false" name="fa_angle_left">&#xf053;</string>
<string translatable="false" name="fa_angle_down">&#xf078;</string>
<string translatable="false" name="fa_skipped">&#xf068;</string>
<string translatable="false" name="fa_bell_o">&#xf0f3;</string>
<string translatable="false" name="fa_calendar">&#xf073;</string>

@ -56,6 +56,8 @@ data class Habit(
val uriString: String
get() = "content://org.isoron.uhabits/habit/$id"
var collapsed = false
fun isSubHabit(): Boolean = groupUUID != null
fun hasReminder(): Boolean = reminder != null

@ -45,6 +45,14 @@ data class HabitGroup(
val uriString: String
get() = "content://org.isoron.uhabits/habitgroup/$id"
var collapsed = false
set(value) {
if (value != field) {
field = value
habitList.forEach { it.collapsed = value }
}
}
fun hasReminder(): Boolean = reminder != null
fun isCompletedToday(): Boolean {

@ -29,6 +29,7 @@ data class HabitMatcher(
if (isReminderRequired && !habit.hasReminder()) return false
if (!isCompletedAllowed && habit.isCompletedToday()) return false
if (!isEnteredAllowed && habit.isEnteredToday()) return false
if (habit.collapsed) return false
return true
}

@ -47,6 +47,7 @@ class MemoryHabitGroupList : HabitGroupList {
parent.observable.addListener { loadFromParent() }
for (hgr in parent.list) {
hgr.habitList.observable.addListener { loadFromParent() }
hgr.observable.notifyListeners()
}
loadFromParent()
}

Loading…
Cancel
Save