Skip to content

Commit

Permalink
Always use square icon for Templates
Browse files Browse the repository at this point in the history
Fixes #484.
  • Loading branch information
FWDekker committed Oct 22, 2023
1 parent f9bbeb1 commit e461cbc
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 52 deletions.
23 changes: 12 additions & 11 deletions src/main/kotlin/com/fwdekker/randomness/Icons.kt
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,6 @@ data class TypeIcon(val base: Icon, val text: String, val colors: List<Color>) :
}


/**
* Returns an icon that describes both this icon's type and [other]'s type.
*/
fun combineWith(other: TypeIcon) =
TypeIcon(
Icons.TEMPLATE,
if (this.text == other.text) this.text else "",
this.colors + other.colors
)


/**
* Paints the colored text icon.
*
Expand Down Expand Up @@ -133,6 +122,18 @@ data class TypeIcon(val base: Icon, val text: String, val colors: List<Color>) :
* The scale of the text inside the icon relative to the icon's size.
*/
const val FONT_SIZE = 12f / 32f


/**
* Returns a single icon that describes all [icons], or `null` if [icons] is empty.
*/
fun combine(icons: Collection<TypeIcon>): TypeIcon? =
if (icons.isEmpty()) null
else TypeIcon(
Icons.TEMPLATE,
if (icons.map { it.text }.toSet().size == 1) icons.first().text else "",
icons.flatMap { it.colors }
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ data class Template(
val arrayDecorator: ArrayDecorator = DEFAULT_ARRAY_DECORATOR,
) : Scheme() {
override val typeIcon
get() = schemes.mapNotNull { it.typeIcon }.reduceOrNull { acc, icon -> acc.combineWith(icon) } ?: DEFAULT_ICON
get() = TypeIcon.combine(schemes.mapNotNull { it.typeIcon }) ?: DEFAULT_ICON
override val decorators get() = listOf(arrayDecorator)

/**
Expand Down
90 changes: 59 additions & 31 deletions src/test/kotlin/com/fwdekker/randomness/IconsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.beEmpty
import io.kotest.matchers.collections.shouldContainExactly
import io.kotest.matchers.nulls.beNull
import io.kotest.matchers.should
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNot
Expand All @@ -33,37 +34,6 @@ object TypeIconTest : FunSpec({
}


context("combineWith") {
test("returns a template TypeIcon") {
val icon1 = TypeIcon(PlainIcon(), "text1", listOf(Color.GREEN))
val icon2 = TypeIcon(PlainIcon(), "text2", listOf(Color.RED))

icon1.combineWith(icon2).base shouldBe Icons.TEMPLATE
}

test("retains the text if it is the same for both icons") {
val icon1 = TypeIcon(PlainIcon(), "text", listOf(Color.PINK))
val icon2 = TypeIcon(PlainIcon(), "text", listOf(Color.CYAN))

icon1.combineWith(icon2).text shouldBe "text"
}

test("removes the text if it is different for the icons") {
val icon1 = TypeIcon(PlainIcon(), "text1", listOf(Color.GRAY))
val icon2 = TypeIcon(PlainIcon(), "text2", listOf(Color.ORANGE))

icon1.combineWith(icon2).text shouldBe ""
}

test("appends the colors of the combined icons") {
val icon1 = TypeIcon(PlainIcon(), "text1", listOf(Color.BLUE, Color.WHITE))
val icon2 = TypeIcon(PlainIcon(), "text2", listOf(Color.RED, Color.PINK))

icon1.combineWith(icon2).colors shouldContainExactly listOf(Color.BLUE, Color.WHITE, Color.RED, Color.PINK)
}
}


context("paintIcon") {
tags(Tags.SWING)

Expand Down Expand Up @@ -98,6 +68,64 @@ object TypeIconTest : FunSpec({
image.getRGB(0, 0, 32, 32, null, 0, 32).filter { it != 0 } shouldNot beEmpty()
}
}


context("combine") {
test("returns `null` if no icons are given to combine") {
TypeIcon.combine(emptyList()) should beNull()
}

test("returns a template icon for a single icon") {
val icons = listOf(TypeIcon(PlainIcon(), "text", listOf(Color.LIGHT_GRAY)))

TypeIcon.combine(icons)!!.base shouldBe Icons.TEMPLATE
}

test("returns a template icon for multiple icons") {
val icons =
listOf(
TypeIcon(PlainIcon(), "text1", listOf(Color.GREEN)),
TypeIcon(PlainIcon(), "text2", listOf(Color.RED)),
TypeIcon(PlainIcon(), "text3", listOf(Color.MAGENTA)),
)

TypeIcon.combine(icons)!!.base shouldBe Icons.TEMPLATE
}

test("retains the text if it is the same for all icons") {
val icons =
listOf(
TypeIcon(PlainIcon(), "text", listOf(Color.PINK)),
TypeIcon(PlainIcon(), "text", listOf(Color.CYAN)),
TypeIcon(PlainIcon(), "text", listOf(Color.GREEN)),
)

TypeIcon.combine(icons)!!.text shouldBe "text"
}

test("removes the text if it is not the same for all icons") {
val icons =
listOf(
TypeIcon(PlainIcon(), "text1", listOf(Color.GRAY)),
TypeIcon(PlainIcon(), "text2", listOf(Color.ORANGE)),
TypeIcon(PlainIcon(), "text2", listOf(Color.BLUE)),
)

TypeIcon.combine(icons)!!.text shouldBe ""
}

test("appends the colors of the combined icons") {
val icons =
listOf(
TypeIcon(PlainIcon(), "text1", listOf(Color.BLUE, Color.WHITE)),
TypeIcon(PlainIcon(), "text2", listOf(Color.RED)),
TypeIcon(PlainIcon(), "text3", listOf(Color.PINK, Color.BLACK, Color.BLUE)),
)

TypeIcon.combine(icons)!!.colors shouldContainExactly
listOf(Color.BLUE, Color.WHITE, Color.RED, Color.PINK, Color.BLACK, Color.BLUE)
}
}
})

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,11 @@ object TemplateSettingsActionTest : FunSpec({
}

test("uses the template's icon if the template is not null") {
val icon = TypeIcon(Icons.SCHEME, "war", listOf(Color.GREEN))
val icon = TypeIcon(Icons.SCHEME, "wax", listOf(Color.GREEN))
val template = Template("subject", mutableListOf(DummyScheme().also { it.typeIcon = icon }))
val action = TemplateSettingsAction(template)

(action.templatePresentation.icon as OverlayedIcon).base shouldBe icon
(action.templatePresentation.icon as OverlayedIcon).base shouldBe template.typeIcon
}
}
}
Expand Down
17 changes: 10 additions & 7 deletions src/test/kotlin/com/fwdekker/randomness/template/TemplateTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.fwdekker.randomness.template

import com.fwdekker.randomness.CapitalizationMode
import com.fwdekker.randomness.DataGenerationException
import com.fwdekker.randomness.Icons
import com.fwdekker.randomness.Settings
import com.fwdekker.randomness.array.ArrayDecorator
import com.fwdekker.randomness.integer.IntegerScheme
Expand Down Expand Up @@ -30,11 +31,10 @@ object TemplateTest : FunSpec({


context("typeIcon") {
test("returns the single scheme's icon if that scheme has an icon") {
val scheme = IntegerScheme()
val template = Template(schemes = mutableListOf(scheme))
test("returns the default icon if the template contains no schemes") {
val template = Template()

template.typeIcon shouldBe scheme.typeIcon
template.typeIcon shouldBe Template.DEFAULT_ICON
}

test("returns the default icon if the single scheme has no icon") {
Expand All @@ -44,10 +44,13 @@ object TemplateTest : FunSpec({
template.typeIcon shouldBe Template.DEFAULT_ICON
}

test("returns the default icon if no scheme is present") {
val template = Template()
test("returns a template version of the single scheme's TypeIcon") {
val scheme = IntegerScheme()
val template = Template(schemes = mutableListOf(scheme))

template.typeIcon shouldBe Template.DEFAULT_ICON
template.typeIcon.base shouldBe Icons.TEMPLATE
template.typeIcon.text shouldBe scheme.typeIcon.text
template.typeIcon.colors shouldBe scheme.typeIcon.colors
}

test("returns the scheme's combined icon if multiple are present") {
Expand Down

0 comments on commit e461cbc

Please sign in to comment.