add some fancy binary/rotary switches to phast

This commit is contained in:
Michael Becker 2024-03-17 02:07:16 -04:00
parent 3ffd2461c2
commit 9499d4535f
5 changed files with 316 additions and 0 deletions

View File

@ -0,0 +1,47 @@
function BinarySwitch(parentElement)
{
this.ParentElement = parentElement;
this.SwitchesElement = this.ParentElement.children[0];
this.InputElement = this.ParentElement.children[1];
var switches = this.SwitchesElement.children;
for (var i = 0; i < switches.length; i++)
{
switches[i].__BinarySwitch = this;
switches[i].addEventListener("change", function(e)
{
this.__BinarySwitch.update();
}, true);
}
this.update = function()
{
var value = 0;
var switches = this.SwitchesElement.children;
for (var i = 0; i < switches.length; i++)
{
if (System.ClassList.Contains(switches[i], "uwt-selected"))
{
if (this.ParentElement.getAttribute("data-endianness") == "little")
{
value += (2 ** (switches.length - i - 1));
}
else
{
value += (2 ** i);
}
}
}
this.InputElement.value = value;
};
}
window.addEventListener("load", function()
{
var items = document.getElementsByClassName("uwt-binaryswitch");
for (var i = 0; i < items.length; i++)
{
items[i].NativeObject = new BinarySwitch(items[i]);
}
});

View File

@ -0,0 +1,40 @@
function RotarySwitch(parentElement)
{
console.log("found rotarySwitch");
console.log(parentElement);
this.ParentElement = parentElement;
this.ValueElement = this.ParentElement.children[0];
this.ListElement = this.ParentElement.children[1];
this.IndicatorElement = this.ParentElement.children[2];
this.AngleOffset = -135;
this.setValue = function(value, angle)
{
this.ValueElement.value = value;
console.log("new angle: " + (angle + this.AngleOffset));
this.IndicatorElement.style.transform = "rotate(" + (angle + this.AngleOffset) + "deg)";
};
for (var i = 0; i < this.ListElement.children.length; i++)
{
this.ListElement.children[i].children[0].NativeObject = this;
this.ListElement.children[i].children[0].addEventListener("click", function(e)
{
this.NativeObject.setValue(this.getAttribute("data-value"), parseFloat(this.getAttribute("data-angle")));
e.preventDefault();
e.stopPropagation();
return false;
});
}
}
window.addEventListener("load", function()
{
var items = document.getElementsByClassName("uwt-rotaryswitch");
for (var i = 0; i < items.length; i++)
{
items[i].NativeObject = new RotarySwitch(items[i]);
}
});

View File

@ -0,0 +1,19 @@
function Switch(parentElement)
{
this.ParentElement = parentElement;
this.ParentElement.addEventListener("click", function()
{
System.ClassList.Toggle(this, "uwt-selected");
System.RaiseEvent(this, "change", null);
});
}
window.addEventListener("load", function()
{
var items = document.getElementsByClassName("uwt-switch");
for (var i = 0; i < items.length; i++)
{
items[i].NativeObject = new Switch(items[i]);
}
});

View File

@ -0,0 +1,130 @@
<?php
namespace Phast\WebControls;
use Phast\Enumeration;
use Phast\WebControl;
use Phast\WebControlAttribute;
/**
* Provides an enumeration of predefined values for endianness.
* @author Michael Becker
*/
abstract class BinarySwitchEndianness extends Enumeration
{
/**
* Big endian.
* @var int 1
*/
const BigEndian = 1;
/**
* Little endian.
* @var int 2
*/
const LittleEndian = 2;
}
class BinarySwitch extends WebControl
{
public $Name;
public int $Value;
public $Endianness;
public int $MinimumValue;
public int $MaximumValue;
public function __construct()
{
parent::__construct();
$this->TagName = "div";
$this->ClassList[] = "uwt-binaryswitch";
$this->MinimumValue = 0;
$this->MaximumValue = 255;
$this->Value = 0;
$this->Endianness = BinarySwitchEndianness::BigEndian;
}
/**
* Gets the number of switches necessary to represent values less than or equal to MaximumValue.
*/
private function getNumSwitches()
{
return ceil(log(($this->MaximumValue - $this->MinimumValue) + 1, 2));
}
private function getSwitchState()
{
$ary = [];
$n = $this->getNumSwitches();
for ($i = 0; $i < $n; $i++)
{
if ($this->Endianness == BinarySwitchEndianness::BigEndian)
{
$v = pow(2, $i);
}
else
{
$v = pow(2, ($n - $i - 1));
}
$val = (($this->Value & $v) == $v);
$ary[] = $val;
}
return $ary;
}
protected function RenderBeginTag()
{
if ($this->Endianness == BinarySwitchEndianness::BigEndian)
{
$this->Attributes[] = new WebControlAttribute("data-endianness", "big");
}
else if ($this->Endianness == BinarySwitchEndianness::LittleEndian)
{
$this->Attributes[] = new WebControlAttribute("data-endianness", "little");
}
parent::RenderBeginTag();
echo("<div class=\"uwt-binaryswitch-switches\">");
$nSwitches = $this->getSwitchState();
for ($i = 0; $i < count($nSwitches); $i++)
{
if ($this->Endianness == BinarySwitchEndianness::BigEndian)
{
$val = pow(2, $i);
}
else
{
$val = pow(2, (count($nSwitches) - $i - 1));
}
echo ("<div class=\"uwt-switch uwt-orientation-vertical");
if ($nSwitches[$i])
{
echo(" uwt-selected");
}
echo("\">");
echo ("<label class=\"uwt-switch-label\">" . $val . "</label>");
echo ("<div class=\"uwt-switch-indicator\">&nbsp;</div>");
echo ("</div>");
}
echo ("</div>");
echo ("<input class=\"uwt-binaryswitch-input\" type=\"text\" inputmode=\"numeric\" pattern=\"\\d*\" name=\"" . $this->Name . "\" value=\"" . $this->Value . "\" />");
echo ("<label class=\"uwt-binaryswitch-label\">" . $this->Value . "</label>");
}
protected function RenderContent()
{
}
}
?>

View File

@ -0,0 +1,80 @@
<?php
namespace Phast\WebControls;
use Phast\WebControl;
use Phast\WebControlAttribute;
class RotarySwitchOption
{
public string $Value;
public function __construct(string $value)
{
$this->Value = $value;
}
}
class RotarySwitch extends WebControl
{
public $Name;
public $Value;
public array $Options;
public function __construct()
{
parent::__construct();
$this->TagName = "div";
$this->ClassList[] = "uwt-rotaryswitch";
$this->Options = array();
$this->Value = "";
}
protected function RenderBeginTag()
{
parent::RenderBeginTag();
echo ("<select name=\"" . $this->Name . "\" class=\"uwt-rotaryswitch-input\" value=\"" . $this->Value . "\">");
foreach ($this->Options as $opt)
{
echo("<option value=\"" . $opt->Value . "\">" . $opt->Value . "</option>");
}
echo("</select>");
$circle_size = 64;
echo ("<ul>");
// thanks https://css-tricks.com/snippets/sass/placing-items-circle/
$count = count($this->Options);
$rot_offset = 45;
if ($count > 0)
{
$angle = (360 / $count);
$rot = $rot_offset;
foreach ($this->Options as $opt)
{
echo ("<li style=\"transform: rotate(" . $rot . "deg)\"><a data-value=\"" . $opt->Value . "\" data-angle=\"" . $rot . "\" style=\"transform: rotate(" . (-1 * $rot) . "deg);\" href=\"#\">" . $opt->Value . "</a></li>");
$rot += $angle;
}
}
echo ("</ul>");
echo ("<div class=\"uwt-rotaryswitch-indicator\">&nbsp;</div>");
}
protected function RenderContent()
{
}
}
?>