Zurück   Flashforum > Flash > ActionScript > Softwarearchitektur und Entwurfsmuster

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 09-04-2003, 11:27   #1 (permalink)
◘ ◘
 
Benutzerbild von beachmeat
 
Registriert seit: Dec 2001
Ort: Amsterdam
Beiträge: 6.126
Shortcut Klasse

Aloha,

hier haben wir eine Klasse, welche Tastenshortcuts frisst, und eine angegebene Funktion aufruft bei erfülltem Shortcut, und gewünschte Parameter übergibt.
Die Anzahl an Keys des Shortcuts ist dabei beliebig.
Beim Testen in der Entwicklungsumgebung Tastenkombinationen ausschalten (Steuerung > Tastenkombinationen deaktivieren)

ActionScript:
  1. function ShortCut()
  2. {
  3. }
  4.  
  5. o = ShortCut.prototype
  6.  
  7. o.init = function()
  8. {
  9.         this.keysDown   = {}            // Hier werden die aktuell gedrückten Keys reingeschrieben
  10.        
  11.         this.keys     = arguments[0].keys.sort();      // Meine ShortcutKeys
  12.         this.func     = arguments[0].func;      // Die Funktion welche bei Shortcut aufgerufen wird.
  13.         this.scope   = arguments[0].scope;            // Wo die aufgerufen werden soll
  14.         this.passedArgs     = arguments[0].passedArgs;    // Mit welchen Argumenten
  15.        
  16.         this.listen();
  17. }
  18.  
  19. o.listen = function()
  20. {
  21.         this.kl = {}
  22.         this.kl.ref         = this
  23.         this.kl.onKeyDown   = function()
  24.         {
  25.                 this.ref.addKey(Key.getCode())
  26.         }
  27.         this.kl.onKeyUp = function()
  28.         {
  29.                 this.ref.remKey(Key.getCode())
  30.         }
  31.        
  32.         Key.addListener(this.kl)
  33. }
  34.  
  35. o.addKey = function(code)
  36. {
  37.         if (!this.keysDown[code])
  38.         {
  39.                 this.keysDown[code] = true
  40.                 this.checkKeys()
  41.         }
  42.        
  43. }
  44.  
  45. o.remKey = function(code)
  46. {
  47.         if (this.keysDown[code])
  48.         {
  49.                 delete this.keysDown[code]
  50.     this.checkKeys()
  51.         }
  52. }
  53.  
  54. o.checkKeys = function()
  55. {
  56.         var tArr = []
  57.         for(var i in this.keysDown)
  58.         {
  59.                 tArr.push(i)
  60.         }
  61.         tArr.sort()
  62.         if(tArr.toString() == this.keys.toString())
  63.         this.action()
  64. }
  65.  
  66. o.action = function()
  67. {
  68.         this.scope[this.func].apply(this.scope,this.passedArgs);
  69. }
  70. // __________________________________________________
  71.  
  72.  
  73.  
  74.  
  75. // Die Funktion die aufgerufen wird in unserem Beispiel bei Shortcut
  76. fObj = {}
  77. fObj.testemermol = function(a,b,c,d)
  78. {
  79.         trace(a + "-" + b + "-" + c + "-" + d);
  80. }
  81.  
  82. // Das Arguments Object
  83. var obj = {}
  84.  
  85. obj.keys       = [17,65//Strg + A
  86. obj.func       = "testemermol";
  87. obj.scope      = fObj;
  88. obj.passedArgs      = ["test",1,2,3];
  89.  
  90. // Shortcut
  91. sc = new ShortCut();
  92. sc.init(obj)
__________________
jeden Tag frisch

Geändert von beachmeat (09-04-2003 um 13:56 Uhr)
beachmeat ist offline   Mit Zitat antworten
Alt 09-04-2003, 11:58   #2 (permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
Sehr praktisch !

Noch praktischer wäre es vielleicht,
wenn man mehrere Shortcuts
auf einmal handeln könnte

Wer wagt sich dran ?

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 09-04-2003, 12:01   #3 (permalink)
◘ ◘
 
Benutzerbild von beachmeat
 
Registriert seit: Dec 2001
Ort: Amsterdam
Beiträge: 6.126
Hmm - man kann ja einfach mehrere Instanzen erstellen - aber ok, das liesse sich wohl problemlos machen
__________________
jeden Tag frisch
beachmeat ist offline   Mit Zitat antworten
Alt 09-04-2003, 12:06   #4 (permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
Stimmt auch wieder

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 09-04-2003, 12:25   #5 (permalink)
querdenker
 
Benutzerbild von kelor
 
Registriert seit: Jun 2001
Ort: formel1-stadt hockenheim
Beiträge: 4.731
Thumbs up



hübsch...gefällt mir...
ein weiterer beweis, dass man kreativität noch ne menge neuer sachen machen kann...

greetz

kelor
kelor ist offline   Mit Zitat antworten
Alt 09-04-2003, 13:59   #6 (permalink)
◘ ◘
 
Benutzerbild von beachmeat
 
Registriert seit: Dec 2001
Ort: Amsterdam
Beiträge: 6.126
hab oben das apply nochma geändert - muss natürlich "this.scope" anstatt "null" sein, um Methoden aufzurufen.
Auch müssen noch die Parameter bei Bedarf zur Laufzeit ausgewertet werden.

ActionScript:
  1. function ShortCut()
  2. {
  3. }
  4.  
  5. o = ShortCut.prototype
  6.  
  7. o.init = function()
  8. {
  9.     this.keysDown   = {}              // Hier werden die aktuell gedrückten Keys reingeschrieben
  10.    
  11.     this.keys   = arguments[0].keys.sort();        // Meine ShortcutKeys
  12.     this.func   = arguments[0].func;         // Die Funktion welche bei Shortcut aufgerufen wird.
  13.     this.scope  = arguments[0].scope;            // Wo die aufgerufen werden soll
  14.     this.passedArgs = arguments[0].passedArgs;      // Mit welchen Argumenten
  15.  
  16.     this.listen();
  17. }
  18.  
  19. o.listen = function()
  20. {
  21.     this.kl = {}
  22.     this.kl.ref         = this
  23.     this.kl.onKeyDown   = function()
  24.     {
  25.         trace(Key.getCode())
  26.         this.ref.addKey(Key.getCode()) 
  27.     }
  28.     this.kl.onKeyUp = function()
  29.     {
  30.         this.ref.remKey(Key.getCode()) 
  31.     }
  32.    
  33.     Key.addListener(this.kl)
  34. }
  35.  
  36. o.addKey = function(code)
  37. {
  38.     if (!this.keysDown[code])
  39.     {
  40.         this.keysDown[code] = true
  41.         this.checkKeys()
  42.     }
  43.    
  44. }
  45.  
  46. o.remKey = function(code)
  47. {
  48.     if (this.keysDown[code])
  49.     {
  50.         delete this.keysDown[code]
  51.     }
  52. }
  53.  
  54. o.checkKeys = function()
  55. {
  56.     var tArr = []
  57.     for(var i in this.keysDown)
  58.     {
  59.         tArr.push(i)
  60.     }
  61.     tArr.sort()
  62.     if(tArr.toString() == this.keys.toString())
  63.     this.action()
  64. }
  65.  
  66. o.action = function()
  67. {
  68.     argArr = [];
  69.     while(var i=0; i<this.passedArgs.length; i++)
  70.     {
  71.         argArr[i] = this.passedArgs[i].evaluate ? eval(this.passedArgs[i].arg) : this.passedArgs[i].arg
  72.     }
  73.  
  74.     this.scope[this.func].apply(this.scope,argArr);
  75. }


Der veränderte Aufruf sieht so aus:
ActionScript:
  1. // NEW NODE
  2. var obj = {}
  3.  
  4. obj.keys    = [17,78]      //Strg + N
  5. obj.func    = "newNode";
  6. obj.scope   = _global[menuName];
  7. obj.passedArgs  = [{arg:"_root.input.text", evaluate:true},{arg:"item", evaluate:false}];
  8.  
  9. // Shortcut
  10. scNewNode = new ShortCut();
  11. scNewNode.init(obj)

Wenn man einen Wert also zur Laufzeit auswerten will, als String übergeben , und evaluate = true
__________________
jeden Tag frisch

Geändert von beachmeat (09-04-2003 um 14:10 Uhr)
beachmeat ist offline   Mit Zitat antworten
Alt 10-04-2003, 00:56   #7 (permalink)
[Matthias K.] - Moderator
 
Benutzerbild von Madokan
 
Registriert seit: Jun 2001
Ort: Berlin/Germany - and the hole World !
Beiträge: 9.971
Kann mich der Meinung der Jungs nur anschliessen. Bin sicher da hast einigen eine Freude gemacht. Im Offline Bereich wäre die Klasse sicher gut zu gebrauchen, oder man kombiniert sie mit borisp XP Windows Menu Bar.

Entdecke dieMöglichkeiten (Wer hat das nochmals gesagt? )

Liebe Grüsse
Matze K.
Madokan ist offline   Mit Zitat antworten
Alt 10-04-2003, 10:27   #8 (permalink)
◘ ◘
 
Benutzerbild von beachmeat
 
Registriert seit: Dec 2001
Ort: Amsterdam
Beiträge: 6.126
Freut mich

Nur ist doch irgendwie das Problem, das das dynamische Auswerten von Argumenten problematisch bleibt.

Wenn man z.B. eine Methode eines anderen Objektes aufrufen möchte, und an diese ebenso diverse Argumente übergeben möchte - was dann?

Muss man also noch ne Klasse machen, die sowas ermöglicht
__________________
jeden Tag frisch
beachmeat ist offline   Mit Zitat antworten
Alt 10-04-2003, 10:53   #9 (permalink)
◘ ◘
 
Benutzerbild von beachmeat
 
Registriert seit: Dec 2001
Ort: Amsterdam
Beiträge: 6.126
Ahoi, na da hab ich doch was schönes gefunden:
ActionScript:
  1. _global.Command = function ()
  2. {
  3.     if (arguments[0] == undefined)
  4.     {
  5.         return;
  6.     }
  7.     var a = arguments[0];
  8.     if (arguments.length > 1)
  9.     {
  10.         this.obj = a;
  11.         this.method = a[arguments[1]];
  12.         this.args = arguments.slice (2);
  13.     }
  14.     else if (a instanceof Function)
  15.     {
  16.         this.method = a;
  17.     }
  18.     else if (typeof a == "string")
  19.     {
  20.         var idxOfParensL = a.indexOf ("(");
  21.         var pathToMethod = a.slice (0, idxOfParensL);
  22.         this.obj = eval (pathToMethod.slice (0, pathToMethod.lastIndexOf (".")));
  23.         this.method = eval (pathToMethod);
  24.         this.args = a.slice (idxOfParensL + 1, a.lastIndexOf (")")).split (",");
  25.     }
  26. };
  27. Command.prototype.execute = function ()
  28. {
  29.     var cmd = this;
  30.     Command.callback = function (params)
  31.     {
  32.         Command.data = arguments;
  33.         cmd.callbackCommand.execute ();
  34.         cmd.onComplete ();
  35.     };
  36.     return this.method.apply (this.obj, this.args);
  37. };

Dies stammt von http://flashAPI.yestoall.com und bietet die gewünschte Funktionalität. Saugt euch am besten die API und schaut euch Command an um den zu verstehen

Was sich nun am Code der Klasse verändert, ist die Methode "action":

ActionScript:
  1. o.action = function()
  2. {
  3.     argArr = [];
  4.     for(var i=0; i<this.passedArgs.length; i++)
  5.     {
  6.         if(this.passedArgs[i].evaluate != null)
  7.         {
  8.             if(this.passedArgs[i].evaluate == "static")
  9.                 argArr[i] = eval(this.passedArgs[i].arg)
  10.             else
  11.                 argArr[i] = this.passedArgs[i].arg.execute()
  12.         }
  13.         else argArr[i] = this.passedArgs[i].arg
  14.     }
  15.     this.scope[this.func].apply(this.scope,argArr);
  16. }


und der Aufruf des Shortcuts, das Argument "passedArgs":
ActionScript:
  1. obj.passedArgs  = [{arg:new Command(myObject.sub, "evaluateFunc", 10,7),evaluate:"command"},{arg:"hallo", evaluate:null},{arg:"mc._x", evaluate:"static"}]

evaluate "command" bedeutet also, das der Command ausgeführt wird
evaluate "static" wertet nur eine Eigenschaft aus
null ist n konstanter Wert
__________________
jeden Tag frisch

Geändert von beachmeat (10-04-2003 um 10:56 Uhr)
beachmeat ist offline   Mit Zitat antworten
Alt 10-04-2003, 11:03   #10 (permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
Eigentlich führt das ein bißchen zuweit, oder ?
Die Verantwortung des ShortCut-Objekts sollte
dann enden, wenn es das Ereignis gemeldet hat.
Sonst landest du in letzter Konsequenz da, dass alle
Programmlogik vom ShortCut-Objekt realisiert wird

Hier ist mal eine Version, die das Key-Objekt so erweitert,
dass sich Listener für die Shortcuts eintragen können.
Der Name der aufgerufenenen Methode setzt sich dabei
aus den KeyCodes der Tastenkombination zusammen:

ActionScript:
  1. function KeyShortCutsExtensionClass() {
  2.     //trace("KeyShortCutsExtensionClass");
  3.     this.keysDown = {};
  4.     this.combis = {};
  5.     Key.addListener(this);
  6. }
  7. //
  8. o = KeyShortCutsExtensionClass.prototype;
  9. //
  10. o.addCombi = function() {
  11.     //trace("KeyShortCutsExtensionClass.addCombi " + arguments);
  12.     //wie merken uns die akt. Kombination
  13.     this.combis[arguments.toString()] = 1;
  14. };
  15. //
  16. o.removeCombi = function(arguments) {
  17.     //trace("KeyShortCutsExtensionClass.removeCombi " + arguments);
  18.     delete this.combis[arguments.toString()];
  19. };
  20. //
  21. o.checkKeys = function() {
  22.     //trace("KeyShortCutsExtensionClass.checkKeys");
  23.     var result = [];
  24.     for (var i = 0; i < 256; i++) {
  25.         if (Key.isDown(i)) {
  26.             result.push(i);
  27.         }
  28.     }
  29.     //trace("KeyShortCutsExtensionClass.checkKeys " + result);
  30.     if (this.combis[result.toString()]) {
  31.         Key.broadcastMessage("onKeyCombi_" + result.join("_"));
  32.     }
  33. };
  34. //
  35. o.onKeyDown = o.checkKeys;
  36. //
  37. // Statische Methode um das Key-Objekt zu initialisieren
  38. KeyShortCutsExtensionClass.initialize = function(){
  39.     //trace("KeyShortCutsExtensionClass.initialize");
  40.     Key.shortCuts = new this();
  41.     Key.addCombi = function(){
  42.         this.shortCuts.addCombi.apply(this.shortCuts, arguments);
  43.     }
  44.     Key.removeCombi = function(){
  45.         this.shortCuts.removeCombi.apply(this.shortCuts, arguments);
  46.     }
  47. }
  48. //
  49. //-----------------------------------------------
  50. // Test
  51. //-----------------------------------------------
  52. //Keyobjekt erweitern
  53. KeyShortCutsExtensionClass.initialize();
  54. // Shortcut hinzufügen Strg-A
  55. Key.addCombi(17, 65);
  56. // Shortcut hinzufügen Strg-B
  57. Key.addCombi(17, 66);
  58. //
  59. //
  60. // Die Handler, die bei ShortCut aufgerufen werden
  61. fObj = {};
  62. fObj.onKeyCombi_17_65 = function() {
  63.     trace("fObj.onKeyCombi_17_65");
  64. };
  65. Key.addListener(fObj);
  66. //
  67. //Ein Handler kann auch auf mehrere Ereignisse
  68. //reagieren
  69. fObj2 = {};
  70. fObj2.onKeyCombi_17_65 = function() {
  71.     trace("fObj2.onKeyCombi_17_65");
  72. };
  73. fObj2.onKeyCombi_17_66 = function() {
  74.     trace("fObj2.onKeyCombi_17_66");
  75. };
  76.  
  77. Key.addListener(fObj2);
  78. //
  79.  

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 10-04-2003, 11:42   #11 (permalink)
◘ ◘
 
Benutzerbild von beachmeat
 
Registriert seit: Dec 2001
Ort: Amsterdam
Beiträge: 6.126
Jajaja da hasde wohl recht, wieder zuviel in ein
Modul gequetscht.

Die Broadcasterlösung gefällt mir gut, außer der 0-256 Schleife [aber interessante Lösung], zumal die bei mir mit "strg" nen Fehler produziert (STRG ergibt 17 UND 162)

Is wohl richtig, das ne eigene Funktion für jede TastenKombination die kompaktere Lösung ist, zumal die Logik des auswertens da wirklich nix zu suchen hat.
__________________
jeden Tag frisch

Geändert von beachmeat (10-04-2003 um 11:48 Uhr)
beachmeat ist offline   Mit Zitat antworten
Alt 10-04-2003, 11:55   #12 (permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
Dann ist doch bestimmt deine Tastatur kaputt

Eine Kombination deiner Tastenerkennung mit der
Liste der Tasten hier hinein wäre dann wohl ganz
gut.

Dann werden auch nur die Tasten abgefraggt ,
die wirklich erwartet werden und nicht noch hunderte
andere.

Machst du fertig ?

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 10-04-2003, 12:29   #13 (permalink)
◘ ◘
 
Benutzerbild von beachmeat
 
Registriert seit: Dec 2001
Ort: Amsterdam
Beiträge: 6.126
Mit meiner Tastatur is alles in Ordnung - frag mich auch was das soll - laut charCode is das diese Zeichen: ¢ -komisch- is auch nich die einzige Taste, Shift auch noch z.B
ActionScript:
  1. _root.onEnterFrame = function ()
  2. {
  3.     for (var i = 0; i < 256; i++)
  4.     {
  5.         if (Key.isDown (i))
  6.             trace (i);
  7.     }
  8. };


HHowever, here we go:

ActionScript:
  1. function KeyShortCutsExtensionClass() {
  2.         this.keysDown = {};
  3.         this.combis = {};
  4.         Key.addListener(this);
  5. }
  6. //
  7. o = KeyShortCutsExtensionClass.prototype;
  8. //
  9. o.addCombi = function() {
  10.         this.combis[arguments.sort().toString()] = 1;
  11. };
  12. //
  13. o.removeCombi = function() {
  14.         delete this.combis[arguments.sort().toString()];
  15. };
  16.  
  17.  
  18. o.onKeyDown = function(code)
  19. {
  20.     var k = Key.getCode()
  21.     if (!this.keysDown[k])
  22.     {
  23.         this.keysDown[k] = true
  24.         this.checkKeys()
  25.     }
  26. }
  27.  
  28. o.onKeyUp = function(code)
  29. {
  30.     var k = Key.getCode()
  31.     if (this.keysDown[k])
  32.     {
  33.         delete this.keysDown[k]
  34.         this.checkKeys()
  35.     }
  36. }
  37.  
  38. o.checkKeys = function()
  39. {
  40.     var tArr = []
  41.     for(var i in this.keysDown)
  42.     {
  43.         tArr.push(i)
  44.     }
  45.     tArr.sort()
  46.             if (this.combis[tArr.toString()])
  47.             {
  48.                 Key.broadcastMessage("onKeyCombi_" + tArr.join("_"));
  49.  
  50.     }
  51. }
  52.  
  53.  
  54.  
  55.  
  56.  
  57. //
  58. // Statische Methode um das Key-Objekt zu initialisieren
  59. KeyShortCutsExtensionClass.initialize = function(){
  60.         //trace("KeyShortCutsExtensionClass.initialize");
  61.         Key.shortCuts = new this();
  62.         Key.addCombi = function(){
  63.                 this.shortCuts.addCombi.apply(this.shortCuts, arguments);
  64.         }
  65.         Key.removeCombi = function(){
  66.                 this.shortCuts.removeCombi.apply(this.shortCuts, arguments);
  67.         }
  68. }
  69. //
  70. //-----------------------------------------------
  71. // Test
  72. //-----------------------------------------------
  73. //Keyobjekt erweitern
  74. KeyShortCutsExtensionClass.initialize();
  75.  
  76.  
  77. // Shortcut hinzufügen Strg-A
  78. Key.addCombi(17, 65);
  79. Key.addCombi(17, 83);
  80.  
  81. //
  82. // Die Handler, die bei ShortCut aufgerufen werden
  83. fObj = {};
  84. fObj.onKeyCombi_17_65 = function() {
  85.         trace("fObj.onKeyCombi_17_65");
  86. };
  87. fObj.onKeyCombi_17_83 = function() {
  88.         trace("fObj.onKeyCombi_17_83");
  89. };
  90.  
  91.  
  92. Key.addListener(fObj);


Strenggenommen ist das garnich ECMA konform, weil wir Objekt Props numerisch beginnen - woscht
__________________
jeden Tag frisch

Geändert von beachmeat (10-04-2003 um 13:02 Uhr)
beachmeat ist offline   Mit Zitat antworten
Alt 10-04-2003, 13:19   #14 (permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
Genau,
in diesem Fall, wo wir die Liste als
Dictionary benutzen, ist das m. E.
erlaubt.

Sieht gut aus, Daumen hoch.

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 10-04-2003, 14:01   #15 (permalink)
◘ ◘
 
Benutzerbild von beachmeat
 
Registriert seit: Dec 2001
Ort: Amsterdam
Beiträge: 6.126
na DEN Daumen muss ich zurückgeben

wie waäre es den, wenn man add keyCombi entfernen würde, und IMMER broadcastet welche keys grade gedrückt sind, dann würde man sich das sparen, und die Implementation würde sich auf die onKeyKombi reduzieren - der Broadcaster würde also blind broadcasten (was er ja eh tut) und nur die entsprechenden Listener würde ihre Kombis auffangen - der rest schiesst ins Nirvana - Performance dürfte das ja nix antun...

mach das mal grad...
__________________
jeden Tag frisch

Geändert von beachmeat (10-04-2003 um 14:04 Uhr)
beachmeat ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an



Alle Zeitangaben in WEZ +1. Es ist jetzt 15:44 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele