From 3f1b7213af69fa8d8426294de512686d7b8e9c38 Mon Sep 17 00:00:00 2001 From: Georg Gadinger Date: Fri, 16 Apr 2021 19:38:16 +0200 Subject: Initial commit --- .gitignore | 1 + README | 34 ++++++++++++++ fonts/09-Espy Sans-Bold.fnt | Bin 0 -> 195513 bytes fonts/10-Espy Sans-Bold.fnt | Bin 0 -> 198224 bytes gems.locked | 13 ++++++ gems.rb | 5 ++ gen_theme.rb | 93 ++++++++++++++++++++++++++++++++++++++ icons/absolutely_nothing-6x18.bmp | Bin 0 -> 2366 bytes images/batt.bmp | Bin 0 -> 12298 bytes images/battchrg.bmp | Bin 0 -> 12214 bytes images/directory.bmp | Bin 0 -> 702 bytes images/hold.bmp | Bin 0 -> 294 bytes images/playmodes.bmp | Bin 0 -> 5454 bytes images/progressbar.bmp | Bin 0 -> 4322 bytes images/progressbar_backdrop.bmp | Bin 0 -> 350 bytes images/progressbar_slider.bmp | Bin 0 -> 222 bytes templates/base.liquid | 73 ++++++++++++++++++++++++++++++ templates/fms.liquid | 67 +++++++++++++++++++++++++++ templates/sbs.liquid | 44 ++++++++++++++++++ templates/wps.liquid | 77 +++++++++++++++++++++++++++++++ 20 files changed, 407 insertions(+) create mode 100644 .gitignore create mode 100644 README create mode 100644 fonts/09-Espy Sans-Bold.fnt create mode 100644 fonts/10-Espy Sans-Bold.fnt create mode 100644 gems.locked create mode 100644 gems.rb create mode 100755 gen_theme.rb create mode 100644 icons/absolutely_nothing-6x18.bmp create mode 100644 images/batt.bmp create mode 100644 images/battchrg.bmp create mode 100644 images/directory.bmp create mode 100644 images/hold.bmp create mode 100644 images/playmodes.bmp create mode 100644 images/progressbar.bmp create mode 100644 images/progressbar_backdrop.bmp create mode 100644 images/progressbar_slider.bmp create mode 100644 templates/base.liquid create mode 100644 templates/fms.liquid create mode 100644 templates/sbs.liquid create mode 100644 templates/wps.liquid diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b1c8b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/dist diff --git a/README b/README new file mode 100644 index 0000000..1d8eb9d --- /dev/null +++ b/README @@ -0,0 +1,34 @@ +rockbox-theme-ipawbmini +======================= + +This is a theme for iPod minis running Rockbox that makes it almost look like +it's running the stock Apple software. Yes, with the fonts and all; though it +also displays album artwork in the while playing screen. + + +Building from source +-------------------- + +As all views share a common look (with the status bar and such) I decided to use +a templating engine to keep the common parts in one place. As usual, I chose +Ruby for the task :) + +First, install Ruby using your favourite package manager, any version newer than +2.6 should do fine. Then install the dependencies using Bundler by running: + + % bundle install + +Then run the theme generator. This will create a new `dist` directory where the +theme is being built to and all required files are copied into. + + % ./gen_theme.rb + +The contents of the `dist/iPawbMini` directory can be then copied into the +`.rockbox` directory of your iPod mini running Rockbox. + + +License +------- + +This work is licensed under a Creative Commons +Attribution-NonCommercial-ShareAlike 4.0 International License. diff --git a/fonts/09-Espy Sans-Bold.fnt b/fonts/09-Espy Sans-Bold.fnt new file mode 100644 index 0000000..bdde49d Binary files /dev/null and b/fonts/09-Espy Sans-Bold.fnt differ diff --git a/fonts/10-Espy Sans-Bold.fnt b/fonts/10-Espy Sans-Bold.fnt new file mode 100644 index 0000000..5dff9d0 Binary files /dev/null and b/fonts/10-Espy Sans-Bold.fnt differ diff --git a/gems.locked b/gems.locked new file mode 100644 index 0000000..3275512 --- /dev/null +++ b/gems.locked @@ -0,0 +1,13 @@ +GEM + remote: https://rubygems.org/ + specs: + liquid (5.0.0) + +PLATFORMS + ruby + +DEPENDENCIES + liquid (~> 5.0) + +BUNDLED WITH + 2.1.4 diff --git a/gems.rb b/gems.rb new file mode 100644 index 0000000..b37a46f --- /dev/null +++ b/gems.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "liquid", "~> 5.0" diff --git a/gen_theme.rb b/gen_theme.rb new file mode 100755 index 0000000..d7530d3 --- /dev/null +++ b/gen_theme.rb @@ -0,0 +1,93 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'liquid' +require 'fileutils' + +THEME_NAME = 'iPawbMini' +# MAIN_MENU_TITLE = 'iPod mini' +MAIN_MENU_TITLE = 'iPawb mini' + +DEST_DIR = File.join(__dir__, 'dist', THEME_NAME) + +TEMPLATE_PATH = File.join(__dir__, 'templates') +BASE_TEMPLATE = 'base.liquid' +TEMPLATES = { + 'fms.liquid' => "wps/#{THEME_NAME}.fms", + 'sbs.liquid' => "wps/#{THEME_NAME}.sbs", + 'wps.liquid' => "wps/#{THEME_NAME}.wps" +}.freeze + +THEME_CONFIG = { + **TEMPLATES.map { |_, path| [path.split('.').last.downcase, "/.rockbox/#{path}"] }.to_h, + 'selector type' => 'bar (inverse)', + 'filetype colours' => '-', + 'font' => '/.rockbox/fonts/10-Espy Sans-Bold.fnt', + 'statusbar' => 'off', + 'scrollbar' => 'right', + 'scrollbar width' => '9', + 'battery display' => 'graphic', + 'show icons' => 'on', + 'ui viewport' => '-' +}.freeze + +def new_liquid(template_path) + Liquid::Template.parse(IO.read(File.join(TEMPLATE_PATH, template_path))) +end + +base_vars = { + 'theme_name' => THEME_NAME, + 'main_menu_title' => MAIN_MENU_TITLE, + 'generated_at' => Time.now.to_s +}.freeze + +FileUtils.mkdir_p(DEST_DIR) + +puts "===> Generating WPS screens" +FileUtils.mkdir_p(File.join(DEST_DIR, 'wps')) +TEMPLATES.each do |src, dst| + vars = base_vars.merge('filename' => src) + template = new_liquid(src) + content = template.render(**vars).strip + assigns = template.instance_assigns.transform_values(&:chomp) + result = new_liquid(BASE_TEMPLATE).render( + 'content' => content, + 'filename' => src, + **vars, + **assigns + ) + + dest_full = File.join(DEST_DIR, dst) + puts "writing #{dest_full} ..." + File.open(dest_full, 'w') do |f| + f.puts result + end +end + +puts "===> Generating theme config" +FileUtils.mkdir_p(File.join(DEST_DIR, 'themes')) +File.open(File.join(DEST_DIR, 'themes', "#{THEME_NAME}.cfg"), 'w') do |f| + f.puts "# #{THEME_NAME} Rockbox theme" + f.puts "# Generated using gen_theme.rb at #{base_vars['generated_at']}" + f.puts + + THEME_CONFIG.each do |key, value| + f.puts "#{key}: #{value}" + end +end + +def copy(kind, pattern, dest_dir) + source_files = Dir[*pattern] + return if source_files.empty? + + puts "===> Copying #{kind}" + FileUtils.mkdir_p(dest_dir) + source_files.each do |source_file| + dest_file = File.join(dest_dir, File.basename(source_file)) + puts dest_file + FileUtils.cp(source_file, dest_file) + end +end + +copy :fonts, File.join(__dir__, 'fonts', '*.fnt'), File.join(DEST_DIR, 'fonts') +copy :images, File.join(__dir__, 'images', '*.bmp'), File.join(DEST_DIR, 'wps', THEME_NAME) diff --git a/icons/absolutely_nothing-6x18.bmp b/icons/absolutely_nothing-6x18.bmp new file mode 100644 index 0000000..75b4cdc Binary files /dev/null and b/icons/absolutely_nothing-6x18.bmp differ diff --git a/images/batt.bmp b/images/batt.bmp new file mode 100644 index 0000000..85bf32e Binary files /dev/null and b/images/batt.bmp differ diff --git a/images/battchrg.bmp b/images/battchrg.bmp new file mode 100644 index 0000000..a8b200b Binary files /dev/null and b/images/battchrg.bmp differ diff --git a/images/directory.bmp b/images/directory.bmp new file mode 100644 index 0000000..cf57ccc Binary files /dev/null and b/images/directory.bmp differ diff --git a/images/hold.bmp b/images/hold.bmp new file mode 100644 index 0000000..c88ffef Binary files /dev/null and b/images/hold.bmp differ diff --git a/images/playmodes.bmp b/images/playmodes.bmp new file mode 100644 index 0000000..b8c6e3c Binary files /dev/null and b/images/playmodes.bmp differ diff --git a/images/progressbar.bmp b/images/progressbar.bmp new file mode 100644 index 0000000..7e58301 Binary files /dev/null and b/images/progressbar.bmp differ diff --git a/images/progressbar_backdrop.bmp b/images/progressbar_backdrop.bmp new file mode 100644 index 0000000..82925dc Binary files /dev/null and b/images/progressbar_backdrop.bmp differ diff --git a/images/progressbar_slider.bmp b/images/progressbar_slider.bmp new file mode 100644 index 0000000..ddc0587 Binary files /dev/null and b/images/progressbar_slider.bmp differ diff --git a/templates/base.liquid b/templates/base.liquid new file mode 100644 index 0000000..da4ad7d --- /dev/null +++ b/templates/base.liquid @@ -0,0 +1,73 @@ +# {{ theme_name }} Rockbox theme +# Generated using gen_theme.rb at {{ generated_at }} +# +# Theme made by Georg Gadinger in 2021. +# Licensed under CC BY-NC-SA + +# Disable status bar and clear backdrop +%wd +%X(d) + +#################### +# Fonts and images # +#################### +%Fl(2,10-Espy Sans-Bold.fnt) +{{- fonts }} + +%xl(battery,batt.bmp,0,0,16) +%xl(battery_charging,battchrg.bmp,0,0,16) +%xl(playmodes,playmodes.bmp,0,0,9) +%xl(hold,hold.bmp,0,0) +{{- images }} + +############# +# Viewports # +############# +%Vd(playbackmode) +%?if(%mh, =, h)<%Vd(hold_lock)|> +%Vd(title) +%?if(%St(battery display), =, numeric)<%Vd(batteryn)|%Vd(batteryg)> + +%Vd(topbar) +{{- viewports }} + +######################### +# Playback status icons # +######################### +%Vl(playbackmode,1,3,20,10,-) +%xd(playmodes,%mp) + +######################## +# Lock for hold switch # +######################## +%Vl(hold_lock,13,3,8,10,-) +%xd(hold) + +############## +# Menu title # +############## +%Vl(title,20,3,95,13,2) +#%?if(%lh, =, h)<%HDD|> +%ac%?Lt<%?if(%Lt, =, Rockbox)<{{ default_title | default: main_menu_title }}|%?if(%Lt, =, Database)>|{{ default_title | default: main_menu_title }}> + +####################### +# Battery (graphical) # +####################### +%Vl(batteryg,111,3,25,10,-) +%?if(%bp, =, p)<%?if(%bl, >, 94)<%xd(battery_charging, 16)|%?if(%bl, >, 88)<%xd(battery_charging, 15)|%?if(%bl, >, 81)<%xd(battery_charging, 14)|%?if(%bl, >, 75)<%xd(battery_charging, 13)|%?if(%bl, >, 69)<%xd(battery_charging, 12)|%?if(%bl, >, 63)<%xd(battery_charging, 11)|%?if(%bl, >, 56)<%xd(battery_charging, 10)|%?if(%bl, >, 50)<%xd(battery_charging, 9)|%?if(%bl, >, 44)<%xd(battery_charging, 8)|%?if(%bl, >, 38)<%xd(battery_charging, 7)|%?if(%bl, >, 31)<%xd(battery_charging, 6)|%?if(%bl, >, 25)<%xd(battery_charging, 5)|%?if(%bl, >, 19)<%xd(battery_charging, 4)|%?if(%bl, >, 13)<%xd(battery_charging, 3)|%?if(%bl, >, 6)<%xd(battery_charging, 2)|%xd(battery_charging, 1)>>>>>>>>>>>>>>>|%?if(%bl, >, 94)<%xd(battery, 16)|%?if(%bl, >, 88)<%xd(battery, 15)|%?if(%bl, >, 81)<%xd(battery, 14)|%?if(%bl, >, 75)<%xd(battery, 13)|%?if(%bl, >, 69)<%xd(battery, 12)|%?if(%bl, >, 63)<%xd(battery, 11)|%?if(%bl, >, 56)<%xd(battery, 10)|%?if(%bl, >, 50)<%xd(battery, 9)|%?if(%bl, >, 44)<%xd(battery, 8)|%?if(%bl, >, 38)<%xd(battery, 7)|%?if(%bl, >, 31)<%xd(battery, 6)|%?if(%bl, >, 25)<%xd(battery, 5)|%?if(%bl, >, 19)<%xd(battery, 4)|%?if(%bl, >, 13)<%xd(battery, 3)|%?if(%bl, >, 6)<%xd(battery, 2)|%xd(battery, 1)>>>>>>>>>>>>>>>> + +####################### +# Battery (numerical) # +####################### +%Vl(batteryn,110,1,27,10,2) +%ar%?if(%bc, =, c)<+|>%bl%% + +########################## +# Top Bar Separator Line # +########################## +%Vl(topbar,0,17,138,1,-) +%dr(0,0,138,1) + +## {{ filename }} starts below this line ## + +{{ content }} diff --git a/templates/fms.liquid b/templates/fms.liquid new file mode 100644 index 0000000..19d43db --- /dev/null +++ b/templates/fms.liquid @@ -0,0 +1,67 @@ +{% capture fonts %} +%Fl(3,09-Espy Sans-Bold.fnt) +{% endcapture %} + +{% capture images %} +%xl(pbs,progressbar_slider.bmp,0,0) +{% endcapture %} + +{% capture viewports %} +%Vd(metadata) +%?mv<%Vd(volume)|%Vd(frequency)> +{% endcapture %} + +{% capture default_title %}FM Radio{% endcapture %} + +################# +# Preset number # +################# +%Vl(metadata,4,23,130,9,3) +%al%?Ti<%Ti of %Tc|Scan mode> + +# Preset Name or RDS Name +%Vl(metadata,0,44,138,12,-) +%s%ac%?Tn<%Tn|%?ty<%ty|%tf MHz>> + +# RDS Text +%Vl(metadata,0,60,138,12,-) +%s%ac%?tz<%tz|...no RDS info...> + +################### +# Frequency + bar # +################### +# the value +%Vl(frequency,4,98,129,10,2) +%al%tf MHz%ar%?ts +# the bar, borders drawn by hand to avoid flickering +%Vl(frequency,4,85,129,11,-) +# x = 6 (+ 4 _2_); y = 85 +%dr(2, 0, 125, 1) +%dr(1, 1, 1, 1) +%dr(127, 1, 1, 1) +%dr(0, 2, 1, 7) +%dr(128, 2, 1, 7) +%dr(1, 9, 1, 1) +%dr(127, 9, 1, 1) +%dr(2, 10, 125, 1) +%Vl(frequency,6,87,125,7,-) +%pb(0,0,-,-,nobar,nofill,slider,pbs) + +####################### +# Volume + volume bar # +####################### +# the value +%Vl(volume,4,98,129,10,2) +%ac%?if(%pv, >, 0)<+|>%pvdB +# the bar, borders drawn by hand to avoid flickering +%Vl(volume,4,85,129,11,-) +%dr(2, 0, 125, 1) +%dr(1, 1, 1, 1) +%dr(127, 1, 1, 1) +%dr(0, 2, 1, 7) +%dr(128, 2, 1, 7) +%dr(1, 9, 1, 1) +%dr(127, 9, 1, 1) +%dr(2, 10, 125, 1) +%Vl(volume,6,87,125,7,-) +%pv(0,0,-,-,nobar,nofill,slider,pbs) diff --git a/templates/sbs.liquid b/templates/sbs.liquid new file mode 100644 index 0000000..117dc02 --- /dev/null +++ b/templates/sbs.liquid @@ -0,0 +1,44 @@ +{% capture images %} +%xl(directory,directory.bmp,0,0,2) +{% endcapture %} + +{% capture viewports %} +# Always define scroll bar viewport as I have no idea how to properly resize the list items/main viewport. +%Vd(scrollbar) +{%- comment %} +# maybe via something like that? list_[no]scroll would be the %Vi viewport ... +#%?LB<%Vd(scrollbar)%Vd(list_scroll)|%Vd(list_noscroll)> +{% endcomment %} +{% endcapture %} + +################################### +# Menus / Lists (including items) # +################################### + +# Define list item viewport +%Lb(item,138,18) +# TODO: SCROLL BAR -- figure out how to make use of %?LB properly to show/hide it when required +# Scroll bar - outer border +%Vl(scrollbar,129,17,9,92,-)%Vf(0)%dr(0,0,-,-) +# Scroll bar - inner border +%Vl(scrollbar,130,18,7,90,-)%Vf(3)%dr(0,0,-,-) +# Scroll bar - actual bar +%Vl(scrollbar,131,19,5,88,-)%Vb(3)%Vf(0) +%LB(-,-,-,-, invert, noborder, vertical) +# Main list viewport +%Vi(-,0,19,128,91,-) +{%- comment %} +#%Vl(list_scroll,0,19,128,91,-) +#%Vi(list_scroll,0,19,128,91,-) +#%Vl(list_noscroll,0,19,137,91,-) +#%Vi(list_noscroll,0,19,137,91,-) +{% endcomment %} +# Rectangle around list item +%Vl(item,0,0,128,18,-)%Vf(0)%Vb(0) +%?Lc<%dr(0,0,128,-)> +# Draw directory arrow first, otherwise %s gets confused about it +%Vl(item,114,5,12,9,-) +%?if(%LI, >=, 0)<%?Lc<%xd(directory, 2)|%xd(directory, 1)>> +# Position text inside list item (108 = 128 - 6(=x position) - 12(=width of > arrow) - 2(= to make it look nicer :-)) +%Vl(item,6,3,108,13,-) +%?Lc<%Vs(invert)|%Vs(clear)>%s%?if(%cs, =, 1)<%?if(%LT, =, Database)>|%LT> diff --git a/templates/wps.liquid b/templates/wps.liquid new file mode 100644 index 0000000..3eafe21 --- /dev/null +++ b/templates/wps.liquid @@ -0,0 +1,77 @@ +{% capture fonts %} +%Fl(3,09-Espy Sans-Bold.fnt) +{% endcapture %} + +{% capture images %} +%xl(pbbd,progressbar_backdrop.bmp,0,0) +%xl(pbs,progressbar_slider.bmp,0,0) +{% endcapture %} + +{% capture viewports %} +%Vd(playlist_entry) +# Viewport conditionals for album art (the `A` prefix is our indicator if the current track has some) +%?C<%Vd(Ametadata)|%Vd(metadata)> +%?C<%Vd(Aartist)|%Vd(artist)> +# This one displays the volume slider if there is a change in volume, the track position otherwise +%?mv<%Vd(volume)|%Vd(trackpos)> +{% endcapture %} + +{% capture default_title %}Now playing{% endcapture %} + +############# +# Album art # +############# +%ax%Vl(Ametadata,4,36,44,44,-) +%Cl(0,0,44,44,c,c) +%Cd + +################## +# Playlist entry # +################## +%Vl(playlist_entry,4,23,130,9,3) +%al%pp of %pe + +############################ +# Track title or file name # +############################ +%Vl(Ametadata,52,44,82,12,-) +%s%al%?it<%it|%fn> +%Vl(metadata,0,44,138,12,-) +%s%ac%?it<%it|%fn> + +################## +# (Album) artist # +################## +%Vl(Aartist,52,60,82,12,-) +%s%al%?ia<%ia|%?iA<%iA|Unknown Artist>> +%Vl(artist,0,60,138,12,-) +%s%ac%?ia<%ia|%?iA<%iA|Unknown Artist>> + +################## +# Track position # +################## +# the value +%Vl(trackpos,4,98,129,10,2) +%al%pc%ar-%pr +# the bar +%Vl(trackpos,4,85,129,11,-) +%pb(0,0,129,11,image,progressbar.bmp,backdrop,pbbd) + +####################### +# Volume + volume bar # +####################### +# the value +%Vl(volume,4,98,129,10,2) +%ac%?if(%pv, >, 0)<+|>%pvdB +# the bar, borders drawn by hand to avoid flickering +%Vl(volume,4,85,129,11,-) +%dr(2, 0, 125, 1) +%dr(1, 1, 1, 1) +%dr(127, 1, 1, 1) +%dr(0, 2, 1, 7) +%dr(128, 2, 1, 7) +%dr(1, 9, 1, 1) +%dr(127, 9, 1, 1) +%dr(2, 10, 125, 1) +%Vl(volume,6,87,125,7,-) +%pv(0,0,-,-,nobar,nofill,slider,pbs) -- cgit v1.2.3-13-gbd6f