Results 1 to 7 of 7

Thread: Toolbar with multiple changing cursors.

  1. #1
    Join Date
    Jan 2008
    Location
    Near Chicago
    Posts
    247
    Thanks
    105
    Thanked 2 Times in 2 Posts

    Default Toolbar with multiple changing cursors.

    This is an easy way to get cursors to change with buttons with this code:
    Here is the url to look at it: http://www.asmakta.com/eraseme_test/test.html

    This is my first try to set up a toolbox with changing cursors. As you can see, the cursors jump, which is because I used "alpha" to hide the cursors not being used without actually getting rid of them -so they stay where they were dropped.

    //hide standard cursor
    Mouse.hide();

    //activate main cursor

    yellow.startDrag("true");
    black._alpha=0;
    blue._alpha=0;
    //swap cursors -still working on getting old cursor to go away

    red1_btn.onRelease = function(){
    blue.startDrag("true");
    /*does not work black.stopDrag(); */
    // this hides the other icons but does not make them go away
    black._alpha=0;
    blue._alpha=100;
    yellow._alpha=0;}
    red2_btn.onRelease=function(){
    black.startDrag("true");
    /*does not work blue.stopDrag();*/
    blue._alpha=0;
    black._alpha=100;
    yellow._alpha=0;
    }
    Any suggestions or places to get more info greatly appreciated.

  2. #2
    Join Date
    Mar 2007
    Location
    Currently: New York/Philadelphia
    Posts
    2,735
    Thanks
    3
    Thanked 519 Times in 507 Posts

    Default

    Do you need the cursors to stay where they are dropped? I'm assuming not and you're just not aware of how to move them. In which case, I'll suggest the following:

    You can move the "cursor" to where the mouse is as soon as you click (or release in this instance). For example:

    Code:
    red2_btn.onRelease = function() {
       black._x = _xmouse;
       black._y = _ymouse;
       // your alpha code
    }
    This makes it so that it doesn't matter where you've "dropped off" the old cursor. It picks up right where your mouse is.

    Is that what you're looking for?

    How many "tools" do you plan to have in your toolbar, by the way? If it's just those two than your code should work fine. Well, even if you have 100 your code will work fine. The code will become incredibly hard to manage though. If you're going to have a few more "tools" that change cursors, may I suggest this approach:

    1) Set up only one movieclip with a different cursor per frame. When you're changing cursors, you can just use a gotoAndStop() method to change them. It cuts down the number of movieclips you'll need in your library and cuts down all the different cursors that you'll need to manage (what's on the stage, what's not and all the alpha changes).

    2) Store the button movieclips and their associated cursors in an array. Then, loop through the array to assign the onRelease or other mouse events. Again, if you have many buttons, typing the same function over and over again is a waste of resources and your time.

    Here is a visual example of what I mean. It's a replica (kind of) of the Flash CS3 toolbar. If you notice in Flash, when you click on a tool to select it, it doesn't actually change the cursor until you are on the stage. I've done something similar here. I think it provides a bit of a transition between the changes. Otherwise it was looking too abrupt. All of the tools from the zoom tool up "work". The things that I would add to this before launching on a public site would be some onRollOver and "selected" stages to the buttons and get rid of the hand cursor. But since I didn't have an onRollOver, I kept the hand cursor so you can see where the buttons are.

    The source, as always, is included (Flash 8 and CS3) on the page and released under Creative Commons Noncommercial. Be mindful that the cursors and menu are property of their respective copyright owners (Adobe, presumably). I was feeling a little lazy so I didn't do a very good job commenting out the source. If you have any questions about the technique I used, feel free to ask here.

    HTH
    Last edited by Medyman; 05-10-2008 at 09:09 PM.

  3. The Following 2 Users Say Thank You to Medyman For This Useful Post:

    evan (05-12-2008),ReadyToLearn (05-16-2008)

  4. #3
    Join Date
    Jan 2008
    Location
    Near Chicago
    Posts
    247
    Thanks
    105
    Thanked 2 Times in 2 Posts

    Default nuts and bolts

    That's good stuff!

    Let me see if I got this right:
    (I want to learn as much as I can here)
    menubar-->--tools-->selection

    You use an instance of the movie clip "menu" -and name it "back" -which is on the stage.
    You use an instances of "tools" within the main "menu" movieclip and name them "selection","subselection" -etc. for all the tools in the array ie.
    [tools.selection, "selection"]
    in the array.

    I assume they are not calling the symbols from the library -for example as with "ink-bottle" -in the code it's "inkbottle" otherwise I would get an error.

    in the function to change cursors I see
    function changeCursor(label)
    -wat does "label"reffer to?

    in the remove cursor function I see:
    // Remove the cursor when choosing new tools
    tools.back.onRollOver = function() {
    this.useHandCursor = false;
    cursor.gotoAndStop(1)
    -the tools.back rollover makes sense.

    it's this part:
    this.useHandCursor = false;
    I understnad what it's doing I don't know how it works.
    It turn off the hand cursor.
    Is it reffering to "hand" in the "Cursors" folder in the library?


    This code is great because intstead of using separate functions for separate buttons, There is an array to do all that. I see how you did it but to do something like this from scratch are there some general rules for using arrays, functions, with library items and nested symbols within them?


    last question:

    going back to my code where I have functions for each button and cursor swap. which is good for a newbee (except when You need a dozen icons as you demonstrate so well.)

    red2_btn.onRelease=function(){
    //drag new cursor
    black.startDrag("true");
    //this places the new starting cursor where the mouse is
    black._x = _xmouse;
    black._y = _ymouse;
    //show and hide cursor
    blue._alpha=0;
    black._alpha=100;
    yellow._alpha=0;
    }
    instead of the _alpha properties could I substitute something related to:
    this.useHandCursor = false;
    in some way to simply swap out library items?

    Thank again!

  5. #4
    Join Date
    Mar 2007
    Location
    Currently: New York/Philadelphia
    Posts
    2,735
    Thanks
    3
    Thanked 519 Times in 507 Posts

    Default

    You use an instance of the movie clip "menu" -and name it "back" -which is on the stage.
    Right. "back" is only the image of the menu. It does serve a functional purpose, though.

    I assume they are not calling the symbols from the library -for example as with "ink-bottle" -in the code it's "inkbottle" otherwise I would get an error.
    Right. The symbols in the library are the images for the cursors. They're assets to the Cursor movieclip.

    what does "label"refer to?
    label is an arbitrary parameter that I pass to the changeCursor() function. You could write a unique function to call each cursor, or do it this way. In this function, I'm using label to signify the frame label within the Cursor movieclip. If you open up the Cursor movieclip, you'll notice that each of the different cursors on are on one frame each with a frame label to specify which cursor it is.

    The label parameter then is used in a basic gotoAndStop():

    Code:
    function changeCursor(label) {
    	cursor._x = _xmouse; 
    	cursor._y = _ymouse;
    	cursor.startDrag();
    	
    	cursor.gotoAndStop(label); 
    }
    it's this part:
    Code:
    Quote:this.useHandCursor = false;
    I understand what it's doing I don't know how it works.
    It turn off the hand cursor.
    Is it referring to "hand" in the "Cursors" folder in the library?
    I can see why that would be confusing. movieclip.useHandCursor is a property of the movieclip object. It's Actionscript syntax -- not something I wrote for this application. What it does is remove the default "hand" or "pointer" cursor when you mouse over anything with mouse actions attached.

    For example, when you mouse over this link, you'll cursor will turn into a hand. It's this behavior that I'm deactivating. It would be similar to specifying a cursor:default; property on an anchor element with CSS.

    My main concern here was that the individual buttons to change cursors (the "tools") should be discernible from the rest of the menu. If I hadn't turned the handCursor off, you would have seen the hand cursor over the entire menu and not have been able to tell where one button began and ended. Currently, if you mouse over each individual "tool" in the menu, you'll see the hand cursor that this property controls. The hand cursor is only turned off for the "back" movieclip.

    This code is great because instead of using separate functions for separate buttons, There is an array to do all that. I see how you did it but to do something like this from scratch are there some general rules for using arrays, functions, with library items and nested symbols within them?
    Arrays in Actionscript are the same as you might find them in PHP or JavaScript. There really isn't any magic or special steps to using these in AS. The general rule of thumb is that if you find yourself repeating code, it's probably more efficient to use arrays and for or for...in loops.

    The thing to be careful of is what kind of data type that you're adding to the array. Arrays can take any data type: movieclips, strings, numbers etc... You want to make sure that it's consistent and that you're relating to it in the same behavior as you would a single instance of that data type.

    Also, arrays begin at index 0. I can't tell you how many times I've seen people loop through an array and wonder why the first item isn't showing up. It's because they began their loop at 1 and arrays begin at 0.


    going back to my code where I have functions for each button and cursor swap. which is good for a newbee (except when You need a dozen icons as you demonstrate so well.)
    It certainly is, but like you realize, inefficient for multiple instances. But I know that the explicit calling of the alpha property can be comforting to use as you know exactly what's happen every step of the way. With arrays and loops, you're just writing a plan and letting the little AS elves run their magic.

    instead of the _alpha properties could I substitute something related to:
    Code:
    Quote:this.useHandCursor = false;
    in some way to simply swap out library items?
    Not exactly. After my explanation of the useHandCuror property, that's probably clear. Instead of the _alpha property, you can use the _visible property. It essentially will do the same thing though.

    If you want to swap items from the library, you'll have to use the attachMovie and removeMovieClip methods. If you're going to do this make sure that you've assigned an identifier (not the same as an instance name) and are exporting that clip for Actionscript. Both of these things are set in the properties of the movieclip via the library (right click -> properties).

    With this method you would be adding and removing movieclips from the stage. In general, it's good practice to remove movieclips that you're not using from the stage to free up system resources. But, for clips as small as I've used for the cursors, the effect is non-consequential. That is why I used the one movieclip, several frames technique. It's less (and simpler) code and the result is essentially the same.

  6. The Following 2 Users Say Thank You to Medyman For This Useful Post:

    evan (05-12-2008),ReadyToLearn (05-16-2008)

  7. #5
    Join Date
    Jan 2008
    Location
    Near Chicago
    Posts
    247
    Thanks
    105
    Thanked 2 Times in 2 Posts

    Default

    // Assign onRelease Events
    for(i=0; i<cursors.length; i++) {
    cursors[i][0].id = i;
    cursors[i][0].onRelease = function() {
    currentCursor = cursors[this.id][1];
    I understand this.id corresponds with the strings in the array right?
    what does cursors.length represent?

    tools.back.onRollOver
    to get the hang of the syntax ---This is essential,
    In that "tools" is a movieclip in the libray -yet instances of it appear are nested in "back" -an instance of menu. Does this also have connection to the syntax in the array -with also says
    [tools.line, "crosshair"]
    ?

    Is there a similarity with calling up classes? In this case it's a little confusing to see which instance is higher up in the hearchy.

    Anyways, I am getting alot out of this. Thanks much

  8. #6
    Join Date
    Mar 2007
    Location
    Currently: New York/Philadelphia
    Posts
    2,735
    Thanks
    3
    Thanked 519 Times in 507 Posts

    Default

    Code:
    // Assign onRelease Events
    for(i=0; i<cursors.length; i++) {
    cursors[i][0].id = i;
    cursors[i][0].onRelease = function() {
    currentCursor = cursors[this.id][1];
    I understand this.id corresponds with the strings in the array right?
    what does cursors.length represent?
    I have a (bad?) habit of using this naming convention. To me, it makes sense but it trips some people up who are trying to learn from my code. I should probably learn a better convention.

    Anyway, there is a movieclip with an instance name of cursor (singular) on the stage. This contains the various cursors that will change when you click on it's cooresponding buttom.

    In the Actionscript, there is also the cursors (plural) array. "length" is a property of the Array object. It tell us how many items are in the array. You could count how many items are in the array and hard code that value, but if you ever need to update it...it's more things to keep track of.

    So, using cursors.length as the upper limit to the loop means that it will loop just enough times to assign the actions within the loop to the movieclips in the array. That way, you're not wasting any unnecessary resources.

    In my example, cursors.length would equal 16. You can read more about the array.length property here.

    Code:
    cursors[i][0].id = i;
    Yes, the above code assigns an arbitrary "id" property to each button in the menu. With ActionScript, you can add whatever made-up property you want -- cursors.favoriteColor = red, for example. What this does, is assigns the property to the movieclip object, and therefore making it available globally. Within a for loop, we have access to i, the variable. This also serves as an index to the array. For example, in the first loop, the function does this (subtituting i for 0...the first value within the loop):

    Code:
    cursors[0][0].id = 0;
    Remember, arrays begin counting at 0. Also , remember we're using a associative array (i.e. an array within an array).

    cursors[0] says...give me the first element within the cursor's array. The result is [tools.selection, "selection"].
    cursors[0][0] says give me the first element with the first element of the cursors erray. In other words, the first element of [tools.selection, "selection"]; which is tools.selection.

    Moving on, we're assigning an id property. So, we're setting the id property of the tools.selection movieclip to 0.

    What's the point? Well, like I said, assigning a property makes that value global. The i within that loop is only available with in the loop. It is not available within that onRelease function. We need the index within the on release function to know which cursor to display after you click the button. So instead of using the i, we use the movieclip's id property which equals the same thing. Again, for illustration, purposes: the code broken down for the first loop

    Code:
    for(i=0; i<cursors.length; i++) {
    	cursors[i][0].id = i;
    	cursors[i][0].onRelease = function() {
    		currentCursor = cursors[this.id][1];
    	}
    }
    We've already figured out that the cursors[i][0].id = i line equals out to tools.selection.id = 0. Next, we're taking that same movieclip (tools.selection or cursors[i][0]) and assignin an onRelease event to it. That part should be familiar to you. Now, within the onRelease, we're setting a variable called currentCursor. We're setting currentCursor eq1al to cursors[this.id][1] -- or cursors[0][1] after the 1st loop. We also know that cursors[0] is equal to [tools.selection, "selection"]. cursors[0][1], then, refers to the second value in the array -- "selection". So, after you click on the button, the currentCursor variable is set equal to selection. The currentCursor variable then is used to set the label paramter of the changeCursor function.

    Code:
    tools.back.onRollOver
    Actually, again there are multiple usages of the terms. I should have paid closer attention to what I was naming things. There is a bit of a disconnect between what things are called in the library and their instance names.

    Menu in the library has an instance name of "tools"
    Tools in the library has various instance names (selection, subselection, lasso, etc...)

    If you open up the Menu (library name) movieclip, you should see a bunch of rectangles around each of the buttons. Each of those rectangles is actually an instance of the Tools(library name) movieclip. The Tools(library name) movieclip is just a rectangle with 0% transparency. It just serves as a hit state...there are no visuals in it.

    So to go over it again (with instance names).

    tools (contains everything) -> back (the image of the buttons)
    tools -> selection (instance of the "tools" movieclip from the library)
    tools -> subselect (another instance)
    etc...

    Hope that makes sense. Please let me know if it doesn't. Sorry for the confusing naming.


    Code:
    [tools.line, "crosshair"]
    The array is set up in an associated array with the following syntax.

    Code:
    var cursors = [
    	[movieclip, "label"]
    ];
    movieclip refers to the actual button. this is located within the tools (instance name) movieclip, hence the tools.xxx. label, as before, refers to the frame label within the cursor (singluar) movieclip that is associated with that button.

    Is there a similarity with calling up classes?
    I'm not sure I know what you mean here.
    Last edited by Medyman; 05-12-2008 at 11:02 PM.

  9. The Following 2 Users Say Thank You to Medyman For This Useful Post:

    evan (05-13-2008),ReadyToLearn (05-16-2008)

  10. #7
    Join Date
    Jan 2008
    Location
    Near Chicago
    Posts
    247
    Thanks
    105
    Thanked 2 Times in 2 Posts

    Default

    I'm pretty good to go, the last part was just the oder of calling things up ie:
    Highest.High.Lower or array.instance. or array.libraryitem.instance -if that makes sense.

    I will haver to mess around with the code, use it get some errors when I rename things and it will be intuitive -I realize it's hard to explain sometimes.

    Thanks again -this is better than alot of tutorials I have used.

    I am a baby coder, but I have my chops when it comes to art and graphics. message me sometime if I can be of any help.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •