From 348d2b086150434a8b0d6fc5b7269950d13af2b8 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Wed, 18 Jan 2023 18:49:12 -0800 Subject: [PATCH] add play button to center of album cover in album grid --- go.mod | 2 +- go.sum | 4 +- res/bundled.go | 5 +++ res/bundled_gen.sh | 1 + res/icons/playbutton.png | Bin 0 -> 1961 bytes ui/widgets/albumcard.go | 85 +++++++++++++++++++++++++++++++++------ 6 files changed, 81 insertions(+), 16 deletions(-) create mode 100644 res/icons/playbutton.png diff --git a/go.mod b/go.mod index d81bfa9..d88ca8a 100644 --- a/go.mod +++ b/go.mod @@ -44,4 +44,4 @@ require ( honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 // indirect ) -replace fyne.io/fyne/v2 v2.2.4 => github.com/dweymouth/fyne/v2 v2.2.5-0.20230110171955-98071d7f072f +replace fyne.io/fyne/v2 v2.2.4 => github.com/dweymouth/fyne/v2 v2.2.5-0.20230119024415-238e09217d09 diff --git a/go.sum b/go.sum index 11c7445..d3de868 100644 --- a/go.sum +++ b/go.sum @@ -72,8 +72,8 @@ github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7h github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dweymouth/fyne/v2 v2.2.5-0.20230110171955-98071d7f072f h1:Tgz5Tx14yQLkKl4JH5eGWnUpq9J8+cbLTuj8lfzgqG0= -github.com/dweymouth/fyne/v2 v2.2.5-0.20230110171955-98071d7f072f/go.mod h1:MBoGuHzLLSXdQOWFAwWhIhYTEMp33zqtGCReSWhaQTA= +github.com/dweymouth/fyne/v2 v2.2.5-0.20230119024415-238e09217d09 h1:huJvmT36/E7MsuAVILCK7VPFd0UiPQDpphn215e1rCo= +github.com/dweymouth/fyne/v2 v2.2.5-0.20230119024415-238e09217d09/go.mod h1:MBoGuHzLLSXdQOWFAwWhIhYTEMp33zqtGCReSWhaQTA= github.com/dweymouth/go-subsonic v0.0.0-20221214005741-bd8048fa1863 h1:bOWMpFJ9zY839T1EngQ5nxVCiMlatPtpGkg/yHK6szg= github.com/dweymouth/go-subsonic v0.0.0-20221214005741-bd8048fa1863/go.mod h1:fUez6NFiEJiQTZizZ1BThZr5GJXAbigzGYjEPNm4tdI= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= diff --git a/res/bundled.go b/res/bundled.go index 77145ee..7502315 100644 --- a/res/bundled.go +++ b/res/bundled.go @@ -65,6 +65,11 @@ var ResPeopleInvertPng = &fyne.StaticResource{ StaticContent: []byte( "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x80\x00\x00\x00\x80\b\x04\x00\x00\x00i7\xa9@\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\v\xfca\x05\x00\x00\x00 cHRM\x00\x00z&\x00\x00\x80\x84\x00\x00\xfa\x00\x00\x00\x80\xe8\x00\x00u0\x00\x00\xea`\x00\x00:\x98\x00\x00\x17p\x9c\xbaQ<\x00\x00\x00\x02bKGD\x00\xff\x87\x8f̿\x00\x00\x00\tpHYs\x00\x00Xp\x00\x00Xp\x01\xbc\xed\xbaK\x00\x00\x00\atIME\a\xe7\x01\x0e\x01\x18;(\xf8\xc4S\x00\x00\f\x7fIDATx\xda\xed\x9dipTU\x1a\x86\x9f\xee\xceB6B\x84\x80\x84-\xec\x8a\x10\x14\x14AY\x04\xc5\xc1\x1dG˱F\x9dҲJ\v\x04\x1cKk(\xc7\x19\x87\xf9a\xcd\x0f\xc7\x1a\xc7aD\xcbe\x16\xac)\\p\xb4D\x06EDdq\x04\x91e\x044\x04\x88\xec\x01I\x80$d\xeb\xeew~\xe4\xe6\xa6C\x92\ueee5/\x16y\xfb\xcfI\xf7=\xdf\xfb}\xef\xbd\xf7\xdcs\xbes\xceM@\x9c\xdf\b\xfa\xed\x80\xdf\xe8\x14\xc0o\a\xfcF\xa7\x00~;\xe07:\x05\xf0\xdb\x01\xbfq\xde\v\x90\xe2\xa2n\x88TR\x81\x06\x1a\x88\xf8\xe0{\x884\x83\xbf\xde9\xbf\x13\x01R\x19\xc0h.e\x10=\xc9\x00j8\xc6^\xb6\xb2\x8d\xfd\xd4'!\xf0\xb4\xb3\xf8k9F\t\xdb\xd8\xc6\xf7\xf6\xf9\xed\n\x90˵\xdc\xc1Dz\x93z\xd6/\r\x1ca=KY\xc5\xc9\x0e\f>\x97k\xb9\x93\xab)h\xe5y\x98ì\xe7\x1d>\xb5\xc9/\xeb\x9f.\xbaU\x9f\xa8F\xf1P\xa3U\xbaM]lX\xb5\xc3\x7f\x9bVY\xe0\x9fi\x87\xdf:}\x7f\xbd\xa4Ӳ\x82J\xbd\xac\x01\x9e\x87\xdf_\x8bT\xe9=\xbfU\xfa+\xb5\xc1\x12y\x13\xbe\xd0xO\xc3\x1f\xa7\xf5\xb6\xf87\xe8J/\x05\x98\xaaom\xd1Kҷ\x9a\xeaY\xf8\xd7hWG\xf1[S\x7f\xa7mzIکq\x1e\x9d}g\xfc\xbb\xac\\\x05\x89\xe9\xfb\xe9sG\xf4\x92\xb4V\xfd\\\x87\xdfWk:\x92?\x11}\xaa^pL/I\v\x95\xe6*\xfcT\xfd\xd9\x15\xff_\x12\xf1'r\xe0\x06U\xb8r\xe0\xa4nt%\xc0\f\xd7\xfc7\xc5g\x88?\x16\xc8f6\xdd\\v\\f\x93\xed\xb8\xb67\xfc9\xf1\x0e\x88/\xc0$\xa6\xba\xa2\a\xb8\x86I\x8e\xeb^\xed\x01\xff\x94\xf8\xfc\xc1\xb8\xbf\xcd$˵\x03Y\xdcN\xc8Q\xcd \xb7\xbb\xb8z,\xf2\xc7\x13\xa0\x80)\xae\xe9\x01\xa6P\xe0\xa8^o\x8f\xf8'\xc7\xe3\x8f'\xc0\b\xfa{\xe2@?F8\xaa\x97\x14\xfex\x02\x8c\"\xc3\x13\a2\x18\xe9\xa8\xde%dv<\x7f<\x01\x06yB\x0f08\x89\xb5lFҾ\x00)\xf4\xf4́^\x0e\x12/\xa1\xe4\xf0\xb7/@\xc0\xa3\v\x10 \xd3Q\xee\xf1\x87d\xf0\xc7;3\xdeֶ͛\xb2\x95B\x0f\x06П\x9ed!\xaa9\xc2~\xf6S\x1e\x93ۋ\xb0\x80\n\x1eq\xd9\x11J\x18I\xfb\x02D\xa9\xf6(\xfc\x1d\xbc@\x83\xf9W\x80\xde\\\xc3\f\xc6Зl\xf3\t\x1d\xa6\x92\xef\xf9\x8a\xe5\xac\xe3\xb8\xf1\xddq\x16\xb0\x9dg=x\x16T\xc5I\x9a\xc6\xe9'?\xef\xaa\x17ބ/uY\x8b\xb1ݯ\xb4]\r\xed\x1e]\xab/5[\xf915\xa6i\x87k\x1f\x9ew6\x18\x9a\xebA\xf8\x9bu\xa9i/]?\xd3fE\x13\xd6\tk\x8dnP\x8aYo\xb2\xf6\xb8\xf4b\x8e3\x01&[\xcc\xc1\xb5\x8fRM4\xad\xf5\xd0\x1fm\xd8;\xa1\xa7\x94cֽUG]xQ\xa9)\xce\x04詭\xae¯\xd4}\xa6\xad>Z\xa2\x88\xad\xda\rzIݍ\xda\x01=\xaez\xc7~lS/\xa7\xf9\x80\xe7\\\t\xb0H醝^Z\xea\xa0~T\xaf(װ\xd0Uo:\xf6\xe39\xe7\t\x91I:\xe1\x98v\xa7\x86\x1aV\xb2\xf4\x8aC\x1ba=\xa3T\xc3\xca\xe5:\xe8\xc8Ɖ\x98\xdbж\x00\xe9Z\xec\xd0\xf5\x88\x1e3\xad\xccQ\xadc\x19O\xeb.\xc3JP\x7fpd\xe1\r\xf3:t \x00\x1a\xafÎh\xb7\xaa\x8faa\xb4\xf69\x0e\xbf\xd1R\xa1a\xe9\"\a\x96\x0e'\x9a\x9fH\xd4E\xdd\xc8\"G3\xaf\xefr\b\x80T\x1e\xa1\xd0U'f4\x0f\x12\x00\xa0\x98\x0fm֍\xf0\"\x1b\x13\x1c\xa3D\x9f<\a\rX\x99\xf9\xf4\xbfR\xc7\\\x9d\x7fI*\xd10\xc3\xdaT\x8b\x93sMxGy\x89\xe2Kkm*\xbf\x85b\xa3\xf4S\xf2]\x9d\x7f\x80\xc1\xdcd\x94\xb6\xf1\xad\x8dzk\x99OE\xa2\x83\xac\x8c\xd2J\x98\xc5\xe7\xb6\\^\xcb\x19\x00zr\xbd\xeb\xf0\x01n4r\x83\xe5\xfc\xd7r\x9dϙŞćY\x1b\xa6\xee\xe0\x01\xde&l\x91\xba\x8e\xadFi\x04C<\x11`\x14\x03\x8d\xd2&\xa2\x16\x8e\x0f\xf3\x16\x0f\xb0Êi\xab\xe3\xf4\xbd<\xc4o\x8c\x86-\x11\x8a\xd9e\x94.\xf3 \xab\v\xd0\xc3Lj\xed\xb10F=\xc8S<\xc4^\x8b\xb6\x136\x82͟\xa0\xc6\xeaU\x95\xc5mv\x8ej\xa1F*h\xd4X\xe4\xba\x01l\xc2o\r\x8b\xfd\x12t\xcf\xcb\xf4\xaaƚ\xfc\x16>vRUQ63\x8b\x97\xb8\x85\xeb\x19F\xb7\x16WO\x84\n\xbec9\xcb\xd9a\x8e\xfdS\xe9\xe3\xc9\xf9\a\xe8K\x00\x01\x87\xb8\x8fۙ\xce\xc5\xe4\xb5\xe0\x8fr\x92b>\xe6\x03\xb6\xc5\xe4\x1e, \xe0 \xed\x13 \x87\xc1\x8c`0\x17\x92E\x94\x93\x94\xf3\x1d\xbb(\xa5\xb2\xc5q\x19,c\x9aG\x02,\xe1^\xb3?\x12 \x8b\xc1\\\xcc\x10z\x91C\x80*\x8e\xb2\x97\x9d\xec\xa1\x12\xdb\xe1X\x15 @\x1a٤\x93F\n \xa2\x88\x00!\x82\x88(\x11 @\x90\x00\x8d\xb9\x9dr\x04d\xf3!\x93=\x12`)w\x13\x06B\xf4\xa6\x8b\xc9\x1f$\x04D\x89\x18\x7f5\xf2\xd7SG\x15\xf5\xd6\xc4H|\v\xe40\x841\\\xc6@\n\xc8&\xbd\xc54\x93\fqZb%\x0fS\a\x84\xa9\xf3(|8c\xb4\xfe\xb9\xbcFQ̓\xa0\xb5\a\x11\xea\xa8\xe20\xfb\xd8\xc2ה\x9cuU\xda\x12 \xc40n\xe4&\x8aκ\xdf\x12a8]\xa8\x03\x1a\x12wC,\xe3\x84\x11t\x06\x83\xb8\xd0\xc2\xf1\x97\x02Q*\xd8·,\xa7\xb8\xfd\xee|{\x02\x04\x19\xc5\xfd\xdcA\xdfV\xe771\xf2\xc8\xe2\x14\x10\xa1\xd43\x01\x9a,\xe5Ɵ\xec>+\x86\xeeL\xe5\x1a\x1ee)\x7f\xe7\x7f\xed\xf4 \xda\xc9\x05=\xa9\xfd\x8e\x1fY'4ְ\xf3\v\x9bY\xa0\xf6pF\xd7\x1b\x16g8\x1cZ\xefד\xeaim8\x1c\xd0x\xadr\xe5xXw\x1b\xb6F\xb9\xca\xe55\xa3\xd8\\\xeb\xf3K\xc76\"Z\xa5\xf1\n$\x1a\f\xa5p\x0fo2\xcd\xd5*\xf2\x10\xe3\x8d\xd2\x1e6{r\x03\xac\xe7\b\x00\xa9Lpl#\xc84\xde\xe4\x9eV7}\v=\xd24\xd7嚜Fl4ә\x0f{p\x13\xd4h\xa6am\x80v\xbb\xb4U\xa1\xb9-\x97Mņ\x1f\xd2\\\u05c9\xf0FTi\x86a\xb3\x8f\xcb̲$}\xaanf\x9b\xd2\xe0\xdaZ\xa5\xe6*Զ\x00\xf7zr\xf6\x1b\xf1\xb2I2ǥ\xd3\xd5fV0C\xef{\xe2[\x85\xeemK\x80\xf1*\xf5,|\xe9\x90\xc6\x18v/\xd0\nW\x96\x16+Ӱ4]'=\xf2\xae\xb49S\xd8\x14~\xbeVz\x18\xbe$\xfd՜\xdcr#\xedv]dX\xc9\xd4\xdb\x1ez\xb7\xb2i\xfe\xb1I\x80\xf9\x1e=\xb1\x9bqB\xd3cn\xaerG6\x0e\xe9\x06\xd3\xc6\xcfU\xed\xa1w\x11͏\x15`\x94\xcb\xd4u\xdbXmNI\x854\xdb\xc1\xe5{Tw\x9b\xcf\xed\xc1\x1e4\xa6-\xb1O\xa3\x9a\x04\b\xe8\xd9\x0e\b_\x8a\xeaO\xe6ލ\x14=`s\x86\xa1D3\xcd\xc4FW\xbd\xd1\x01\xfe=\xab@\xa3\x00\xc3;\xe4\xfcKR\xb5\xe6\x98O\x83\xa0\xa6j\xbd\x85\xc9qI\nk\x85.7\xcf~\xba~\xef\xc1\xe3\xaf5\xf6ix\xa3\x00\xf3:(|I*7\xbb\xc5\b\x15\xe8w\xfa>A\x8d\xa8\xbe\xd3cfG\n\x055Og:Ȼy\"\xb4 \x87\xa7<\xcaݞ\x8d\x06\xbe\xe1\x1d6p\xd8\xfc\xa6\x92u\xac\xe0$\xb9tks\x1cz\x86-\xbcȓ\xac0\xd2\xea\x8d]\xd8Lj\xe9jsHn\xb5{\xfc~@cYfi\x84m\x0fu\xacc1\x1fQ\xd6F^&@O\xc62\x81\xd1\xf4\xa3\x1bi@\x1d\xe5\xecg\v_\xb0\xc5\xc8&\x9d\xedh_n\xe2>\xaep\xb5ѳ5\x8ers@\xb3x\xc1c\xb3Q6\xb2\x90e\x9cj\xe3\xb7\x00\x10@\x88\x00\xe9\xe4\x90E:\xa2\x8e*#\x89\x150~m\v=\xb8\x93ٌ\xf2\xd0\xd30\xf3R\x18\xe7q\xf8\xc7Y\xc4\"\x8e\xb6\xf8.\x9d\x02\x06S\xc8\x00rɊ\xd9r\xd9\x14j\x80شV=\xd5TPJ){(\x8b\xd9\v\xfa\x03/\xf1\x11\x8fr?\xb9\x1e\xf9\x9a\xc28ln\x87K\x84M\xba.v\xa8\xa1t\x15\xe9\t}\xa0}\xaa\xb1\xf8\x04hn\f\xab\xb5[K\xf5\x88.2\x17I \x94\xaa;\x1c\xec!k\x0f\x1b\xd0\x01όE\xf4\x96\x06Ÿ\x9a\xa9\x9fh\x89\x8e\xda\f\xbc\xb5\xd5\x03zM\x93Z,s(\xd2'\x1e\xf9|\x00\x9d\xf2\xc8T\x83\x16\xa9G\xcc\xd0z\x82\xde\xf6hp-I\xe5z]E13>\xfd\xf5\xb6Ka\x1bq\n\x8f\xba\x18a-TWӽ\v\xf4\xb4GɰX\x94\xeaQe\x9b\x1c\xbd\\,\x9bjF\x03\x1e9\xf773i\x81F\xe8=\x85=\x0f_\x92\xea\xf4\x8f\x98]\xc1\x05\xfa\xc0\xbdIo\x04Xi\xae\bB\x13\xb4\xb9C\x82o\xc2j\x8d4\xb9.\xd2W\xe7\x82\x00%f\xf2\x03Mv\xb0\xcb\xd8.6i\xb4\xc9w]\x82\xd9\xea$\bP\xa3\aMw\xc6h{\x87\x87/Ik5\xc4\x1c)\xfc\xda\xdd\xed\xe6^\x80%\xca2\x13\xa0\x9f%%|)v\xf9S\x0f\xad\xf2S\x80#fv\xad\x8b\x16&-|)\xac\xa7\xcd\x0e\xd7\xcdn\x1e\xe5nGXo\xb1\xc9(\xdd\xc2\xfd\x9ev\xa9\xe3#\xc4\x1csG\xe8'\xfcǹ!w\x02\x1c\xe5\x9fƼk\x01\x8f{\xb0\xcb\xd4\x0e\xf2y\xc2\x18\x13\xd4\xf2z\xa2I\xf0\x8e\x12\xe0#\xb6\x19\xa5\xbb\x18\x97\xd4\xf0\x01\xae\xe3F\xa3\xb4\x9e\xf5~\bP˻\xc6ҹ\xde\xdc\xe7`\x1a\xdd-\xd2y\x80\xae\x00T\xf3oK\xcb\xe7<\x16\xe0;\xbe4J\xd7R\x94\xf4\xf0\x01\xae2\xa7aWs0\xf9\x02l\xe0\x18\x00\xe9\xdc\xe6qN\xc1*\xb2\xb8ٸ\xf2\xf6\xf3u\xb2\x05\x88\xb2\xceHg\x14\x9a\xe7!\xf9\x98J/\xa01\x05\x97d\x01*\xd8i\x94\x8a: \xa7h\x15\x85\f3J۩I\xae\x00\aͻ\xce\xebT\xa5\x1dds\x99Q\xda\xe7l\xab\xads\x01\x0e\x1b\xcf\xdeT\x86\xfa\x16>`^\x01\xe5F\x8b\x94D\x01\x1aӕ\xd9\xf4\xf5U\x80B\xd2\x01\xa8\xa2,\xb9\x02\x9c0\x9a\xc0L\xf2|\x15 \x8f.\x00\x84)O\xae\x00MMN\x9aq\x06\xfcB\x86\x91f\x97\xd3Fp\x97\xb3\x8a\xe62\xd84\x87\xef\x88\xf1\n\xe9F\x13,jm\xd7-\xe7\xdd\x14\xa63\x92\x89\\\xc5%\xe4ۺ\x1e\x9afo\x02>t\x82c\xd1\xccng\xa5x\x94\x83,\xe7_lJ\xe1\x10\x87\xf8\x98L\x06r9\x93\xb8\x82\x81\x1e\xed\xf28W!\x8e\xf35\xcb\xf8\x84=\x841/\x9fj\xbe\xe1\x1b\x16ӝ\x8b\xb9\x94ь`\x00\xdd[\xbd7\xf4Ǎ3\x1cd\x1b\x9f\xb1\x8e\x92\xe6\xd9\xe7\x96]\x98\b\xc78\xc6\x1a\x82t\xa5\x80a\x14QD!\xbd\xe8\xe6\xf0- \xe7\x02\x1a(\xe7\x10\xbb\xd9\xcaW\xec\xe2\xd8\xd9\xfbI\xda\xee\xc3E9\xc9Iv\xf2\x1e\xa9\xe4\x90Go\xfa1\x90\x81\xf4#\x8f\\r\xc8 \xcb\xe9\xf0\xb3\x83\x11\xa6\x81:\xea8\xcdq\x8ep\x80\x03\x94\xb0\x87#\x9cno\xcf[\xa2Nl\x03\xe5\x94\x1b\xfb\uf0a4\x92A\x06Y\xe4\x92\xc7\xf7~\xc7\xda\no\xf15\x15TRE\x15\xa79M\r\x91\xc4\r\xa3\xbdMSu\xd4u\xe8[\x83\xdd\xc1Q^\xe8\xc7zg{\x86N\x01\xfcv\xc0ot\n\xe0\xb7\x03~\xa3S\x00\xbf\x1d\xf0\x1b\x9d\x02\xf8\xed\x80\xdf\xe8\x14\xc0o\a<\x80\xab\x84\x8c{\x01\xa2\xbe\xfc\x87\x99f\x1cw\xf7\x8f]B\v\xdc:p\x86R*I#'\xe9\xe9\x93\b\xc5,\xe2\x19\xa7Ӣ\x8dp\xf2\x06\x89\xd6\b\x91O\x11\x93\x98\xc8\b\xba'%Iz\x82M\xbc\xcfr\x0e\xba\xcdKx#\x80a\x8b,\n\x19\xcd8\xc62\x84\xee\x1d2a\x16\xa1\x8c\xad\xaca5;b6U\x9c#\x024\v\x91C?\x86S\xc4(\x86ћ\xae\x1e\xdc\x1c\r\x1c\xa7\x84-|\xc5fJ\x1d&\xf2\x93&@3R\xb9\x80\xde\f`(C)\xa4\x17=\xe8J\x86\xc5+#B=Ք\xb3\x9f\xbd즘b\x0eRm\xff%)\xfe\n\x10\xc3C:\xd9t\xa3'\xf9\xe4Ӄ|r\xc9&\x9bLR\b\x11B\xd4SO\x1du\xd4R\xc51\xca(\xe3\a\xca9NE\x1bo%\xfe\x11\nЖ$A\x82\xa4\x102\xdf\xfe\x12!\x82\x8c7\xc4$ύ\xce\x7f\xbb{\x9e\xa3S\x00\xbf\x1d\xf0\x1b\x9d\x02\xf8\xed\x80\xdf\xe8\x14\xc0o\a\xfc\xc6y/\xc0\xff\x01\xc0\x80UF\xc9\x05M\x93\x00\x00\x00%tEXtdate:create\x002023-01-14T01:24:41+00:00\x1f\xbd\t^\x00\x00\x00%tEXtdate:modify\x002023-01-14T01:24:41+00:00n\xe0\xb1\xe2\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\x9b\xee<\x1a\x00\x00\x00\x00IEND\xaeB`\x82"), } +var ResPlaybuttonPng = &fyne.StaticResource{ + StaticName: "playbutton.png", + StaticContent: []byte( + "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x80\x00\x00\x00\x80\b\x03\x00\x00\x00\xf4\xe0\x91\xf9\x00\x00\x00\x04gAMA\x00\x00\xb1\x8f\v\xfca\x05\x00\x00\x00 cHRM\x00\x00z&\x00\x00\x80\x84\x00\x00\xfa\x00\x00\x00\x80\xe8\x00\x00u0\x00\x00\xea`\x00\x00:\x98\x00\x00\x17p\x9c\xbaQ<\x00\x00\x01\xcePLTE\x00\x00\x00\"\xd7)!\xd3(#\xe2+!\xd6( \xce'\"\xd9)!\xd5(\"\xd6)\x1b\xae!!\xd2(\"\xd8)\x1b\xb0!\"\xd8)!\xd5(!\xd5(\"\xd7)!\xd6(!\xd6(!\xd6(!\xd6(\"\xd7)!\xd6(\"\xdb)!\xd6(!\xd6(!\xd6(!\xd6(!\xd6(\"\xd7)\"\xd6)\"\xd6)\"\xd7)!\xd6(!\xd6(!\xd6(!\xd6(!\xd6(\"\xd7)!\xd6(!\xd5(!\xd6(\"\xd7)!\xd6(#\xde*!\xd5(!\xd6(!\xd6(!\xd6( \xcd'!\xd3(!\xd6(!\xd6(!\xd2(!\xd5(!\xd6(!\xd6(!\xd6(!\xd6(\"\xd7)!\xd6(!\xd6(\"\xd7)!\xd6(!\xd5(!\xd6(\"\xd6)\"\xd7)\"\xd6)!\xd6(!\xd6(\"\xd6)!\xd6(!\xd5(!\xd6(\"\xd6)!\xd6(!\xd6(!\xd6(\"\xd6)!\xd5(!\xd6(\"\xd6)\"\xd7)\"\xd7)!\xd6(\"\xd7)!\xd6(!\xd5(\"\xd6)!\xd6(!\xd5(\"\xd7)!\xd6(!\xd6(!\xd6(!\xd6(!\xd5(!\xd6(!\xd4(!\xd6(!\xd5(!\xd6(!\xd6(!\xd5(\"\xd7)\"\xd7)!\xd6(!\xd6(\"\xd7)\"\xd7)\"\xd6)!\xd6(!\xd6(\"\xd7)\"\xd6) \xd6'(\xd8/)\xd80\x1f\xd6&>\xdcD\x97\xec\x9b\xc3\xf4\xc5\xc6\xf4Ǐ\xea\x93?\xdcE\xc5\xf4\xc7\xff\xff\xff\xfe\xfe\xfe\xdc\xf8\xddz\xe6~-\xd94\x97\xec\x9a\xfa\xfe\xfa\xba\xf2\xbcQ\xdfW\xec\xfb\xec\x90\xeb\x944\xda:9\xdb?\xe0\xf9\xe1\xfc\xfe\xfc\xcf\xf6\xd0f\xe3k$\xd7+<\xdbB\xe4\xfa\xe5\xf2\xfc\xf2\xa7\xef\xa9D\xddI\xbf\xf3\xc1&\xd7-\x98원\xea\x93(2|%\x00\x00\x00qtRNS\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x141S\x7f\x93\xbe\xcf\xdd\x01\x1cEq\xa6\xcb\xe7\xf8\xfe\v3f\xa9\xd9\xfe\x05'e\xb4\xee\xfd\x01\x11L\xa0\xe4\x01\x16\xc7\xf6\x15o\xd0\xfb\x14\xca\nM\xbf\xfc\x01)\xa1\xf5\ro(\xa4\xfb\x04Q\xd7\x0f\x80\xf0\"\xfc*\xbdCC\xdd\xd6\"\x0e\x03\xfd)\rp\tN\x15\xc9p\xfc\x17\xce\x12Ɵ\n3\xed\xa8\xd8\x03\xa60\x92\x9c\x8e\xa7 \x00\x00\x00\x01bKGD\x7fH\xbfq\xe5\x00\x00\x00\atIME\a\xe7\x01\x13\x01%2\x99\xbf\xbb\v\x00\x00\x04[IDATx\xda\xe5\x9bgC\x13A\x10\x86wÑP\x83\xb4H\rx\x82tA\x9a\"\x1d%H\x93Б\xa2\"Ho\xb7\x89\x82\xf5,\xd8{\x03\xfd\xb7\xe6\x12\x90\x00Iؽ\xdd\xcb|\xf0\xfd\xbe\xf7>\x99\x9d\xdcm\x99A\x88Q8ޚp*1)9%զ\x90=)\xb6Ԕ\xe4\xa4\xc4S\t\xd6x\xcc\xfa<6\xf3\xd3ִ\xf4\x8c̬l{\x0e9\xa6\x1c{vVfFz\x9a\xf5\xb4A\x10\x18瞑\xcf\xe6\xd9\xf3I\b\xe5\xdb\xf3\xce\xcagr\xb1x\x06|\xae\xa0\xb0\xa8\xb8\x84P\xa8\xa4\xb8\xa8\xb0\xe0\x9cP\x04\\Zv\xbe\xbc\xa2\xc4Ec\xaf\xc9URQ~\xbe\xacT\x14\x83\xe9B\xa5\\UMk\xbe\xaf\xea*\xb9\xf2\x82I\x84}DM\xed\xc5K\xac\xf6\x9a.]\xac\xad\x89\xe0E\xc0R\x9d|Y\x97\xbd\x17\xe1\xb2\\'qM\x04\xaeohl\xd2k\xaf\xa9\xa9\xb1\xa1^?\x01nnim\xa3μ\xc0r\xb5\xb5\xb64\xebD\xc0W\xae\x1e\xbc\xec\xf4K\xb1]\xbd\xa2\x87\x00G\xb6;:\xf8\xed5u8\xda#\x99\x11\xf0\xb5\xce.\xce\xe8\xfb\xcdCW\xe75F\x02\xdc\xdd\xd3+\xcc\xdfC\xd0\xdb\xd3\xcdB\x80\xa5\xeb\x8e>q\xf6\x9a\xfa\x1c\xd7\xe9\xff\x90\xd8\xec\xec\x17k\xaf\xa9\xdfi\xa6$\xc0x\xa0K@\xf6\x1f\x95\xd25@\xf7\x91\xc4xpH\xbc\xbd\xa6\xa1A\x1a\x02\xe3\xfc\xe9\b\x8c\xf4\xa7!0\xd6\xffd\x02lq\x0e\x1b\xe9OȰ\xd3\x12\x8a\x00\x8f\xf4\x1b\x90\xff\xfeR\xfaGB\x00H\xa3\x0ec\xed59F\xa5\xa0\xfec=7\x8c\a\xb8\xd13\x16\x84\x00\xe3\xce^\xe3\xfd\t\xe9\xed\f\x92\x88\xd2\xf8\xb0\xc0\xefOp\xb9\x86\xc7\x03\x86@\x9ap\x84\xc5\xdfC\xe0\x98\b@\x80\xa3&\x05\xad?NV\xc7d\xd4\xf1I\xb08m\xe1\xf2'\xc4\xe6\xb4\x1c\x9b\x80\xa9V\x83\xdf\x00\xfeRZ\xa7\x8eLB\xb4\xf9f[\xf8\xfc\ti\xbbi\x8e>\x1c\x80[\x8da\xca@\x9f\\\x8d\xb7\x0e\x85 &V\xe6\xda\x7f\xb0\xabI\x8e\x8d\xf1\x030U\xde\x0e\xaf?!\xb7+\xfd\xb6\x8dX\x9a\xbe\x13n\x80;\xd3~\x8bT\xd3\xccl\xb8\xfd\t\x99\x9d1\x1d\x04@\x0e{\x00ݢ\x8d\x81A\x00\xea6\xed\xc2\xdd(\x80\x9d\xdd\xff\x1d\x00z\n\x80\x93\x90\xe9o\b\xfe\"\x02\x7f\x15\x83\x7f\x8c\xc0?\xc7\xe0\v\x12\xf0%\x19\xf8\xa2\x14|Y\x0e\xbe1\x01ߚ\x81oN\xc1\xb7\xe7\xe0\a\x14\xe0G4\xe0\x87T\xe0\xc7t\xf0\a\x95\xe0G\xb5\xe0\x87\xd5\xcc\xc7\xf5\xbfwv\xfe\b=\xaeg\xbe\xb0\xd8\xdd\x15{a\x01\x7fe\x03~i\x05~m\a\x7fq\t~u\v\x7fy\r~}\x0f_\xc0\x00^\xc2\x01_\xc4\x02_\xc6\x03^\xc8\x04_\xca\x05_\xcc\x06^\xce\a_\xd0\b_\xd2\t_\xd4\n^\xd6\v_\xd8\f_\xda\r_\xdc\x0e_\xde\x0f\xdf\xe0\x00\xdf\xe2\x81\xc0\x9b\\\x10|\x9b\x0f|\xa3\x13\x02o\xf5B\xf0\xcdn\b\xbc\xdd\x0f\xc17<\"\xf0\x96O/\x02lӫw\"`\xdb~}\f\xa0\x8d\xcf>\x04\xd8\xd6o\x1f\x03h\xf3\xfb>\x84\xe0\xf6\xff\xbfN\xd2\xc9+\xf1{\x02!\x00\x00\x00%tEXtdate:create\x002023-01-19T01:37:03+00:00/\x9b0\x17\x00\x00\x00%tEXtdate:modify\x002023-01-19T01:36:39+00:00\x9b\xfb\xbb8\x00\x00\x00\x00IEND\xaeB`\x82"), +} var ResPlaylistPng = &fyne.StaticResource{ StaticName: "playlist.png", StaticContent: []byte( diff --git a/res/bundled_gen.sh b/res/bundled_gen.sh index ca045e6..4a4644d 100755 --- a/res/bundled_gen.sh +++ b/res/bundled_gen.sh @@ -12,6 +12,7 @@ fyne bundle -append -prefix Res icons/musicnotes.png >> bundled.go fyne bundle -append -prefix Res icons/musicnotes-invert.png >> bundled.go fyne bundle -append -prefix Res icons/people.png >> bundled.go fyne bundle -append -prefix Res icons/people-invert.png >> bundled.go +fyne bundle -append -prefix Res icons/playbutton.png >> bundled.go fyne bundle -append -prefix Res icons/playlist.png >> bundled.go fyne bundle -append -prefix Res icons/playlist-invert.png >> bundled.go fyne bundle -append -prefix Res icons/podcast.png >> bundled.go diff --git a/res/icons/playbutton.png b/res/icons/playbutton.png new file mode 100644 index 0000000000000000000000000000000000000000..f8433c930ebfbd8eae0bd7f59e9ee3d4bcc7e771 GIT binary patch literal 1961 zcmZ8h3pkW%8-C|tjkBcumdZ>yuQe#A9A+G1R>XvA$>=BY=X^Lp33X z%{u(+R5`U_R?8%ZF%HvADI)&FkQg)jF|FP9yWa18p67m^`+o25`o8PC>h9(wC;hcF z06>o5>_CJfW#dL6pq*&Kg67fySlyU^3&1%n z05kpoSmpts5?T1r!wLWx)BUigBQ$^+)01iu|6YPkGV-f4{ll#=bQew z6vVDJ$}Iz%xduyHhi$0K#_nNh*^E2foGp05@9g3;vSxB@#~nNQ43S7A6bi>zIPsHY zgOU9=XKAa#)rSks9^7NIYqQjMx%)>gEyiqlpI!=tf@jNpK@(^94eMKt*}YzUvmjU~ zdtc$eA+#+%)*3d*n=PQu-`Du(EG6pDXcFr>24(d3-gXB?QiV^rzyQ!7Fl zlc0(bp@jD7y8o}kwjHLwhV5i5?}+GIQ+_J#+9rVM-d&Q5&?#9%dJHR2<}m`j7JGXR z3nPzM*OiNua@)}zDNtc5b={FRnJZ@_O0m}qGs`rf6Jh^$adJp@Zi{*Y6_POoS4YVy z*mjtvaemt)8R(1kAvoYY<3`^U1lw=ND_%bTB-=f;&RH%lB?eE!?9z13>B}y{I7c*I zOqndXTjOE*_#ZsXU(h1;jC3tDhf1l|x($Q5uS+_P zO0nX4R;^4I2UvCd^q$Jl1bK^6^@LdOphNMrr8>Ogzou?yKbss`B%t1mEi#`5N7u%E zl~_fuDQ`-1FE42-ui+KCBYnS*ZEY^X3j`FgpYZLOZsd$5o~ zNK0~Xo$GX|T&8_{vhwGvJjZt8t;7>ITU1{D&sRIj61ET0~{f&Zp|J?QwJ$-143q{ReO#vpeD< zots-q@8Z9PPY9+_>HIP@mL&>=hepY(O&|HKWPL$zK1Vf2F4V{gKEAml=r5I9g;{C)b{rhr&^cwIqJF zb@OHf4t^lin1{Vw(C(P5Q!k)Yc&BoKkobLB=3%?KPeDE_0;!NkA(=Mn6rYS!PjPpA zGaBVDX=r&*jwaXKCuC-PKw!OI$XDB<8}-*4GLF+)w}(>>4v_!rInWc@v@Vr@%V-x8 zC!YYU&{WYS+{1$mW8w#A)k-ySi z3Q{iI&%*tu+J9x;=ZKeA(z2k_g`9RR)(}_tfGYI3mf*8AGxW}^qgRTqOq-|!-zYzC zyL2N#VaU2A>Emq^R8^6L0WvP?Dmi`a2_p$C4NMu5J}LgVv$jDgS9SL*;qpoAzN|ZK zO(^A&Uo7j=4NPP$Wa&Q@b~jlC;fbTtk|5Z)s)T?l8@m8ju0Ow>xsBSq~VfHkyXq zIfJ77WWy=SxQGWcrgOh?bSSqtqFo?fnvz4Ejz9@9@Z=q-$?5I344#bAyr$|(k#gb* z`Bozsmv%A2?Q!E2Pg0rZw4ZmylgEgem%PDqs^?u9>R~LkosSiwtgC`sYuKC}38!Gm zrxD~3338ZZa+DPLoJ{fsIdYN$sU7(J3L|yENnHrP-;kuI5~QB5{FsuYJ`|~6iZm$g z$C4qjWl5uQq;YxD3k5C@a9>?)FYr}NEKo=+-VTpgvYYP>M>TU49-CQV=6^h52oD{& ze;(sMMoyBYXFRh(vRM&(5N8(GY|?nkqBghwZv77la5VJi(Ts6C9us&f=Cox%^l2yn zW2~`>0oKUC$ifqAWNBh%i8ay3VlA;)!vd_z7lg2gz>uH||0I}NnplVl1#6GYAp#&c Lx;a$Y`KSB=P5Nt; literal 0 HcmV?d00001 diff --git a/ui/widgets/albumcard.go b/ui/widgets/albumcard.go index 7f2c684..6cecf26 100644 --- a/ui/widgets/albumcard.go +++ b/ui/widgets/albumcard.go @@ -3,14 +3,17 @@ package widgets import ( "context" "image" + "image/color" "strconv" + "supersonic/res" "supersonic/ui/layouts" "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/driver/desktop" + "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" "github.com/dweymouth/go-subsonic" @@ -20,45 +23,105 @@ var _ fyne.Widget = (*AlbumCard)(nil) var _ fyne.Widget = (*albumCover)(nil) var _ fyne.Tappable = (*albumCover)(nil) -var _ fyne.DoubleTappable = (*albumCover)(nil) type albumCover struct { widget.BaseWidget Im *canvas.Image + playbtn *canvas.Image + btnCircle *btnCircle OnDoubleTapped func() OnTapped func() } +type btnCircle struct { + canvas.Circle + + Diameter float32 +} + +func (b *btnCircle) MinSize() fyne.Size { + return fyne.NewSize(b.Diameter, b.Diameter) +} + func newAlbumCover() *albumCover { a := &albumCover{} a.ExtendBaseWidget(a) a.Im = &canvas.Image{FillMode: canvas.ImageFillContain} a.Im.SetMinSize(fyne.NewSize(200, 200)) + a.playbtn = &canvas.Image{FillMode: canvas.ImageFillContain, Resource: res.ResPlaybuttonPng} + a.playbtn.SetMinSize(fyne.NewSize(60, 60)) + a.playbtn.Hidden = true + // TODO: + a.btnCircle = &btnCircle{ + Diameter: 63, + Circle: canvas.Circle{ + FillColor: color.Transparent, + StrokeColor: theme.PrimaryColor(), + StrokeWidth: 2, + Hidden: true, + }, + } return a } func (a *albumCover) CreateRenderer() fyne.WidgetRenderer { - return widget.NewSimpleRenderer(a.Im) + return widget.NewSimpleRenderer( + container.NewMax(a.Im, container.NewCenter(a.playbtn), container.NewCenter(a.btnCircle)), + ) } -func (a *albumCover) DoubleTapped(e *fyne.PointEvent) { - if a.OnDoubleTapped != nil { - a.OnDoubleTapped() - } +func (a *albumCover) Cursor() desktop.Cursor { + return desktop.PointerCursor } func (a *albumCover) Tapped(e *fyne.PointEvent) { + if isInside(a.center(), a.playbtn.Size().Height/2, e.Position) { + if a.OnDoubleTapped != nil { + a.OnDoubleTapped() + } + return + } if a.OnTapped != nil { a.OnTapped() } } +func (a *albumCover) MouseIn(*desktop.MouseEvent) { + a.playbtn.Hidden = false + a.Refresh() +} + +func (a *albumCover) MouseOut() { + a.playbtn.Hidden = true + a.Refresh() +} + +// TODO: figure out why circle around play button isn't being displayed +func (a *albumCover) MouseMoved(e *desktop.MouseEvent) { + if inside := isInside(a.center(), a.btnCircle.Diameter/2, e.Position); inside && !a.btnCircle.Visible() { + a.btnCircle.Show() + a.Refresh() + } else if !inside && a.btnCircle.Visible() { + a.btnCircle.Hide() + a.Refresh() + } +} + +func (a *albumCover) center() fyne.Position { + return fyne.NewPos(a.Size().Width/2, a.Size().Height/2) +} + func (a *albumCover) SetImage(im image.Image) { a.Im.Image = im a.Refresh() } +func isInside(origin fyne.Position, radius float32, point fyne.Position) bool { + x, y := (point.X - origin.X), (point.Y - origin.Y) + return x*x+y*y <= radius*radius +} + type AlbumCard struct { widget.BaseWidget @@ -83,12 +146,6 @@ type AlbumCard struct { OnShowArtistPage func() } -func (a *AlbumCard) MouseIn(*desktop.MouseEvent) {} - -func (a *AlbumCard) MouseOut() {} - -func (a *AlbumCard) MouseMoved(*desktop.MouseEvent) {} - func NewAlbumCard(showYear bool) *AlbumCard { a := &AlbumCard{ title: NewCustomHyperlink(), @@ -103,11 +160,13 @@ func NewAlbumCard(showYear bool) *AlbumCard { a.OnPlay() } } - a.title.OnTapped = func() { + showAlbumFn := func() { if a.OnShowAlbumPage != nil { a.OnShowAlbumPage() } } + a.Cover.OnTapped = showAlbumFn + a.title.OnTapped = showAlbumFn a.artist.OnTapped = func() { if a.OnShowArtistPage != nil { a.OnShowArtistPage()