Lets say that I have 2 frames:
Frame 1 with mc01 in it (Instance name: f1)
Frame 2 with mc02 in it (Instance name: f2)
At a certain point, in mc02 (inside Frame 2), I want to jump to let's say Frame 50 of mc01, that is contained in Frame 1. How?
My code atm (that produces 0 results):
_root.f1.mc01.gotoAndPlay(50);
Remember this is an Actionscript 2 question. Any help would be appreciated.
Thanks!
You just need to specify the instance name, like this:
_root.f1.gotoAndPlay(50);
Also, you can just use _parent, if both are siblings:
_parent.f1.gotoAndPlay(50);
Please note that the mc01 (named f1) must exist on frame 2 for this to work.
Update:
Your problem is that, when you need to change the frame of mc01, it doesn't exist. So you need to store a configuration for it to access on it's initialization. For example:
_root frame 1:
// if config isn't set yet, let's define it.
var config;
if (!config) {
config = {f1: {startFrame: 1}};
}
mc01 frame 1:
// go to config.f1.startFrame. If no config is set, go to 1.
gotoAndPlay(_parent.config.f1.startFrame || 1);
mc02 anywhere:
// change the config of mc01. Now, when it's created again
// it'll read the new value and jump straight to it.
_parent.config.f1.startFrame = 50;
Related
Right now I'm using wxWidgets msw 3.0.5 on Windows 7 and the xrc file was created with wxFormBuilder 3.10.1
Normally I use something like this to avoid my wxframe be resized smaller than my child controls:
MyFrame::MyFrame() : wxFrame( NULL, wxID_ANY, wxT("Sometitle") )
{
wxBoxSizer* frameSizer = new wxBoxSizer( wxVERTICAL );
wxPanel* panel = new wxPanel( this, wxID_ANY );
// ..
frameSizer->Add( panel, 1, wxEXPAND | wxALL, 0 );
SetSizerAndFit( frameSizer );
Centre();
}
But, when I'm use xrc file to load my frame I using like this:
MyFrame::MyFrame()
{
// used in App::OnInit()
// wxXmlResource::Get()->InitAllHandlers();
// wxXmlResource::Get()->Load( wxT("some.xrc" ) );
wxXmlResource::Get()->LoadFrame( this, NULL, wxT("MyFrame") );
// ...
Fit(); // this resize my frame to show my child controls as expected (like SetSizerAndFit does )
SetMinClientSize(GetSize()); // is this the right way?
Centre();
}
Fit() resize my frame same as SetSizerAndFit, but if don't use SetMinClientSize my frame can be horrible resize shriking and hiden my controls. So my questions are:
Is there a feature that I'm missing in wxFormBuilder to avoid resize less the frame child controls?
Using SetMinClientSize is the right way?
Is there are any other ways in xrc file to have the same effect like SetSizerAndFit?
Thanks.
Note: this happens also in my linux wxwidgets library
The names are unfortunately confusing, but SetSizerAndFit() calls SetSizer() and wxSizer::SetSizeHints(), and not wxWindow::Fit() as might be expected. So to have exactly the same behaviour as in the first case you need to call GetSizer()->SetSizeHints(this) in your frame code.
And, FWIW, wxSizer::SetSizeHints() does something sensibly equivalent to
wxSize size = GetBestClientSize();
SetMinClientSize(size);
SetClientSize(size);
i.e. it sets both the current and min sizes, which is what you presumably want.
hoping someone can help. I am creating an app whereby the user will touch a series of images to rotate them. What I am trying to do. Is highlight the image once the user has rotated to a particular position.
Is this possible? If, so any tips greatly appreciated.
edit - ok here's an example instead!
First, the simplest way, based off the code example you just posted:
r1c1.setOnClickListener {
r1c1.animate().apply{ duration = 100 rotationBy(270f) }.start()
}
So the issue here is that you want to highlight the view when it's rotated to, say 90 degrees, right? But it has an animation to complete first. You have three options really
do something like if (r1c1.rotation + 270f == 90) and highlight now, as the animation starts, which might look weird
do that check now, but use withEndAction to run the highlighting code if necessary
use withEndAction to do the checking and highlighting, after the anim has finished
the latter probably makes the most sense - after the animation finishes, check if its display state needs to change. That would be something like this:
r1c1.animate().setDuration(100).rotationBy(270f).withEndAction {
// need to do modulo so 720 == 360 == 0 etc
if (r1c1.rotation % 360 == TARGET_ROTATION) highlight(r1c1)
}.start()
I'm assuming you have some way of highlighting the ImageViews and you weren't asking for ways to do that!
Unfortunately, the problem here is that if the user taps the view in the middle of animating, it will cancel that animation and start a new one, including the rotationBy(270) from whatever rotation the view currently happens to be at. Double tap and you'll end up with a view at an angle, and it will almost never match a 90-degree value now! That's why it's easier to just hold the state, change it by fixed, valid amounts, and just tell the view what it should look like.
So instead, you'd have a value for the current rotation, update that, and use that for your highlighting checks:
# var stored outside the click listener - this is your source of truth
viewRotation += 270f
# using rotation instead of rotationBy - we're setting a specific value, not an offset
r1c1.animate().setDuration(100).rotation(viewRotation).withEndAction {
// checking our internal rotation state, not the view!
if (viewRotation % 360 == TARGET_ROTATION) highlight(r1c1)
}.start()
I'm not saying have a single rotation var hanging around like that - you could, but see the next bit - it's gonna get messy real quick if you have a lot of ImageViews to wrangle. But this is just to demonstrate the basic idea - you hold your own state value, you're in control of what it can be set to, and the View just reflects that state, not the other way around.
Ok, so organisation - I'm guessing from r1c1 that you have a grid of cells, all with the same general behaviour. That means a lot of repeat code, unless you try and generalise it and stick it in one place - like one click listener, that does the same thing, just on whichever view it was clicked on
(I know you said youre a beginner, and I don't like loading too many concepts on someone at once, but from what it sounds like you're doing this could get incredibly bloated and hard to work with real fast, so this is important!)
Basically, View.onClickListener's onClick function passes in the view that was clicked, as a parameter - basically so you can do what I've been saying, reuse the same click listener and just do different things depending on what was passed in. Instead of a lambda (the code in { }, basically a quick and dirty function you're using in one place) you could make a general click listener function that you set on all your ImageViews
fun spin(view: View) {
// we need to store and look up a rotation for each view, like in a Map
rotations[view] = rotations[view] + 270f
// no explicit references like r1c1 now, it's "whatever view was passed in"
view.animate().setDuration(100).rotation(rotations[view]).withEndAction {
// Probably need a different target rotation for each view too?
if (rotations[view] % 360 == targetRotations[view]) highlight(view)
}.start()
}
then your click listener setup would be like
r1c1.setOnClickListener { spin(it) }
or you can pass it as a function reference (this is already too long to explain, but this works in this situation, so you can use it if you want)
r1c1.setOnClickListener(::spin)
I'd recommend generating a list of all your ImageView cells when you look them up (there are a few ways to handle this kind of thing) but having a collection lets you do things like
allCells.forEach { it.setOnClickListener(::spin) }
and now that's all your click listeners set to the same function, and that function will handle whichever view was clicked and the state associated with it. Get the idea?
So your basic structure is something like
// maybe not vals depending on how you initialise things!
val rotations: MutableMap<View, Float>
val targetRotations: Map<View, Float>
val allCells: List<ImageView>
// or onCreateView or whatever
fun onCreate() {
...
allCells.forEach { it.setOnClickListener(::spin) }
}
fun spin(view: View) {
rotations[view] = rotations[view] + 270f
view.animate().setDuration(100).rotation(rotations[view]).withEndAction {
val highlightActive = rotations[view] % 360 == targetRotations[view]
highlight(view, highlightActive)
}.start()
}
fun highlight(view: View, enable: Boolean) {
// do highlighting on view if enable is true, otherwise turn it off
}
I didn't get into the whole "wrapper class for an ImageView holding all its state" thing, which would probably be a better way to go, but I didn't want to go too far and complicate things. This is already a silly length. I might do a quick answer on it just as a demonstration or whatever
The other answer is long enough as it is, but here's what I meant about encapsulating things
class RotatableImageView(val view: ImageView, startRotation: Rotation, val targetRotation: Rotation) {
private var rotation = startRotation.degrees
init {
view.rotation = rotation
view.setOnClickListener { spin() }
updateHighlight()
}
private fun spin() {
rotation += ROTATION_AMOUNT
view.animate().setDuration(100).rotation(rotation)
.withEndAction(::updateHighlight).start()
}
private fun updateHighlight() {
val highlightEnabled = (rotation % 360f) == targetRotation.degrees
// TODO: highlighting!
}
companion object {
const val ROTATION_AMOUNT = 90f
}
}
enum class Rotation(var degrees: Float) {
ROT_0(0f), ROT_90(90f), ROT_180(180f), ROT_270(270f);
companion object {
// just avoids creating a new array each time we call random()
private val rotations = values()
fun random() = rotations.random()
}
}
Basically instead of having a map of Views to current rotation values, a map of Views to target values etc, all that state for each View is just bundled up into an object instead. Everything's handled internally, all you need to do from the outside is find your ImageViews in the layout, and pass them into the RotatableImageView constructor. That sets up a click listener and handles highlighting its ImageView if necessary, you don't need to do anything else!
The enum is just an example of creating a type to represent valid values - when you create a RotatableImageView, you have to pass one of these in, and the only possible values are valid rotation amounts. You could give them default values too (which could be Rotation.random() if you wanted) so the constructor call can just be RotatableImageView(imageView)
(you could make more use of this kind of thing, like using it for the internal rotation amounts too, but in this case it's awkward because 0 is not the same as 360 when animating the view, and it might spin the wrong way - so you pretty much have to keep track of the actual rotation value you're setting on the view)
Just as a quick FYI (and this is why I was saying what you're doing could get unwieldy enough that it's worth learning some tricks), instead of doing findViewById on a ton of IDs, it can be easier to just find all the ImageViews - wrapping them in a layout with an ID (like maybe a GridLayout?) can make it easier to find the things you want
val cells = findViewById<ViewGroup>(R.id.grid).children.filterIsInstance<ImageView>()
then you can do things like
rotatables = cells.map { RotatableImageView(it) }
depends what you need to do, but that's one possible way. Basically if you find yourself repeating the same thing with minor changes, like the infomercials say, There Has To Be A Better Way!
//Object 1: (draw event)
draw_text(x,y, global.Score);
draw_set_alpha(0.5);
//Object 2: (draw_event)
draw_text(x,y, global.highscore);
draw_set_alpha(1);
The problem is, that the drawn objects (without sprites) sometimes have the alpha from the other, or even ignores the "draw_set_alpha();" (The same in step-event)
When you use draw_set_alpha(), as well as other draw_set_.. methods, you change global settings for drawing everything after it across the entire project.
Take as a rule, revert such settings back, after you draw the needed thing. So, according to your code above, you should use this:
//Object 1: (draw event)
var prev_alpha = draw_get_alpha(); //getting current alpha settings
draw_set_alpha(0.5); // setting needed alpha
draw_text(x,y, global.Score); //drawing text with 0.5 alpha
draw_set_alpha(prev_alpha); // setting alpha setting back
// the same for the second object
//Object 2: (draw_event)
var prev_alpha = draw_get_alpha();
draw_set_alpha(1);
draw_text(x,y, global.highscore);
draw_set_alpha(prev_alpha);
Application Type: mobile
Titanium SDK: 3.1.0.GA
Platform & version: iOS 6.1
Device: iOS Simulator
Host Operating System: OSX 10.8.3
Titanium Studio: 3.1.0.201304151600
I'd like to conditionally show/hide a textfield in a TableViewRow. In order to do this I need to expand the height of the row. The following code doesn't work, though. The TableViewRow is actually an Alloy controller. I first tried animating it before I realized that it can't be animated. Now I'm just trying to change the height and that isn't even working. I've tried using the setHeight method along with just setting the height property directly to no avail.
Any ideas?
var notesVisible = false;
function notes_click() {
if(notesVisible == false) {
Ti.API.info('expanding');
$.row.height = 200;
// $.notes_container.setHeight(124);
notesVisible = true;
} else {
Ti.API.info('contracting');
$.row.height = 75;
$.notes_container.setHeight(0);
notesVisible = false;
}
};
There are two good ways of doing this, both should be done from the click event listener.
Method 1) One way is to directly change the "height" variable of the row
Method 2) The second is to create a new row and replace the current row with the new row
Method 1 is more straightforward but I found it to be glitchy depending on what version of the SDK you are using, but with 3.1.0 it should work. Both methods should be called from the 'click' eventListener as its easier to tell Titanium which row to act on based on the click
So here is an example
currentTableview.addEventListener('click',function(e)
{
// DO whatever your row is supposed to do when clicked
// Now lets change the height of the row to a new height, 200 in this example
e.row.height = 200
}
With Method two, it involves creating a new row and then replacing the current row with this call
currentTableview.updateRow(e.index,newlyCreatedUpdatedRow);
I know its an old question asked by some one but the solution provided will not work and i think best solution for this is by making a recursive function and changes the height of your row and need to play with the visibility of views inside that row hopefully will help someone :)
How to change plain line to arrow line in infovis?
Currently there are some lines between blocks, I found some css files, but I cannot find which content describing the line behaviour such that I can change the plain line to arrow line.
Thanks.
Generally spoken: You can't (and shouldn't) change it via CSS. Define such properties during the setup.
Here's a brief explanation:
The Code that generates and Edge (which is a line in network visualizations) is generated by the Edge method/function which sits inside Options.Edge.js.
The function Edge is a property/module of the $jit object and works like this:
var viz = new $jit.Viz({
Edge: {
overridable: true,
type: 'line',
color: '#fff',
CanvasStyles: {
: '#ccc',
shadowBlur: 10
}
}
} );
It's important that you define overridable as true as you else can't override anything. The parameter that you're searching for is type. The allowed values are line, hyperline, arrow and I'm pretty sure that bezier will work as well - not sure if this is true for every type of graph. You can as well define custom graph Edge types - an example is missing in the documentation.
To change the Line/Edge style, there's another function that triggers before rendering. You just have to define it during the graph registration $jit.Viz( { /* add here */ } ); - code from the example/Spacetree here:
// This method is called right before plotting
// an edge. It's useful for changing an individual edge
// style properties before plotting it.
// Edge data proprties prefixed with a dollar sign will
// override the Edge global style properties.
onBeforePlotLine: function(adj){
if (adj.nodeFrom.selected && adj.nodeTo.selected) {
adj.data.$color = "#eed";
adj.data.$lineWidth = 3;
}
else {
delete adj.data.$color;
delete adj.data.$lineWidth;
}
}
The final step would now be to inspect what add.data can deliver and then either add the style you want or define a new one using a closure.
There might be another way to go on this: Example for a ForceDirected graph. Take a look at the documentation here.
$jit.ForceDirected.Plot.plotLine( adj, canvas, animating );
Maybe you could even use something like this:
var edge = viz.getEdge('Edge_ID');
edge.setData( property, value, type );
Disclaimer: I got no working copy of theJit/InfoViz library around, so I can't help more than that unless you add a JSFiddle example with your code.
Edit
As I just read that you only want to change to the default arrow type, just enter this type during the configuration of the graph.