Das Problem:
Wenn ein dynamisches Textfeld auf der obersten Ebene einer Schaltfläche liegt, erscheint beim Darüberfahren mit der Maus nicht wie beim Rest der Schaltfläche der Hand-Cursor, sondern der normale Mauszeiger, auch wenn die akive Fläche des Buttons weiterhin bestehen bleibt.
Im Klartext: Ein Button mit oben aufliegendem dynamischen Textfeld bleibt klickbar, aber der Mauszeiger wechselt über der betreffenden Textfläche nicht wie gewünscht zum Hand-Cursor.
Abhilfe:
Unter ActionScript 2 beheben wir dieses Phänomen, indem wir das “selectable”-Attribut des betreffenden Textfeldes auf false setzen. Die Möglichkeit, den Inhalt eines Textfeldes auszuwählen, steht nämlich bei AS2 in Konkurrenz zu den MouseEvents, die bei auswählbaren Textfeldern unter AS2 nicht an die dahinter liegende aktive Fläche eines Buttons weitergereicht (und somit ausgewertet) werden können.
Unter AS2 hilft uns diese Anweisung, um den Mauszeigerwechsel auch über Textfeldern zu bewirken:
Textfeld.selectable = false;
Dies hilft uns allerdings unter ActionScript3 nicht weiter. Auch wenn ein Textfeld nicht auswählbar ist, fängt es trotzdem etwaige MouseEvents ab, die dann nicht mehr für darunterliegende Schaltflächen zur Verfügung stehen.
Wir schaffen für dieses Problem Abhilfe, indem wir das “mouseEnabled”-Attribut heranziehen, das seit AS3 auch für alle Textfelder bereitsteht. Wenn wir mit Hilfe von
Textfeld.mouseEnabled = false;
verhindern, dass das Textfeld selbst auf Mausevents reagiert, halten wir so gleichzeitig auch den “Luftraum” über der aktiven Schaltfläche frei. Anschließend wird nicht mehr das Textfeld, sondern wie gewünscht die dahinterliegende Schaltfläche für MouseEvents empfänglich..
Find some tricks on how to use Smarty effectively here.
Array handling in Smarty
Arrays are a bit tricky to handle in Smarty. But only at first glance! If you know your way around, it´s pretty easy to cope with them. Note that you can use virtually every native php-function by using modifiers, which allow you to use smarty as a smart wrapper for all php-functions:
array_push
let´s say you want to push the value “new” to an existing array named $offers. You can simply do so by using this term:
{$offers|@array_push:"new"}
Note the @-identifier, which makes smarty process the given array as a whole, rather than iterating through each element of the array.
This approach has a disadvantage, though. After having executed array_push, the returning result will be piped to smarty and therefore we have an unwanted output of the function´s result.
We can simply avoid this by following this approach:
By doing so, we are assigning the return value from array_push to a variable (named “void”). As a result, the return-value is being stored in a variable rather than leading to an unwanted output of the latter.
in_array
if you want to check whether a the given value “new” exists within a given $offers, try this:
I am willing to grant you a first little insight into my actionscript (AS3) poison cabinet today.
/* ----------------------------------------------------- */
/* coding: timor kodal [pulsar-network] */
/* copyright by: (c) 2010 timor kodal */
/* ----------------------------------------------------- */
/* contact: [http://pulsar.cc | timor [at] kodal.de */
/* ----------------------------------------------------- */
/* to see this and other scripts in action, please visit */
/* http://pulsar.cc */
/* ----------------------------------------------------- */
/* you are free to use my scripts */
/* according to the creative commons licence cc-nc-by */
/* ----------------------------------------------------- */
/* more information: http://creativecommons.org */
/* ----------------------------------------------------- */
package pflash.widget
{
import flash.display.*;
import flash.events.Event;
import flash.geom.*;
import flash.text.TextField;
import flash.text.TextFormat;
public class Flowchart extends MovieClip {
public var data : Object;
public var graph : Array;
public var range : Object;
public var colors : Array;
public var captionDuration = 400;
public var captionPosition : String = "final";
public var mcGrid : MovieClip;
public var mcStats : MovieClip;
public var w : Number = 200;
public var h : Number = 80;
public var invertX : Boolean = false;
public var invertY : Boolean = true;
public var dateX : Boolean = false;
public var dateY : Boolean = false;
public var intervalX : Number = 5;
public var intervalY : Number = 5;
public var highlightX : Number = 4;
public var highlightY : Number = 4;
public var meterX : Number = 1;
public var meterY : Number = 1;
public var textFormat : TextFormat = null;
/* CONSTRUCTOR */
public function Flowchart (data = false) {
this.data = new Object();
this.graph = new Array();
this.range = new Object();
this.colors = new Array();
this.colors['default'] = [uint(0xff8888),uint(0x44ff44)];
this.colors['gridX'] = uint(0x888888);
this.colors['gridY'] = uint(0x888888);
this.colors['meterX'] = uint(0x444444);
this.colors['meterY'] = uint(0x444444);
if (data)
this.importArray(data);
}
public function createGradient(colors,alphas:Array = null,ratios:Array = null):Object {
var gradient = new Object();
gradient.colors = colors;
if (alphas)
gradient.alphas = alphas;
else
gradient.alphas = [0.6,0.2];
if (ratios)
gradient.ratios = ratios;
else
gradient.ratios = [0x00,0xff];
return gradient;
}
private function drawStats (): Sprite {
var stats = new Sprite();
var dots = new Sprite();
stats.addChild(dots);
var realx;
var point:Point;
var nextPoint:Point;
var color;
var x1,x2,y1,y2: Number;
var first = new Array();
var last = new Array();
var typecount = 0;
var that = this;
for (var type in this.graph) {
if (this.colors[type]) {
color = this.colors[type];
} else if (typeof this.colors['default']=="number") {
color = this.colors['default'];
} else if (this.colors['default'][typecount%this.colors['default'].length]) {
color = this.colors['default'][typecount%this.colors['default'].length];
}
var label = new MovieClip();
if (typeof(color)=="object") {
stats.graphics.lineStyle(2,color.colors[0],0.8);
dots.graphics.lineStyle(2,color.colors[0],1);
label.graphics.beginFill(this.colors[type].colors[0]);
if (!color.matrix) {
color.matrix = new Matrix();
color.matrix.createGradientBox(this.h,80,Math.PI / 2,10,0);
}
stats.graphics.beginGradientFill(GradientType.LINEAR, color.colors, color.alphas, color.ratios, color.matrix, SpreadMethod.PAD);
} else {
stats.graphics.lineStyle(2,color,0.8);
dots.graphics.lineStyle(2,color,1);
stats.graphics.beginFill(color,0.4);
label.graphics.beginFill(color,0.8);
}
for (var x in this.graph[type]) {
point = this.graph[type][x];
x1 = (point.x-this.range.minx)/(this.range.maxx-this.range.minx)*this.w;
if (this.invertX)
x1 = this.w-x1;
y1 = (point.y-this.range.miny)/(this.range.maxy-this.range.miny)*this.h;
if (this.invertY)
y1 = this.h-y1;
if (!first[type]) {
first[type] = new Point(x1,y1);
stats.graphics.moveTo(x1,y1);
}
stats.graphics.lineTo(x1,y1);
dots.graphics.drawCircle(x1,y1,1);
if (this.graph[type][x+1]) {
nextPoint = this.graph[type][x+1];
trace(Math.floor(x1)+"x"+Math.floor(y1)+":"+Math.floor(x2)+"x"+Math.floor(y2));
} else {
nextPoint = new Point(point.x,this.range.miny);
if (that.captionDuration!=="permanent") {
label.addEventListener(Event.ENTER_FRAME,labelView);
var count = 0;
function labelView(e: Event) {
count++;
if (count>that.captionDuration)
e.target.alpha/=1.1;
}
}
var textfield = new TextField();
textfield.htmlText = "<font face='Helvetica,Verdana,Arial' color='#000000' size='7px'>"+type+"</font>";
textfield.selectable = false;
label.graphics.drawRect(0, 2, textfield.textWidth+3,textfield.textHeight);
label.graphics.endFill();
if (this.captionPosition=="final") {
label.y=y1-5;
label.x=x1+5;
} else {
label.y=0+typecount*(textfield.textHeight+1);
label.x=this.w+5;
}
if (label.x+textfield.textWidth>this.w-10)
label.x-=textfield.textWidth+12;
label.addChild(textfield);
label.alpha=0.8;
stats.addChild(label);
}
x2 = (nextPoint.x-this.range.minx)/(this.range.maxx-this.range.minx)*this.w;
if (this.invertX)
x2 = this.w-x2;
y2 = (nextPoint.y-this.range.miny)/(this.range.maxy-this.range.miny)*this.h;
if (this.invertY)
y2 = this.h-y2;
stats.graphics.lineTo(x2,y2);
last[type]=new Point(x2,y2);
}
stats.graphics.lineTo(last[type].x,this.h);
stats.graphics.lineTo(first[type].x,this.h);
stats.graphics.endFill();
typecount++;
}
return stats;
}
private function drawGrid (data = false): Sprite {
if (data)
this.importArray(data);
var grid = new Sprite();
var labels = new MovieClip();
if (this.intervalX<2)
this.intervalX=2;
if (this.intervalY<2)
this.intervalY=2;
var realx;
var realy;
for (var x=0;x<=this.w;x+=this.intervalX) {
realx = x;
if (!this.invertX)
realx = this.w-x;
if (realx/this.intervalX%this.highlightX==0) {
grid.graphics.lineStyle(1,this.colors['gridX']);
var num = Math.floor((this.w-x)/this.w*(this.range.maxx-this.range.minx)+this.range.minx);
var tfcontainer = new MovieClip();
var textfield = new TextField();
if (this.dateX) {
var d = new Date(num*1000);
num = Number(d.getMonth()+1)+" "+d.getFullYear();
}
if (this.textFormat) {
textfield.defaultTextFormat = this.textFormat;
textfield.embedFonts = true;
textfield.text = num;
textfield.rotation=90;
} else {
textfield.htmlText = "<font family='Helvetica, Verdana, Arial' size='7px' color='#ffffff'>"+num+"</font>";
}
//textfield.text = num;
textfield.selectable = false;
tfcontainer.addChild(textfield);
tfcontainer.y=this.h;
tfcontainer.x=realx+textfield.textHeight/2+2;
labels.addChild(tfcontainer);
} else
grid.graphics.lineStyle(1,this.colors['gridX'],0.5);
grid.graphics.moveTo(realx,0);
grid.graphics.lineTo(realx,this.h);
}
for (var y=0;y<=this.h;y+=this.intervalY) {
realy = y;
if (this.invertY)
realy = this.h-y;
if (realy/this.intervalY%this.highlightY==0) {
grid.graphics.lineStyle(1,this.colors['gridY']);
var num = Math.floor(y/this.h*(this.range.maxy-this.range.miny)+this.range.miny);
var textfield = new TextField();
if (this.dateY) {
var d = new Date(num*1000);
num = Number(d.getMonth()+1)+" "+d.getFullYear();
}
if (this.textFormat) {
textfield.defaultTextFormat = this.textFormat;
textfield.embedFonts = true;
textfield.text = num;
} else {
textfield.htmlText = "<font face='Arial' family='Helvetica, Verdana, Arial' size='7px' color='#ffffff'>"+num+"</font>";
}
textfield.selectable = false;
textfield.y=realy-textfield.textHeight/2-2;
textfield.x=this.w+2;
labels.addChild(textfield);
} else
grid.graphics.lineStyle(1,this.colors['gridY'],0.5);
grid.graphics.moveTo(0,realy);
grid.graphics.lineTo(this.w,realy);
}
grid.addChild(labels);
grid.alpha=0.5;
return grid;
}
public function draw (data = false) {
if (data)
this.importArray(data);
var mc = new MovieClip();
mc.addChild(this.drawGrid());
mc.addChild(this.drawStats());
mc.x=0;
mc.y=0;
this.addChild(mc);
}
public function importArray (data) {
this.data = data;
this.graph = new Array();
var buf;
var y; /* y-value */
var x; /* x-value */
var t; /* type */
var point:Point;
for(var t in this.data) {
if (!this.graph[t])
this.graph[t] = new Array();
var keys : Array = [];
for( var key : String in this.data[t] ) keys.push( key );
keys.sort();
for(var key in keys) {
x=keys[key];
y=this.data[t][x];
this.graph[t].push(new Point(x,y));
if (!this.range.hasOwnProperty('minx') || x<this.range['minx'])
this.range.minx=Number(x);
if (!this.range.hasOwnProperty('maxx') || x>this.range['maxx'])
this.range.maxx=Number(x);
if (!this.range.hasOwnProperty('miny') || y<this.range['miny'])
this.range.miny=Number(y);
if (!this.range.hasOwnProperty('maxy') || y>this.range['maxy'])
this.range.maxy=Number(y);
trace("statistics ("+this.graph[t].length+"): "+t+" :"+x+"/"+y);
}
}
trace(this.range.minx+" "+this.range.maxx+"/"+this.range.miny+" "+this.range.maxy);
}
public function importObjects (data) {
this.data = data;
this.graph = new Array();
var buf;
var y; /* y-value */
var x; /* x-value */
var t; /* type */
var point:Point;
for(var t in this.data) {
if (!this.graph[t])
this.graph[t] = new Array();
for(var key in this.data[t]) {
x=this.data[t][key].x;
y=this.data[t][key].y;
this.graph[t].push(new Point(x,y));
if (!this.range.hasOwnProperty('minx') || x<this.range['minx'])
this.range.minx=Number(x);
if (!this.range.hasOwnProperty('maxx') || x>this.range['maxx'])
this.range.maxx=Number(x);
if (!this.range.hasOwnProperty('miny') || y<this.range['miny'])
this.range.miny=Number(y);
if (!this.range.hasOwnProperty('maxy') || y>this.range['maxy'])
this.range.maxy=Number(y);
trace("statistics ("+this.graph[t].length+"): "+t+" :"+x+"/"+y);
}
}
trace(this.range.minx+" "+this.range.maxx+"/"+this.range.miny+" "+this.range.maxy);
}
}
}
Seit dem Jahreswechsel ist auf der non-kommerziellen Netaudioplattform Pulsar ( http://pulsar.cc ) ein selbstentwickelter (Netaudio)Mp3-Player integriert, der auf ActionScript3 basiert, und nach langer Flash-Abstinenz auch gleichzeitig meine erste Flash-Entwicklung nach fast 5 Jahren darstellt.
Since New Year´s, you can find an embedded (netaudio)-mp3-player on my netlabel Pulsar ( http://pulsar.cc ). After more than 5 years pause from developing flash-projects, this is also my first actionscript3-tool I have built.
This class is a first step to a comprehensive, and yet handy little collection of helper-functions, which can ease your way along while using php for shell-scripts.
Whereas most of you probably use php as a scripting-language for websites, it´s also a very good alternative to other shell-scripting languages like perl or python. In fact, I find it a lot more useful than regular shell-scripts.
This little class can be used both as a static collection of shell-methods, but you can also create instances of it.
So far, it automatically parses any userparams coming from the commandline, and stores them in a publicly available array named self::$arguments.
More features are to be added soon
<?
/* ----------------------------------------------------- */
/* coding: timor kodal [pulsar-network] */
/* copyright by: (c) 2010 timor kodal */
/* ----------------------------------------------------- */
/* contact: [http://pulsar.cc | timor [at] kodal.de */
/* ----------------------------------------------------- */
/* to see this and other scripts in action, please visit */
/* http://pulsar.cc */
/* ----------------------------------------------------- */
/* you are free to use my scripts */
/* according to the creative commons licence cc-nc-by */
/* ----------------------------------------------------- */
/* more information: http://creativecommons.org */
/* ----------------------------------------------------- */
class shell {
public $arguments;
public $defaults;
public $aliases;
function __construct (Array $args = NULL,Array $aliases = NULL,Array $defaults = NULL) {
$this->aliases = $aliases;
$this->defaults = $defaults;
$this->arguments = self::parseArguments($args,$aliases,$defaults);
}
public function getArgs(Array $defaults = NULL) {
$args = $this->arguments;
if ($defaults) {
foreach ($defaults as $k=>$v) {
if (!isset($args[$k]))
$args[$k]=$v;
if (!isset($args[$this->aliases[$k]]) && $this->aliases[$k])
$args[$this->aliases[$k]]=$v;
}
}
return $args;
}
public static function parseArguments (Array $args = NULL, Array $aliases = NULL,Array $defaults = NULL) {
global $argv;
if (!$aliases)
$aliases = Array ("u"=>"user");
if (!$args)
$args=$argv;
$arguments = Array();
$count = 0;
// -u=1
// -u test
// --user=1
if (is_array($defaults)) {
foreach ($defaults as $k=>$v) {
$arguments[$k]=$v;
if ($aliases[$k])
$arguments[$aliases[$k]]=$v;
}
}
foreach ($args as $k=>$v) {
$pattern = "/\-{1,2}([a-z]+)=(.*)/";
preg_match($pattern,$v,$matches);
if ($matches[0]) {
$arguments[$matches[1]]=$matches[2];
if ($aliases[$matches[1]])
$arguments[$aliases[$matches[1]]]=$matches[2];
} else
$arguments[]=$v;
}
return $arguments;
}
}
?>