View Single Post
Old 17th March 2005, 20:27   #6
PulseDriver
w3 addict
(Major Dude)
 
PulseDriver's Avatar
 
Join Date: May 2004
Location: Norway
Posts: 1,806
There is a bug that makes rotational layers unaffected by color themes unless you refresh the skin, the layer moved or you restart winamp, so the only way to "fix" this for now is to make the layer move all the time (even if the eye/computer can't see/visualize it).

I've ripped out the volume knob from my Pulsedriver skin, here is the source for the maki. The reason it's so complex is that many of the functions included controlled 5 more knobs so instead of writing functions for each knob I made the original functions more dynamic.

code:

/*
*
* INFORMATION
*
* Ok, this massive script is built up by snipplets from many scripts.
* First of all I want to thank FrisbeeMoney for sharing knowledge, and
* actually seem happy about doing so. Whish more people was like him.
* Anyways, here comes the list, and who wrote some of the parts I have
* used for my script.
*
*
* FrisbeeMonkey <volume.m> (Maki Cheats from http://forums.winamp.com/)
*
*
*/


#include <std.mi>

#ifndef PI
#define PI 3.1415926536
#endif

Function KnobPosition(Layer thisKnob, Slider thisSlider);
Function KnobUpdate(float v, Layer thisKnob, Boolean UpdateSongTicker);
Function KnobUpdateSongTicker(String KnobName, float v);
Function KnobRelease(int x, int y, int thisFlag, Layer thisKnob, Map thisMap);
Function KnobMove(int x, int y, int thisFlag, Layer thisKnob, Map thisMap);
Function KnobRotate(float newVal, Layer thisKnob);
Function KnobInit(Layer thisKnob);
Function KnobRotationDegree(double r, Layer thisKnob);
Function KnobRotation(double r, Layer thisKnob);

Global Container MainContainer;
Global Layout MainLayout;
Global Group ThisGroup;
Global Map VolumeMap;
Global Timer KnobTimer;
Global Slider HiddenVolume;
Global Double KnobR;
Global Int CurrVolume, VolFrames, VolumeFlag;
Global Layer VolumeKnob, Volume;
Global Boolean ValueChanging, KnobToggle;
Global Float VolumeLevel, CurrentVolume, VolumeValue;
Global Double VolumeRotate;

System.onScriptLoaded(){

MainContainer = getContainer("main");
MainLayout = MainContainer.getLayout("player");

VolumeKnob = MainLayout.findObject("volume.knob");
Volume = MainLayout.findObject("volume.pointer");
HiddenVolume = MainLayout.findObject("volume.hidden");

ValueChanging = false;

VolumeMap = new Map;
VolumeMap.loadMap("volume.map");

KnobInit(Volume);

VolumeFlag = 0;

float u = System.GetVolume();

u = u / 255;

KnobRotate(u, Volume);

KnobToggle = 0;
}

HiddenVolume.onPostedPosition(int p) {
if (!ValueChanging) {
Float f = System.GetVolume();
f = f / 255;
KnobRotate(f, Volume);
}
}

System.onVolumeChanged(int NewVol){
int v = System.getVolume();
float k = v / 255;
int p = k * 100;
}

Volume.fx_onGetPixelR(double r, double d, double x, double y) {
return r + VolumeRotate;
}

VolumeKnob.onMouseMove(int x, int y) {
KnobMove(x, y, VolumeFlag, Volume, VolumeMap);
}

VolumeKnob.onLeftButtonUp(int x, int y){
KnobRelease(x, y, VolumeFlag, Volume, VolumeMap);
}

VolumeKnob.onLeftButtonDown(int x, int y) {
ValueChanging = true;
}

System.onScriptUnloading(){
delete VolumeMap;
}

KnobMove(int x, int y, int thisFlag, Layer thisKnob, Map thisMap){
if (ValueChanging) {
x = x - thisKnob.getLeft();
y = y - thisKnob.getTop();
if (thisMap.inRegion(x, y)) {
float v = thisMap.getValue(x, y);
if (!thisFlag) {
KnobUpdate(v, thisKnob, true);
if (v > 245) {
thisFlag = 2;
KnobUpdate(255, thisKnob, true);
}
if (v < 10) {
thisFlag = 1;
KnobUpdate(0, thisKnob, true);
}
}
else {
if ((thisFlag == 2) && (v > 120) && (v < 252)) thisFlag = 0;
if ((thisFlag == 1) && (v < 120) && (v > 2)) thisFlag = 0;
}
}
}
}

KnobRelease(int x, int y, int thisFlag, Layer thisKnob, Map thisMap){
if (ValueChanging) {
x = x - thisKnob.getLeft();
y = y - thisKnob.getTop();
if (thisMap.inRegion(x, y)) {
float v = thisMap.getValue(x, y);
if (!thisFlag) {
KnobUpdate(v, thisKnob, true);
if (v > 245) {
thisFlag = 2;
KnobUpdate(255, thisKnob, true);
}
if (v < 10) {
thisFlag = 1;
KnobUpdate(0, thisKnob, true);
}
}
else {
if ((thisFlag == 2) && (v > 120) && (v < 252)) thisFlag = 0;
if ((thisFlag == 1) && (v < 120) && (v > 2)) thisFlag = 0;
}
}
ValueChanging = false;
}
}

KnobUpdate(float v, Layer thisKnob, Boolean UpdateSongTicker){
if(thisKnob == Volume){
if (v >= 0) {
float k = v / 255;
KnobRotate(k, thisKnob);

if(UpdateSongTicker){
HiddenVolume.setPosition(v);
}
}
}
}

KnobRotate(float newVal, Layer thisKnob){
newVal = newVal * 270;
KnobRotationDegree(-newVal, thisKnob);
}

KnobInit(Layer thisKnob) {
thisKnob.fx_setGridSize(10,10);
thisKnob.fx_setBgFx(0);
thisKnob.fx_setWrap(0);
thisKnob.fx_setBilinear(1);
thisKnob.fx_setRect(0);
thisKnob.fx_setClear(0);
thisKnob.fx_setLocalized(1);
thisKnob.fx_setRealtime(0);
thisKnob.fx_setEnabled(1);
}

KnobRotationDegree(double r, Layer thisKnob) {
KnobRotation(r * PI / 180.0, thisKnob);
}

KnobRotation(double r, Layer thisKnob){
if(thisKnob == Volume){
VolumeRotate = r;
Volume.fx_update();
}
}



And here is the XML

PHP Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<WinampAbstractionLayer version="0.8">
  <skininfo>
    <version>1.0</version>
    <name></name>
    <comment></comment>
    <author></author>
    <email></email>
    <homepage></homepage>
    <screenshot></screenshot>
  </skininfo> 

  <elements>
    <bitmap id="main.body" file="images/main.body.png" />
    <bitmap id="volume.knob" file="images/volume.knob.png" />
    <bitmap id="volume.pointer" file="images/volume.pointer.png" />
    <bitmap id="volume.map" file="images/volume.map.png" />
    <bitmap id="volume.shade" file="images/volume.shade.png" />
  </elements>

  <groupdef id="player.body" w="60" h="60">

    <!-- VOLUME KNOB -->

    <slider
      id="volume.hidden"
      action="Volume"
      x="0"
      y="0"
      w="0"
      h="0"
      thumb="volume.knob"
      alpha="0"
    />

    <layer
      id="volume.shade"
      image="volume.shade"
      x="0"
      y="0"
      rectrgn="0"
      move="0"
    />

    <layer
      id="volume.knob"
      image="volume.knob"
      x="0"
      y="0"
      rectrgn="0"
      move="0"
    />

    <layer
      id="volume.pointer"
      image="volume.pointer"
      elementframes="2"
      x="0"
      y="0"
      rectrgn="0"
      ghost="1"
      move="0"
    />

    <layer
      id="volume.overlay"
      image="volume.overlay"
      x="0"
      y="0"
      ghost="1"
      rectrgn="0"
      move="0"
    />
  </groupdef>

  <container id="main" name="knob_rotate" default_x="0" default_y="0" default_visible="1">
    <layout id="player" background="main.body" x="0" y="0" w="60" h="60">
      <group id="player.body" x="-1" y="-1" />
    </layout>
  </container>

  <script id="rotational_knob.script" file="scripts/rotational_knob.maki" />

</WinampAbstractionLayer>
Or just download this, a fully functional skin, but I've ripped everything away but the volume knob with the source included. 17Kb

Note that it's the pointer that is rotating, which is an image of the same size as the rest of the volume-knob layers, but it's easily removed and changed to the massive layer instead.

Screenshot




Move the skin by using the corners...
Attached Files
File Type: zip rotational_knob.zip (17.6 KB, 219 views)

09 F9 11 01 9D 74 E8 5B D8 41 56 C3 63 56 81 C0

Last edited by PulseDriver; 17th March 2005 at 21:31.
PulseDriver is offline   Reply With Quote