Skip to content

Commit

Permalink
feat: btn text now properly reacts to background changes
Browse files Browse the repository at this point in the history
Signed-off-by: Craig Bassett <[email protected]>
  • Loading branch information
cadriel committed Mar 6, 2021
1 parent 49bc4f5 commit a3a5256
Show file tree
Hide file tree
Showing 13 changed files with 100 additions and 63 deletions.
5 changes: 2 additions & 3 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ export default class App extends Mixins(UtilsMixin) {
// }
mounted () {
this.$vuetify.theme.dark = this.$store.state.config.uiSettings.theme.darkMode
EventBus.$on('flashMessage', (payload: FlashMessageType) => {
this.flashMessage.text = (payload && payload.text) || undefined
this.flashMessage.type = (payload && payload.type) || undefined
Expand Down Expand Up @@ -110,7 +109,7 @@ export default class App extends Mixins(UtilsMixin) {
if (this.printerPrinting) {
// Render the progress indicator.
const favIconSize = 64
const primaryColor = theme.colors.primary
const primaryColor = theme.currentTheme.primary
const secondaryColor = 'rgba(255, 255, 255, 0.10)'
const canvas = document.createElement('canvas') as HTMLCanvasElement
const context = canvas.getContext('2d') as CanvasRenderingContext2D
Expand Down Expand Up @@ -145,7 +144,7 @@ export default class App extends Mixins(UtilsMixin) {
}
// Build a base64 encoded version of our svg with the correct theme color.
const svg_xml = 'data:image/svg+xml;base64,' + btoa(`<svg width="56" height="64" viewBox="0 0 314 361" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g transform="translate(-162.000000, -110.000000)"><path d="M234.444,327.531 L309.066,389.594 C309.906,390.313 310.81,390.928 311.759,391.436 L311.759,391.436 L311.771,391.442 L312.055,391.589 L312.163,391.643 L312.356,391.737 L312.534,391.821 L312.668,391.883 L312.902,391.987 L312.974,392.017 C314.656,392.733 316.433,393.128 318.217,393.206 L318.217,393.206 L318.278,393.209 L318.562,393.218 L318.674,393.22 L318.904,393.221 L319.104,393.22 L319.231,393.218 L319.529,393.208 L319.571,393.207 C321.359,393.128 323.142,392.733 324.829,392.013 L324.829,392.013 L324.877,391.993 L325.143,391.875 L325.244,391.829 L325.438,391.737 L325.643,391.638 L325.731,391.593 L326.012,391.447 L326.042,391.432 C326.989,390.925 327.891,390.311 328.729,389.593 L328.729,389.593 L398.493,331.574 L434.768,355.517 L318.896,470.422 L198.4,350.923 L234.444,327.531 Z M237.067,234.697 L310.465,281.908 C313.075,283.623 315.986,284.481 318.897,284.482 C321.805,284.482 324.713,283.626 327.325,281.912 L327.325,281.912 L400.727,234.702 L456.849,263.367 L318.897,378.093 L180.945,263.359 L237.067,234.697 Z M318.897,110.68 L475.771,168.448 L318.897,269.344 L162.024,168.44 L318.897,110.68 Z" id="Combined-Shape" fill="${theme.colors.primaryOffset}"></path><path d="M318.897,110.68 L475.771,168.448 L319,269.278 L319,111 L318.028,111 L318.897,110.68 Z" id="Combined-Shape" fill="${theme.colors.primary}"></path><path d="M400.727,234.702 L456.849,263.367 L319,378.007 L319.000106,284.481641 C321.735222,284.46261 324.467243,283.686291 326.949875,282.151021 L327.325,281.912 L400.727,234.702 Z" id="Combined-Shape" fill="${theme.colors.primary}"></path><path d="M398.493,331.574 L434.768,355.517 L319,470.319 L319,393.22 L319.104,393.22 L319.231,393.218 L319.529,393.208 L319.571,393.207 C321.359,393.128 323.142,392.733 324.829,392.013 L324.829,392.013 L324.877,391.993 L325.143,391.875 L325.244,391.829 L325.438,391.737 L325.643,391.638 L325.731,391.593 L326.012,391.447 L326.042,391.432 C326.989,390.925 327.891,390.311 328.729,389.593 L328.729,389.593 L398.493,331.574 Z" id="Combined-Shape" fill="${theme.colors.primary}"></path></g></svg>`)
const svg_xml = 'data:image/svg+xml;base64,' + btoa(`<svg width="56" height="64" viewBox="0 0 314 361" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g transform="translate(-162.000000, -110.000000)"><path d="M234.444,327.531 L309.066,389.594 C309.906,390.313 310.81,390.928 311.759,391.436 L311.759,391.436 L311.771,391.442 L312.055,391.589 L312.163,391.643 L312.356,391.737 L312.534,391.821 L312.668,391.883 L312.902,391.987 L312.974,392.017 C314.656,392.733 316.433,393.128 318.217,393.206 L318.217,393.206 L318.278,393.209 L318.562,393.218 L318.674,393.22 L318.904,393.221 L319.104,393.22 L319.231,393.218 L319.529,393.208 L319.571,393.207 C321.359,393.128 323.142,392.733 324.829,392.013 L324.829,392.013 L324.877,391.993 L325.143,391.875 L325.244,391.829 L325.438,391.737 L325.643,391.638 L325.731,391.593 L326.012,391.447 L326.042,391.432 C326.989,390.925 327.891,390.311 328.729,389.593 L328.729,389.593 L398.493,331.574 L434.768,355.517 L318.896,470.422 L198.4,350.923 L234.444,327.531 Z M237.067,234.697 L310.465,281.908 C313.075,283.623 315.986,284.481 318.897,284.482 C321.805,284.482 324.713,283.626 327.325,281.912 L327.325,281.912 L400.727,234.702 L456.849,263.367 L318.897,378.093 L180.945,263.359 L237.067,234.697 Z M318.897,110.68 L475.771,168.448 L318.897,269.344 L162.024,168.44 L318.897,110.68 Z" id="Combined-Shape" fill="${theme.currentTheme.primaryOffset}"></path><path d="M318.897,110.68 L475.771,168.448 L319,269.278 L319,111 L318.028,111 L318.897,110.68 Z" id="Combined-Shape" fill="${theme.currentTheme.primary}"></path><path d="M400.727,234.702 L456.849,263.367 L319,378.007 L319.000106,284.481641 C321.735222,284.46261 324.467243,283.686291 326.949875,282.151021 L327.325,281.912 L400.727,234.702 Z" id="Combined-Shape" fill="${theme.currentTheme.primary}"></path><path d="M398.493,331.574 L434.768,355.517 L319,470.319 L319,393.22 L319.104,393.22 L319.231,393.218 L319.529,393.208 L319.571,393.207 C321.359,393.128 323.142,392.733 324.829,392.013 L324.829,392.013 L324.877,391.993 L325.143,391.875 L325.244,391.829 L325.438,391.737 L325.643,391.638 L325.731,391.593 L326.012,391.447 L326.042,391.432 C326.989,390.925 327.891,390.311 328.729,389.593 L328.729,389.593 L398.493,331.574 Z" id="Combined-Shape" fill="${theme.currentTheme.primary}"></path></g></svg>`)
return {
'link[rel="icon"][sizes="32x32"]': {
Expand Down
4 changes: 2 additions & 2 deletions src/components/AppBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
class="shrink mr-4 mt-1 color-filter"
width="35"
height="40"
:primary-color="theme.colors.primary"
:secondary-color="theme.colors.primaryOffset"
:primary-color="theme.currentTheme.primary"
:secondary-color="theme.currentTheme.primaryOffset"
></fluidd-icon>
</router-link>
<v-toolbar-title
Expand Down
26 changes: 13 additions & 13 deletions src/components/cards/settings/ThemeSettingsCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<!-- <pre>{{ color }}</pre> -->

<v-color-picker
:value="theme.colors.primary"
:value="theme.currentTheme.primary"
@update:color="handlePrimaryColorChange"
mode="hexa"
hide-mode-switch
Expand All @@ -22,7 +22,7 @@
<v-switch
@click.native.stop
label="Dark Mode"
v-model="theme.darkMode"
v-model="theme.isDark"
@change="handleDarkModeChange"
hide-details
class="mb-5"
Expand Down Expand Up @@ -54,36 +54,36 @@ export default class ThemeSettingsCard extends Mixins(UtilsMixin) {
}
setTheme (value: ThemeConfig) {
this.$vuetify.theme.dark = value.darkMode
this.$vuetify.theme.currentTheme.primary = value.colors.primary
this.$vuetify.theme.dark = value.isDark
this.$vuetify.theme.currentTheme.primary = value.currentTheme.primary
}
handlePrimaryColorChange = debounce((value: { hex: string }) => {
this.setTheme({
darkMode: this.theme.darkMode,
colors: {
isDark: this.theme.isDark,
currentTheme: {
primary: value.hex
}
})
this.$store.dispatch('config/saveGeneric', { key: 'uiSettings.theme.colors.primary', value: value.hex })
this.$store.dispatch('config/saveGeneric', { key: 'uiSettings.theme.currentTheme.primary', value: value.hex })
}, 500)
handleDarkModeChange (value: boolean) {
this.setTheme({
darkMode: value,
colors: {
primary: this.theme.colors.primary
isDark: value,
currentTheme: {
primary: this.theme.currentTheme.primary
}
})
this.$store.dispatch('config/saveGeneric', { key: 'uiSettings.theme.darkMode', value })
this.$store.dispatch('config/saveGeneric', { key: 'uiSettings.theme.isDark', value })
}
handleReset () {
const theme: ThemeConfig = {
darkMode: true,
colors: {
isDark: true,
currentTheme: {
primary: '#2196F3'
}
}
Expand Down
50 changes: 30 additions & 20 deletions src/components/inputs/Btn.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
<template>
<v-btn
:elevation="2"
:disabled="disabled"
:loading="loading"
:color="(color) ? color : 'default'"
:block="block"
:dark="dark"
:depressed="depressed"
:fab="fab"
:icon="icon"
:loading="loading"
:outlined="outlined"
:rounded="rounded"
:plain="plain"
:retainFocusOnClick="retainFocusOnClick"
:rounded="rounded"
:tile="tile"
:class="classes"
:disabled="disabled"
:color="(color) ? color : 'default'"
:min-width="minWidth"
:class="{ 'grey--text text--darken-3': !colorIsDark, 'grey--text text--lighten-2': colorIsDark }"
@click="$emit('click', $event)"
>
<slot></slot>
Expand All @@ -23,22 +24,16 @@
import { Component, Vue, Prop } from 'vue-property-decorator'
@Component({})
export default class Btn extends Vue {
@Prop({ default: false })
color!: string
export default class FluiddBtn extends Vue {
@Prop({ default: false })
block!: boolean
@Prop({ default: false })
dark!: boolean
depressed!: boolean
@Prop({ default: false })
fab!: boolean
@Prop({ default: false })
plain!: boolean
@Prop({ default: false })
icon!: boolean
Expand All @@ -48,18 +43,33 @@ export default class Btn extends Vue {
@Prop({ default: false })
outlined!: boolean
@Prop({ default: false })
plain!: boolean
@Prop({ default: false })
retainFocusOnClick!: boolean
@Prop({ default: false })
rounded!: boolean
@Prop({ default: false })
tile!: boolean
get classes () {
return ''
}
@Prop({ default: false })
disabled!: string
// set classes (val: string) {
@Prop({ default: false })
color!: string
@Prop({ type: Number })
minWidth!: number
// }
get theme () {
return this.$store.getters['config/getTheme']
}
get colorIsDark () {
return this.$filters.colorDark(this.theme.currentTheme[this.color])
}
}
</script>
12 changes: 8 additions & 4 deletions src/components/inputs/BtnToolheadMove.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@
<v-tooltip
top>
<template v-slot:activator="{ on, attrs }">
<v-btn
<btn
@click="$emit('click')"
:disabled="disabled"
:elevation="2"
:min-width="40"
:loading="loading"
:color="color"
v-bind="(tooltip !== '') ? attrs : undefined"
v-on="(tooltip !== '') ? on : undefined"
class="px-2">
<v-icon :small="smallIcon" v-if="icon" :class="{ 'mr-1': hasDefaultSlot }">{{ icon }}</v-icon>
<v-icon
v-if="icon"
:small="smallIcon"
:class="{ 'mr-1': hasDefaultSlot }">
{{ icon }}
</v-icon>
<slot></slot>
</v-btn>
</btn>
</template>
<span>{{ tooltip }}</span>
</v-tooltip>
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/EChartsWidget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export default class EChartsWidget extends Vue {
}
initOptions () {
const darkMode = this.$store.state.config.uiSettings.theme.darkMode
const darkMode = this.$store.state.config.uiSettings.theme.isDark
const fontSize = 16
const lineOpacity = 0.2
let labelBackground = 'rgba(10,10,10,0.90)'
Expand Down
10 changes: 5 additions & 5 deletions src/components/widgets/ToolheadMovesWidget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</v-col>
<v-col class="ml-2" v-if="canHomeXY">
<btn-toolhead-move
:color="(!allHomed) ? 'primary' : 'secondary'"
:color="(!allHomed) ? 'primary' : undefined"
:loading="hasWait(waits.onHomeAll)"
:disabled="!klippyConnected || printerPrinting || hasWaits"
@click="sendGcode('G28', waits.onHomeAll)"
Expand All @@ -37,7 +37,7 @@
</v-col>
<v-col cols="auto" class="ml-2">
<btn-toolhead-move
:color="(!xyHomed) ? 'primary' : 'secondary'"
:color="(!xyHomed) ? 'primary' : undefined"
:loading="hasWait(waits.onHomeXY)"
:disabled="!klippyConnected || printerPrinting || hasWaits"
@click="sendGcode('G28 X Y', waits.onHomeXY)"
Expand All @@ -54,7 +54,7 @@
</v-col>
<v-col cols="auto" class="ml-2" v-if="canHomeXY">
<btn-toolhead-move
:color="(!zHomed) ? 'primary' : 'secondary'"
:color="(!zHomed) ? 'primary' : undefined"
:loading="hasWait(waits.onHomeZ)"
:disabled="!klippyConnected || printerPrinting || hasWaits"
@click="sendGcode('G28 Z', waits.onHomeZ)"
Expand All @@ -64,7 +64,7 @@
</v-col>
<v-col class="ml-2" v-if="canHomeXY">
<btn-toolhead-move
:color="(!xHomed) ? 'primary' : 'secondary'"
:color="(!xHomed) ? 'primary' : undefined"
:loading="hasWait(waits.onHomeX)"
:disabled="!klippyConnected || printerPrinting || hasWaits"
@click="sendGcode('G28 X', waits.onHomeX)"
Expand All @@ -91,7 +91,7 @@
</v-col>
<v-col class="ml-2" v-if="canHomeXY">
<btn-toolhead-move
:color="(!yHomed) ? 'primary' : 'secondary'"
:color="(!yHomed) ? 'primary' : undefined"
:loading="hasWait(waits.onHomeY)"
:disabled="!klippyConnected || printerPrinting || hasWaits"
@click="sendGcode('G28 Y', waits.onHomeY)"
Expand Down
4 changes: 2 additions & 2 deletions src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ export const appInit = async (apiConfig?: ApiConfig, hostConfig?: HostConfig): P

// Set vuetify to the correct initial theme.
if (store.state.config && store.state.config.uiSettings.theme) {
vuetify.framework.theme.dark = store.state.config.uiSettings.theme.darkMode
vuetify.framework.theme.currentTheme.primary = store.state.config.uiSettings.theme.colors.primary
vuetify.framework.theme.dark = store.state.config.uiSettings.theme.isDark
vuetify.framework.theme.currentTheme.primary = store.state.config.uiSettings.theme.currentTheme.primary
}

return { apiConfig, hostConfig, apiConnected }
Expand Down
2 changes: 2 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { SVGRenderer } from 'echarts/renderers'
// import { WorkboxPlugin } from './plugins/workbox'
import vueHeadful from 'vue-headful'

import FluiddBtn from '@/components/inputs/Btn.vue'
import FluiddIcon from '@/components/FluiddIcon.vue'
import BtnCollapse from '@/components/inputs/BtnCollapse.vue'
import CollapsableCard from '@/components/cards/CollapsableCard.vue'
Expand Down Expand Up @@ -66,6 +67,7 @@ Vue.component('collapsable-card', CollapsableCard)
Vue.component('vue-headful', vueHeadful)
Vue.component('inline-help', InlineHelpIcon)
Vue.component('fluidd-icon', FluiddIcon)
Vue.component('btn', FluiddBtn)

appInit()
.then((config: InitConfig) => {
Expand Down
10 changes: 10 additions & 0 deletions src/plugins/filters.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import _Vue from 'vue'
import { camelCase, startCase, capitalize, isFinite } from 'lodash-es'
import { ApiConfig } from '@/store/config/types'
import tinycolor from '@ctrl/tinycolor'

export const Filters = {

Expand Down Expand Up @@ -140,6 +141,14 @@ export const Filters = {
socketUrl: `${wsProtocol}${_url.host}/websocket`
}
return o
},

/**
* Tells us if a color is considered dark or light
*/
colorDark (color: string) {
const t = tinycolor(color).getBrightness()
return ((t / 255) * 100) <= 50
}
}

Expand Down Expand Up @@ -169,5 +178,6 @@ declare module 'vue/types/vue' {
getReadableLengthString(lengthInMm: number): string;
getApiUrls(url: string): ApiConfig;
fileSystemSort(items: Array<any>, sortBy: string[], sortDesc: boolean[], locale: string): Array<any>;
colorDark(color: string): boolean;
}
}
28 changes: 19 additions & 9 deletions src/store/config/getters.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { GetterTree } from 'vuex'
import { CardConfig, ConfigState, TemperaturePreset } from './types'
import vuetify from '@/plugins/vuetify'
import { CardConfig, ConfigState, TemperaturePreset, ThemeConfig } from './types'
import { RootState } from '../types'
import { Heater, Fan } from '../socket/types'
import tinycolor from '@ctrl/tinycolor'
Expand Down Expand Up @@ -64,18 +65,27 @@ export const getters: GetterTree<ConfigState, RootState> = {

/**
* Returns our current theme data.
* Should augment vuetifies default.
*/
getTheme: (state) => {
const v = vuetify.framework.theme
const o = state.uiSettings.theme
return {
...o,
colors: {
...o.colors,
primaryOffset: tinycolor(o.colors.primary)
.desaturate(5)
.darken(10)
.toHexString()

const r: ThemeConfig = {
...state.uiSettings.theme,
currentTheme: {
...v.currentTheme,
...o.currentTheme
}
}

for (const key in r.currentTheme) {
// Currently used for the offset in the logo.
r.currentTheme[key + 'Offset'] = tinycolor(o.currentTheme.primary as string)
.desaturate(5)
.darken(10)
.toHexString()
}
return r
}
}
4 changes: 2 additions & 2 deletions src/store/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ export const defaultState = (): ConfigState => {
defaultToolheadZSpeed: 10
},
theme: {
darkMode: true,
colors: {
isDark: true,
currentTheme: {
primary: '#2196F3'
}
},
Expand Down
Loading

0 comments on commit a3a5256

Please sign in to comment.