diff options
| author | Lester Caine <lester@lsces.co.uk> | 2026-06-04 10:47:42 +0100 |
|---|---|---|
| committer | Lester Caine <lester@lsces.co.uk> | 2026-06-04 10:47:42 +0100 |
| commit | de955c85fc44c2f437af523b4a19c2bf4a8e3cb7 (patch) | |
| tree | 3d3334a61f8d82d37b7d6cda9b8f404d5480fd73 | |
| parent | 8ea9ae28981761ba32861f5f1b9c74b7aca62a2c (diff) | |
| download | themes-de955c85fc44c2f437af523b4a19c2bf4a8e3cb7.tar.gz themes-de955c85fc44c2f437af523b4a19c2bf4a8e3cb7.tar.bz2 themes-de955c85fc44c2f437af523b4a19c2bf4a8e3cb7.zip | |
Icon system: switch from silk-sprite/colourstrap to Tango3 freedesktop iconset with SVG support
- function.biticon.php: look in util/iconsets/ (moved from config/); add SVG fallback
via scalable/ directory; biticon_first_match accepts optional extensions param;
isize (small/medium/large) mapped to 16/24/32px for SVG width+height; isize added
to ommit list so it never leaks as an HTML attribute
- admin_themes_inc.php: iconset path updated to UTIL_PKG_PATH; biticon_sizes expanded
to small (16px) / medium (24px) / large (32px)
- admin_themes_manager.php: iconset path updated to UTIL_PKG_PATH
- admin_themes_manager.tpl: replace stale Gnome/KDE links with Tango3/freedesktop refs
- icon_browser.php: icon_fetcher now uses scalable/ SVGs as primary name source,
supplements with large/ PNGs; all iconset paths updated to UTIL_PKG_PATH
- icon_browser.tpl: three clean size columns (small/medium/large) using isize=
instead of sloppy iname path embedding; help text updated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| -rwxr-xr-x | admin/admin_themes_inc.php | 7 | ||||
| -rwxr-xr-x | admin/admin_themes_manager.php | 2 | ||||
| -rwxr-xr-x | icon_browser.php | 22 | ||||
| -rwxr-xr-x | smartyplugins/function.biticon.php | 37 | ||||
| -rwxr-xr-x | templates/admin_themes_manager.tpl | 2 | ||||
| -rwxr-xr-x | templates/icon_browser.tpl | 38 |
6 files changed, 60 insertions, 48 deletions
diff --git a/admin/admin_themes_inc.php b/admin/admin_themes_inc.php index 54b0668..6200c88 100755 --- a/admin/admin_themes_inc.php +++ b/admin/admin_themes_inc.php @@ -76,15 +76,16 @@ $gBitSmarty->assign( "biticon_display_options", $biticon_display_options ); // get the icon styles $subDirs = [ 'style_info' ]; -$iconStyles = $gBitThemes->getStylesList( CONFIG_PKG_PATH."styles/icons/", false, $subDirs ); +$iconStyles = $gBitThemes->getStylesList( UTIL_PKG_PATH."iconsets/", false, $subDirs ); foreach( $iconStyles as $key=>$style ){ $iconStyles[$key] = str_replace( "_", " ", $style['style'] ); } $gBitSmarty->assign( "iconStyles", $iconStyles ); $biticon_sizes = [ - 'small' => KernelTools::tra( 'Small' ), - 'large' => KernelTools::tra( 'Large' ), + 'small' => KernelTools::tra( 'Small (16px)' ), + 'medium' => KernelTools::tra( 'Medium (24px)' ), + 'large' => KernelTools::tra( 'Large (32px)' ), ]; $gBitSmarty->assign( "biticon_sizes", $biticon_sizes ); diff --git a/admin/admin_themes_manager.php b/admin/admin_themes_manager.php index 8bac717..29101b2 100755 --- a/admin/admin_themes_manager.php +++ b/admin/admin_themes_manager.php @@ -42,7 +42,7 @@ $stylesList = $gBitThemes->getStylesList( '', false, $subDirs ); $gBitSmarty->assign( "stylesList", $stylesList ); $subDirs = [ 'style_info' ]; -$iconStyles = $gBitThemes->getStylesList( CONFIG_PKG_PATH."iconsets/", false, $subDirs ); +$iconStyles = $gBitThemes->getStylesList( UTIL_PKG_PATH."iconsets/", false, $subDirs ); $gBitSmarty->assign( "iconStyles", $iconStyles ); $styleLayouts = $gBitThemes->getStyleLayouts(); diff --git a/icon_browser.php b/icon_browser.php index 0cf4efe..9c6bda9 100755 --- a/icon_browser.php +++ b/icon_browser.php @@ -56,7 +56,7 @@ $gBitSmarty->assign( 'iconUsage', $iconUsage ); $iconList = []; $iconNames = []; -$iconThemes = ( !empty( $_REQUEST['icon_style'] ) ) ? [ $_REQUEST['icon_style'] ] : scandir( CONFIG_PKG_PATH . "iconsets/" ); +$iconThemes = ( !empty( $_REQUEST['icon_style'] ) ) ? [ $_REQUEST['icon_style'] ] : scandir( UTIL_PKG_PATH . "iconsets/" ); foreach( $iconThemes as $iconStyle ) { if( $icons = icon_fetcher( $iconStyle ) ) { @@ -74,12 +74,24 @@ $gBitSystem->display( 'bitpackage:themes/icon_browser.tpl', KernelTools::tra( 'I function icon_fetcher( $pStyle = DEFAULT_ICON_STYLE ) { $ret = []; if( strpos( $pStyle, '.' ) !== 0 && $pStyle != 'CVS' ) { - $stylePath = CONFIG_PKG_PATH."iconsets/".$pStyle; + $stylePath = UTIL_PKG_PATH."iconsets/".$pStyle; + + // Primary: scalable SVGs give the most complete name list + if( is_dir( $stylePath."/scalable" )) { + foreach( scandir( $stylePath."/scalable" ) as $icon ) { + if( preg_match( "#\.svg$#", $icon )) { + $name = substr( $icon, 0, -4 ); + $ret[$name] = $name; + } + } + } + + // Supplement with large PNGs not covered by scalable if( is_dir( $stylePath."/large" )) { - $handle = opendir( $stylePath."/large" ); - while( false !== ( $icon = readdir( $handle ))) { + foreach( scandir( $stylePath."/large" ) as $icon ) { if( preg_match( "#\.png$#", $icon ) && !preg_match( "#^process-working\.#", $icon )) { - $ret[str_replace( ".png", "", $icon )] = str_replace( ".png", "", $icon ); + $name = substr( $icon, 0, -4 ); + $ret[$name] ??= $name; } } } diff --git a/smartyplugins/function.biticon.php b/smartyplugins/function.biticon.php index 380b76d..a5ce139 100755 --- a/smartyplugins/function.biticon.php +++ b/smartyplugins/function.biticon.php @@ -18,13 +18,9 @@ use Bitweaver\KernelTools; * @access public * @return string|bool Icon name with extension on success, false on failure */ -function biticon_first_match( $pDir, $pFilename ) { +function biticon_first_match( $pDir, $pFilename, $pExtensions = ['png', 'gif', 'jpg'] ) { if( is_dir( $pDir )) { - global $gSniffer; - - $extensions = [ 'png', 'gif', 'jpg' ]; - - foreach( $extensions as $ext ) { + foreach( $pExtensions as $ext ) { if( is_file( $pDir.$pFilename.'.'.$ext ) ) { return $pFilename.'.'.$ext; } @@ -65,7 +61,7 @@ function biticon_output( $pParams, $pFile ) { $outstr .= ' alt=""'; } - $ommit = [ 'ilocation', 'ipackage', 'ipath', 'iname', 'iexplain', 'iforce', 'istyle', 'iclass' ]; + $ommit = [ 'ilocation', 'ipackage', 'ipath', 'iname', 'iexplain', 'iforce', 'istyle', 'iclass', 'isize' ]; foreach( $pParams as $name => $val ) { if( !in_array( $name, $ommit ) ) { $outstr .= ' '.$name.'="'.$val.'"'; @@ -82,6 +78,12 @@ function biticon_output( $pParams, $pFile ) { $outstr .= ' onclick="'.$pParams["onclick"].'"'; } + if( str_ends_with( $pFile, '.svg' ) ) { + $svgSizes = ['small' => 16, 'medium' => 24, 'large' => 32]; + $px = $svgSizes[$pParams['isize'] ?? 'small'] ?? 16; + $outstr .= " width=\"$px\" height=\"$px\""; + } + $outstr .= " />"; if( $gBitSystem->getConfig( 'site_biticon_display_style' ) == 'icon_text' && $pParams['iforce'] != 'icon' || $pParams['iforce'] == 'icon_text' ) { @@ -167,19 +169,30 @@ function smarty_function_biticon( $pParams, $pSmall = false ) { return $ret; } - // first deal with most common scenario: icon style ( a selected iconset from config/iconsets/ ) + // first deal with most common scenario: icon style ( a selected iconset from util/iconsets/ ) if( $pParams['ipackage'] == 'icons' ) { // get the current icon style // istyle is a private parameter!!! - only used on theme manager page for icon preview!!! // violators will be poked with soft cushions by the Cardinal himself!!! $icon_style = !empty( $pParams['istyle'] ) ? $pParams['istyle'] : $gBitSystem->getConfig( 'site_icon_style', DEFAULT_ICON_STYLE ); - if( false !== ( $matchFile = biticon_first_match( CONFIG_PKG_PATH."iconsets/$icon_style".$pParams['ipath'], $pParams['iname'] ))) { - return biticon_output( $pParams, CONFIG_PKG_URL."iconsets/$icon_style".$pParams['ipath'].$matchFile ); + if( false !== ( $matchFile = biticon_first_match( UTIL_PKG_PATH."iconsets/$icon_style".$pParams['ipath'], $pParams['iname'] ))) { + return biticon_output( $pParams, UTIL_PKG_URL."iconsets/$icon_style".$pParams['ipath'].$matchFile ); } - if( $icon_style != DEFAULT_ICON_STYLE && false !== ( $matchFile = biticon_first_match( CONFIG_PKG_PATH."iconsets/".DEFAULT_ICON_STYLE.$pParams['ipath'], $pParams['iname'] ))) { - return biticon_output( $pParams, CONFIG_PKG_URL."iconsets/".DEFAULT_ICON_STYLE.$pParams['ipath'].$matchFile ); + if( $icon_style != DEFAULT_ICON_STYLE && false !== ( $matchFile = biticon_first_match( UTIL_PKG_PATH."iconsets/".DEFAULT_ICON_STYLE.$pParams['ipath'], $pParams['iname'] ))) { + return biticon_output( $pParams, UTIL_PKG_URL."iconsets/".DEFAULT_ICON_STYLE.$pParams['ipath'].$matchFile ); + } + + // SVG fallback: raster not found, try scalable/ directory + $isize = trim( $pParams['ipath'], '/' ); + if( false !== ( $matchFile = biticon_first_match( UTIL_PKG_PATH."iconsets/$icon_style/scalable/", $pParams['iname'], ['svg'] ))) { + $pParams['isize'] = $isize; + return biticon_output( $pParams, UTIL_PKG_URL."iconsets/$icon_style/scalable/".$matchFile ); + } + if( $icon_style != DEFAULT_ICON_STYLE && false !== ( $matchFile = biticon_first_match( UTIL_PKG_PATH."iconsets/".DEFAULT_ICON_STYLE."/scalable/", $pParams['iname'], ['svg'] ))) { + $pParams['isize'] = $isize; + return biticon_output( $pParams, UTIL_PKG_URL."iconsets/".DEFAULT_ICON_STYLE."/scalable/".$matchFile ); } // if that didn't work, we'll try liberty diff --git a/templates/admin_themes_manager.tpl b/templates/admin_themes_manager.tpl index 75207e8..bde786e 100755 --- a/templates/admin_themes_manager.tpl +++ b/templates/admin_themes_manager.tpl @@ -49,7 +49,7 @@ {jstab title="Icon Theme"} {legend legend="Pick Icon Theme"} <p class="help"> - Icon themes can be downloaded from <a class="external" href="http://art.gnome.org/themes/icon/">Gnome</a> or <a class="external" href="http://www.kde-look.org/?xcontentmode=27">KDE</a> as long as they adhere to the <a class="external" href="http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html">Icon Naming Specifications</a>. For more information, please visit <a class="external" href="https://www.bitweaver.org/wiki/IconThemes">IconThemes</a>. + Icon sets must follow the <a class="external" href="https://specifications.freedesktop.org/icon-naming-spec/latest/">freedesktop Icon Naming Specification</a>. The active set is <strong>tango</strong>, sourced from <a class="external" href="https://gitlab.com/tango-project/tango-icon-theme">Tango3</a> (stored in <code>externals/Tango3</code>). Place additional iconsets in <code>util/iconsets/</code>. </p> <p class="help"> If you are a developer and you want to view a list of available icons, you can do this with the {smartlink ititle="Icon Browser" ifile="icon_browser.php"}. diff --git a/templates/icon_browser.tpl b/templates/icon_browser.tpl index 5c51cbc..43ed76f 100755 --- a/templates/icon_browser.tpl +++ b/templates/icon_browser.tpl @@ -6,18 +6,15 @@ <div class="body"> <p class="help"> - {tr}Very much work in progress, but getting there ... need to update the ross reference with current icon names rather than the desktop standard Tango ones!{/tr}<br /> - Source of Fontawesome <a class="external" href="http://fortawesome.github.io/Font-Awesome/">on GitHub</a> for the monochrome icons.<br /> - The font-awesome-to-png python script is used to create an image set for easier handling with the array display.<br /> - <a class="external" href="http://www.famfamfam.com/lab/icons/silk/">Original source of the silk icon set</a> for full colour icons.<br /> - This is enhanced by the <a class="external" href="http://www.fatcow.com/free-icons">FatCow extended icon set</a> which also provides 32x32 versions of the silk library<br /> - See the <a href="/wiki/colourstrap">Colourstrap information page</a> for more data on replacing Bootstraps monochrome icons with traditional colour ones. + Icon sets use <a class="external" href="https://specifications.freedesktop.org/icon-naming-spec/latest/">freedesktop icon naming</a>. + The active set is <strong>tango</strong>, built from <a class="external" href="https://gitlab.com/tango-project/tango-icon-theme">Tango3</a> with raster sizes at 16px (small), 24px (medium) and 32px (large), plus scalable SVGs. + SVGs are served automatically when no raster file exists for the requested size. </p> <table class="table data"> <tr> {foreach from=$iconList item=icons key=iconStyle} <th class="width1p" colspan="3"><a href="{$smarty.request.SCRIPT_NAME}?icon_style={$iconStyle}">{$iconStyle}</a></th> - {/foreach} + {/foreach} <th class="width70p;">{tr}Icon name{/tr}</th> <th class="width29p;">{tr}bitweaver uses{/tr}</th> </tr> @@ -25,25 +22,14 @@ {foreach from=$iconNames item=name} <tr class="{cycle values="odd,even"}"> {foreach from=$iconList item=icons key=iconStyle} - <td {if $gBitSystem->getConfig( 'site_icon_style' ) == $iconStyle}class="prio1"{elseif $iconStyle == $smarty.const.DEFAULT_ICON_STYLE}class="prio2"{/if}> - {if $iconList.$iconStyle.$name} - {* avoid translation here by not using iexplain *} - {biticon istyle=$iconStyle ipackage=icons iname="small/`$iconList.$iconStyle.$name`"} - {/if} - </td> - <td {if $gBitSystem->getConfig( 'site_icon_style' ) == $iconStyle}class="prio1"{elseif $iconStyle == $smarty.const.DEFAULT_ICON_STYLE}class="prio2"{/if}> - {if $iconList.$iconStyle.$name} - {* avoid translation here by not using iexplain *} - {biticon istyle=$iconStyle ipackage=icons iname="large/`$iconList.$iconStyle.$name`"} - {/if} - </td> - <td> - {* only show huge size if looking at a particular set *} - {if $smarty.request.icon_style && $iconList.$iconStyle.$name} - {* avoid translation here by not using iexplain *} - {biticon istyle=$iconStyle ipackage=icons iname="huge/`$iconList.$iconStyle.$name`"} - {/if} - </td> + {assign var=tdClass value=($gBitSystem->getConfig('site_icon_style') == $iconStyle) ? 'prio1' : (($iconStyle == $smarty.const.DEFAULT_ICON_STYLE) ? 'prio2' : '')} + {if $iconList.$iconStyle.$name} + <td class="{$tdClass}">{biticon istyle=$iconStyle ipackage=icons iname=$name isize="small" iexplain=$name}</td> + <td class="{$tdClass}">{biticon istyle=$iconStyle ipackage=icons iname=$name isize="medium" iexplain=$name}</td> + <td class="{$tdClass}">{biticon istyle=$iconStyle ipackage=icons iname=$name isize="large" iexplain=$name}</td> + {else} + <td class="{$tdClass}"></td><td class="{$tdClass}"></td><td class="{$tdClass}"></td> + {/if} {/foreach} <td> |
