mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-21 09:09:01 +00:00
Start abstracting skin data
This commit is contained in:
parent
e75a06a96e
commit
e74eded3f1
5 changed files with 150 additions and 119 deletions
95
css/main.css
95
css/main.css
|
|
@ -64,23 +64,9 @@
|
|||
left: 0;
|
||||
height: 14px;
|
||||
width: 275px;
|
||||
/* background-image: TITLEBAR.BMP via Javascript */
|
||||
background-position: -27px -14px;
|
||||
cursor:url('../cursors/TITLEBAR.PNG?inline'), auto;
|
||||
}
|
||||
|
||||
#title-bar.selected {
|
||||
background-position: -27px 0px;
|
||||
}
|
||||
|
||||
.llama #title-bar {
|
||||
background-position: -27px -61px;
|
||||
}
|
||||
|
||||
.llama #title-bar.selected {
|
||||
background-position: -27px -57px;
|
||||
}
|
||||
|
||||
#option,
|
||||
#minimize,
|
||||
#shade,
|
||||
|
|
@ -101,11 +87,6 @@
|
|||
top: 12px;
|
||||
left: 0px;
|
||||
}
|
||||
#title-bar #option:active,
|
||||
#title-bar #option.selected
|
||||
{
|
||||
background-position: 0 -9px;
|
||||
}
|
||||
#title-bar #option:active #context-menu,
|
||||
#title-bar #option.selected #context-menu
|
||||
{
|
||||
|
|
@ -114,44 +95,20 @@
|
|||
|
||||
#title-bar #minimize {
|
||||
left: 244px;
|
||||
/* background-image: TITLEBAR.BMP via Javascript */
|
||||
background-position: -9px 0;
|
||||
}
|
||||
#title-bar #minimize:active {
|
||||
background-position: -9px -9px;
|
||||
}
|
||||
|
||||
#title-bar #shade {
|
||||
left: 254px;
|
||||
/* background-image: TITLEBAR.BMP via Javascript */
|
||||
background-position: 0px -18px;
|
||||
}
|
||||
#title-bar #shade:active {
|
||||
background-position: -9px -18px;
|
||||
}
|
||||
|
||||
#title-bar #close {
|
||||
left: 264px;
|
||||
/* background-image: TITLEBAR.BMP via Javascript */
|
||||
background-position: -18px 0px;
|
||||
cursor:url('../cursors/CLOSE.PNG?inline'), auto;
|
||||
}
|
||||
#title-bar #close:active {
|
||||
background-position: -18px -9px;
|
||||
}
|
||||
|
||||
.status #clutter-bar {
|
||||
#clutter-bar {
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
left: 10px;
|
||||
height: 43px;
|
||||
width: 8px;
|
||||
/* background-image: TITLEBAR.BMP via Javascript */
|
||||
background-position: -304px 0;
|
||||
}
|
||||
|
||||
.status #clutter-bar.disabled {
|
||||
background-position: -312px 0;
|
||||
}
|
||||
|
||||
#clutter-bar div {
|
||||
|
|
@ -165,38 +122,21 @@
|
|||
top: 3px;
|
||||
height: 8px;
|
||||
}
|
||||
#clutter-bar #button-o:active {
|
||||
background-position: -304px -47px;
|
||||
}
|
||||
#clutter-bar #button-a {
|
||||
top: 11px;
|
||||
}
|
||||
#clutter-bar #button-a:active,
|
||||
#clutter-bar #button-a.selected {
|
||||
background-position: -312px -55px;
|
||||
}
|
||||
#clutter-bar #button-i {
|
||||
top: 18px;
|
||||
}
|
||||
#clutter-bar #button-i:active {
|
||||
background-position: -320px -62px;
|
||||
}
|
||||
#clutter-bar #button-d {
|
||||
top: 25px;
|
||||
height: 8px;
|
||||
}
|
||||
#clutter-bar #button-d:active,
|
||||
#clutter-bar #button-d.selected {
|
||||
background-position: -328px -69px;
|
||||
}
|
||||
#clutter-bar #button-v {
|
||||
top: 33px;
|
||||
}
|
||||
#clutter-bar #button-v:active {
|
||||
background-position: -336px -77px;
|
||||
}
|
||||
|
||||
.status #play-pause {
|
||||
#play-pause {
|
||||
position: absolute;
|
||||
top: 28px;
|
||||
left: 26px;
|
||||
|
|
@ -206,7 +146,7 @@
|
|||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.play .status #work-indicator {
|
||||
.play #work-indicator {
|
||||
position: absolute;
|
||||
top: 28px;
|
||||
left: 24px;
|
||||
|
|
@ -215,13 +155,6 @@
|
|||
/* background-image: PLAYPAUS.BMP via Javascript */
|
||||
background-position: -36px 0;
|
||||
}
|
||||
.play .status #work-indicator.selected {
|
||||
background-position: -39px 0;
|
||||
}
|
||||
|
||||
.play .status #play-pause { }
|
||||
.pause .status #play-pause { background-position: -9px 0; }
|
||||
.stop .status #play-pause { background-position: -18px 0; }
|
||||
.status #time {
|
||||
position: absolute;
|
||||
left: 39px;
|
||||
|
|
@ -243,23 +176,14 @@
|
|||
left: -1px;
|
||||
width: 5px;
|
||||
height: 1px;
|
||||
/* background-image: NUMBERS.BMP via Javascript */
|
||||
background-position: -9px -6px;
|
||||
}
|
||||
.status #time.countdown #minus-sign {
|
||||
background-position: -20px -6px;
|
||||
}
|
||||
|
||||
/* Alternate format for minus sign, when skin supports it */
|
||||
.status #time.ex #minus-sign {
|
||||
top: 0px;
|
||||
left: -1px;
|
||||
width: 9px;
|
||||
height: 13px;
|
||||
/* background-image: NUMS_EX.BMP via Javascript */
|
||||
background-position: -90px 0px;
|
||||
}
|
||||
.status #time.ex.countdown #minus-sign {
|
||||
background-position: -99px 0px;
|
||||
}
|
||||
|
||||
.status #time #minute-first-digit {
|
||||
|
|
@ -658,20 +582,9 @@
|
|||
display: none;
|
||||
}
|
||||
.shade #title-bar {
|
||||
background-position: -27px -42px;
|
||||
cursor:url('../cursors/MAINMENU.PNG?inline'), auto;
|
||||
}
|
||||
|
||||
.shade #title-bar.selected {
|
||||
background-position: -27px -29px;
|
||||
}
|
||||
|
||||
.shade #title-bar #shade {
|
||||
background-position: 0px -27px;
|
||||
}
|
||||
.shade #title-bar #shade:active {
|
||||
background-position: -9px -27px;
|
||||
}
|
||||
.shade .actions div {
|
||||
background: none;
|
||||
position: absolute;
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@
|
|||
<script src="js/visualizer.js?inline"></script>
|
||||
<script src="js/media.js?inline"></script>
|
||||
<script src="js/font.js?inline"></script>
|
||||
<script src="js/skin-sprites.js?inline"></script>
|
||||
<script src="js/skin.js?inline"></script>
|
||||
<script src="js/multi-display.js?inline"></script>
|
||||
<script src="js/hotkeys.js?inline"></script>
|
||||
|
|
|
|||
|
|
@ -32,13 +32,9 @@ Font = {
|
|||
|
||||
// Get a <div> containing a digit
|
||||
digitNode: function(digit) {
|
||||
var horizontalOffset = digit * 9;
|
||||
var div = document.createElement('div');
|
||||
div.classList.add('digit');
|
||||
// Ex rules superseed if nums_ex.bmp is present
|
||||
div.classList.add('digit-ex');
|
||||
div.style.backgroundPosition = '-' + horizontalOffset + 'px 0';
|
||||
div.innerHTML = digit;
|
||||
div.classList.add('digit-' + digit);
|
||||
return div;
|
||||
},
|
||||
|
||||
|
|
|
|||
92
js/skin-sprites.js
Normal file
92
js/skin-sprites.js
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
var SKIN_SPRITES = [
|
||||
{
|
||||
img: "MAIN",
|
||||
sprites: [
|
||||
{ selectors: ["#main-window"], x: 0, y: 0, width: 275, height: 116}
|
||||
]
|
||||
},
|
||||
{
|
||||
img: "NUMBERS",
|
||||
sprites: [
|
||||
{ selectors: ["#time #minus-sign"], x: 9, y: 6, width: 5, height: 1},
|
||||
{ selectors: ["#time.countdown #minus-sign"], x: 20, y: 6, width: 5, height: 1},
|
||||
{ selectors: [".digit-0"], x: 0, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-1"], x: 9, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-2"], x: 18, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-3"], x: 27, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-4"], x: 36, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-5"], x: 45, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-6"], x: 54, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-7"], x: 63, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-8"], x: 72, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-9"], x: 81, y: 0, width: 9, height: 13},
|
||||
]
|
||||
},
|
||||
{
|
||||
img: "NUMS_EX",
|
||||
sprites: [
|
||||
{ selectors: ["#time.ex #minus-sign"], x: 90, y: 0, width: 9, height: 13},
|
||||
{ selectors: ["#time.ex.countdown #minus-sign"], x: 99, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-0"], x: 0, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-1"], x: 9, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-2"], x: 18, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-3"], x: 27, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-4"], x: 36, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-5"], x: 45, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-6"], x: 54, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-7"], x: 63, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-8"], x: 72, y: 0, width: 9, height: 13},
|
||||
{ selectors: [".digit-9"], x: 81, y: 0, width: 9, height: 13},
|
||||
]
|
||||
},
|
||||
{
|
||||
img: "PLAYPAUS",
|
||||
sprites: [
|
||||
{ selectors: [".play #play-pause"], x: 0, y: 0, width: 9, height: 9},
|
||||
{ selectors: [".pause #play-pause"], x: 9, y: 0, width: 9, height: 9},
|
||||
{ selectors: [".stop #play-pause"], x: 18, y: 0, width: 9, height: 9},
|
||||
{ selectors: [".play #work-indicator"], x: 36, y: 0, width: 9, height: 9},
|
||||
{ selectors: [".play #work-indicator.selected"], x: 39, y: 0, width: 9, height: 9}
|
||||
]
|
||||
},
|
||||
{
|
||||
img: "PLEDIT",
|
||||
sprites: [
|
||||
{ selectors: [".playlist-top-tile"], x: 127, y: 21, width: 25, height: 20},
|
||||
{ selectors: [".selected .playlist-top-tile"], x: 127, y: 0, width: 25, height: 20},
|
||||
{ selectors: [".playlist-left-tile"], x: 0, y: 42, width: 25, height: 29},
|
||||
{ selectors: [".playlist-right-tile"], x: 27, y: 42, width: 25, height: 29},
|
||||
{ selectors: [".playlist-bottom-tile"], x: 179, y: 0, width: 25, height: 38},
|
||||
{ selectors: ["#playlist.shade"], x: 72, y: 57, width: 25, height: 14}
|
||||
]
|
||||
},
|
||||
{
|
||||
img: "TITLEBAR",
|
||||
sprites: [
|
||||
{ selectors: ["#title-bar"], x: 27, y: 15, width: 275, height: 14},
|
||||
{ selectors: ["#title-bar.selected"], x: 27, y: 0, width: 275, height: 14},
|
||||
{ selectors: [".lllama #title-bar"], x: 27, y: 61, width: 275, height: 14},
|
||||
{ selectors: [".lllama #title-bar.selected"], x: 27, y: 57, width: 275, height: 14},
|
||||
{ selectors: ["#title-bar #option"], x: 0, y: 0, width: 9, height: 9},
|
||||
{ selectors: ["#title-bar #option"], x: 0, y: 0, width: 9, height: 9},
|
||||
{ selectors: ["#title-bar #option:active", "#title-bar #option:selected"], x: 0, y: 9, width: 9, height: 9},
|
||||
{ selectors: ["#title-bar #minimize"], x: 9, y: 0, width: 9, height: 9},
|
||||
{ selectors: ["#title-bar #minimize:active"], x: 9, y: 9, width: 9, height: 9},
|
||||
{ selectors: ["#title-bar #shade"], x: 0, y: 18, width: 9, height: 9},
|
||||
{ selectors: ["#title-bar #shade:active"], x: 9, y: 18, width: 9, height: 9},
|
||||
{ selectors: ["#title-bar #close"], x: 18, y: 0, width: 9, height: 9},
|
||||
{ selectors: ["#title-bar #close:active"], x: 18, y: 9, width: 9, height: 9},
|
||||
{ selectors: ["#clutter-bar"], x: 304, y: 0, width: 8, height: 43},
|
||||
{ selectors: ["#clutter-bar.disabled"], x: 312, y: 0, width: 8, height: 43},
|
||||
{ selectors: ["#button-o:active", "#button-0:selected"], x: 304, y: 47, width: 8, height: 8},
|
||||
{ selectors: ["#button-a:active", "#button-a.selected"], x: 312, y: 55, width: 8, height: 7},
|
||||
{ selectors: ["#button-i:active", "#button-i.selected"], x: 320, y: 62, width: 8, height: 7},
|
||||
{ selectors: ["#button-d:active", "#button-d.selected"], x: 328, y: 69, width: 8, height: 8},
|
||||
{ selectors: ["#button-v:active", "#button-v.selected"], x: 336, y: 77, width: 8, height: 7},
|
||||
{ selectors: [".shade #title-bar"], x: 27, y: 42, width: 275, height: 14},
|
||||
{ selectors: [".shade #title-bar.selected"], x: 27, y: 29, width: 275, height: 14},
|
||||
{ selectors: [".shade #title-bar #shade"], x: 0, y: 27, width: 9, height: 9},
|
||||
{ selectors: [".shade #title-bar #shade:active"], x: 9, y: 27, width: 9, height: 9}
|
||||
]
|
||||
},
|
||||
];
|
||||
75
js/skin.js
75
js/skin.js
|
|
@ -8,19 +8,6 @@ SkinManager = {
|
|||
},
|
||||
|
||||
_skinImages: {
|
||||
"#main-window": "MAIN.BMP",
|
||||
"#title-bar": "TITLEBAR.BMP",
|
||||
"#title-bar #option": "TITLEBAR.BMP",
|
||||
"#title-bar #minimize": "TITLEBAR.BMP",
|
||||
"#title-bar #shade": "TITLEBAR.BMP",
|
||||
"#title-bar #close": "TITLEBAR.BMP",
|
||||
".status #clutter-bar": "TITLEBAR.BMP",
|
||||
".status #clutter-bar div:active": "TITLEBAR.BMP",
|
||||
".status #clutter-bar div.selected": "TITLEBAR.BMP",
|
||||
".status #play-pause": "PLAYPAUS.BMP",
|
||||
".play .status #work-indicator": "PLAYPAUS.BMP",
|
||||
".status #time #minus-sign": "NUMBERS.BMP",
|
||||
".status #time.ex #minus-sign": "NUMS_EX.BMP",
|
||||
".media-info .mono-stereo div": "MONOSTER.BMP",
|
||||
"#volume": "VOLUME.BMP",
|
||||
"#volume::-webkit-slider-thumb": "VOLUME.BMP",
|
||||
|
|
@ -36,7 +23,6 @@ SkinManager = {
|
|||
"#eject": "CBUTTONS.BMP",
|
||||
".shuffle-repeat div": "SHUFREP.BMP",
|
||||
".character": "TEXT.BMP",
|
||||
".digit": "NUMBERS.BMP",
|
||||
// Put this second, since it will trump .digit
|
||||
".digit-ex": "NUMS_EX.BMP",
|
||||
".shade #position": "TITLEBAR.BMP",
|
||||
|
|
@ -44,6 +30,9 @@ SkinManager = {
|
|||
".shade #position::-moz-range-thumb": "TITLEBAR.BMP",
|
||||
},
|
||||
|
||||
// For sprites that tile, we need to use just the sprite, not the whole image
|
||||
_skinSprites: SKIN_SPRITES,
|
||||
|
||||
// Given a file of an original Winamp WSZ file, set the current skin
|
||||
setSkinByFile: function(file, completedCallback) {
|
||||
this.completedCallback = completedCallback;
|
||||
|
|
@ -56,16 +45,14 @@ SkinManager = {
|
|||
var zip = new JSZip(buffer);
|
||||
document.getElementById('time').classList.remove('ex');
|
||||
|
||||
this._createNewStyleNode();
|
||||
|
||||
var cssRules = '';
|
||||
for(var selector in SkinManager._skinImages) {
|
||||
var fileName = SkinManager._skinImages[selector];
|
||||
var promisedCssRules = [];
|
||||
for(var selector in this._skinImages) {
|
||||
var fileName = this._skinImages[selector];
|
||||
var file = this._findFileInZip(fileName, zip);
|
||||
|
||||
if (file) {
|
||||
var value = "background-image: url(data:image/bmp;base64," + btoa(file.asBinary()) + ")";
|
||||
cssRules += selector + "{" + value + "}\n";
|
||||
promisedCssRules.push(selector + "{" + value + "}");
|
||||
|
||||
// CSS has to change if this file is present
|
||||
if(fileName == 'NUMS_EX.BMP') {
|
||||
|
|
@ -74,9 +61,24 @@ SkinManager = {
|
|||
}
|
||||
}
|
||||
|
||||
this.styleNode.appendChild(document.createTextNode(cssRules));
|
||||
this._parseVisColors(zip);
|
||||
this.completedCallback();
|
||||
Array.prototype.push.apply(promisedCssRules, this._skinSprites.map(function(spriteObj) {
|
||||
var file = this._findFileInZip(spriteObj.img, zip);
|
||||
if (file) {
|
||||
var src = "data:image/bmp;base64," + btoa(file.asBinary());
|
||||
return this._spriteCssRule(src, spriteObj);
|
||||
}
|
||||
}, this));
|
||||
|
||||
|
||||
// Extract sprite images
|
||||
Promise.all(promisedCssRules).then(function(newCssRules) {
|
||||
this._createNewStyleNode();
|
||||
cssRules = newCssRules.join('\n');
|
||||
console.log(cssRules.length);
|
||||
this.styleNode.appendChild(document.createTextNode(cssRules));
|
||||
this._parseVisColors(zip);
|
||||
this.completedCallback();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_parseVisColors: function(zip) {
|
||||
|
|
@ -109,5 +111,32 @@ SkinManager = {
|
|||
}
|
||||
this.styleNode = document.createElement('style');
|
||||
document.head.appendChild(this.styleNode);
|
||||
},
|
||||
|
||||
// Given an image URL and coordinates, returns a data url for a sub-section
|
||||
// of that image
|
||||
_spriteCssRule: function(src, spriteObj) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var imageObj = new Image();
|
||||
imageObj.src = src;
|
||||
|
||||
imageObj.onload = function() {
|
||||
var skinImage = this;
|
||||
var cssRules = '';
|
||||
var canvas = document.createElement('canvas');
|
||||
spriteObj.sprites.forEach(function(sprite) {
|
||||
canvas.height = sprite.height;
|
||||
canvas.width = sprite.width;
|
||||
|
||||
var context = canvas.getContext('2d');
|
||||
context.drawImage(skinImage, -sprite.x, -sprite.y);
|
||||
var value = "background-image: url(" + canvas.toDataURL() + ")";
|
||||
sprite.selectors.forEach(function(selector) {
|
||||
cssRules += selector + "{" + value + "}\n";
|
||||
});
|
||||
});
|
||||
resolve(cssRules);
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue