ImageButton skin file scene2d (libgdx ) - libgdx

Could anyone point me to a working sample skin file for Scene2d ImageButton? Based on the ImageButton constructor, this was my unsuccessful attempt at creating a basic skin:
styles: {
com.badlogic.gdx.scenes.scene2d.ui.ImageButton$ImageButtonStyle:
{
down: downImage,
up: upImage,
checked: checkedImage
}
}
I can't find one anywhere in the documentation, although there is a sample for a TextButton skin file here.
In the Libgdx source, there is one example of using an ImageButton in a UI test by setting the styling programmatically here, but I'm hoping to avoid setting the styling in code.

I'm using the following skin successfully in my libgdx game:
{
com.badlogic.gdx.scenes.scene2d.ui.ImageButton$ImageButtonStyle: {
default: { up: select-default, imageChecked: boundary }
}
}
Where I am referencing the following image resources:
select-default.png
boundary.png
Maybe you need to name your style? If anything you can call it "default" and libgdx will use it by default if you don't specify which style to use. Also, I don't have the "styles:" that you have at the beginning. It might help if you could post the specific Exception or error message you are getting.

Try to read this tutorial. It is pretty complete and easy to understand.
Basicly, as much as i can remember, you need to define resources, which are the Textures etc.
In this resources you describe the name, which is used in your styles section (your downImage would be one). You also tell it which region of the TextureAtlas you will use for this resource.
Then you have your styles section, where you define, which resource is used for which widged in which situation.
Then in your java code you create the skin, by using the "skin.json" file and the ".png" or whatever file.
But look at this tutorial, it is much more detailed as my quick summary.

Related

Changing materials in Forge

We are currently making the client retrieve the object states when the page loads (which will cause the 'pending' objects in the model to turn into different colors). Then we poll for changes to update the coloring (Firstly: pending object gets colored when the viewer loads, and then we keep polling to check and change state again, to make Forge render those in a different color and store their old color/material. When the polling received a change that an object should no longer be colored, it tells Forge to use the old color/material again.
The problem:
We've found out what the problem is, but we couldn't find out how to fix it. The problem is that changing materials in Forge doesn't work after startup anymore, it only works in the first ~3 seconds or so (the materials were used to show the colors).
However, setting overlays works even after the first ~3 seconds, (showing overlays instead of materials to show the colors).
This is not what we want to achieve. This looks unoptimized, because overlays will be shown through everything.
The materials, however, seem to be 'locked', as in, they cannot be changed anymore after the first ~3 seconds. It seems like they aren't refreshed or something
In the examples, we found they used viewer.impl.invalidate(true) to refresh the Forge viewer, but that doesn't do anything after ~3 seconds.
We've also tried every combination of viewer.impl.invalidate(true, true, true) as well as setting material.needsUpdate to true, as well as trying to re-render the entire scene.
We also found this: https://github.com/mrdoob/three.js/issues/790, but we couldn't find a good way to do that in Forge, we tried viewer.requestSilentRender() but that didn't do anything either.
Anyway, we've tried everything we could come up with and could find online to make the materials work, but nothing made a difference.
We are looking to find someone that's more experienced with how Forge works that can see what the material code is doing wrong.
As for the content, here is all the code you will need to understand what is happening:
DROPBOX LINK
And here is a small part of the "index.html" file that sets the color:
try
{
viewer.restoreAllColorOverlays(); //for materials instead of overlays: viewer.restoreAllColorMaterials();
$.each(colors, function(color, selectionIds)
{
viewer.setColorOverlay(selectionIds, color); //for materials instead of overlays: viewer.setColorMaterial(selectionIds, color);
});
}
catch(error)
{
console.error(error);
}
I have no idea how you implement your app, so I only tell what I found in your codes. If you want to resolve the issue you addressed, you can consider providing a reproducible case demonstrating that, I will gladly pass it to our dev team. Those following items should be in the reproducible case:
A short exact description of what you are trying to achieve. The behavior you observe versus what you expect, and why this is a problem.
A complete yet minimal sample source model to run a test in.
A complete yet minimal Forge app that can be run and debugged with a simple procedure to analyze its behavior lives in the sample model.
A complete yet minimal pure three.js app that can be run and demonstrated the shader effect you want. Note. Forge Viewer is using r71 three.js.
Detailed step-by-step instructions for reproducing the issue, e.g. which element to pick, what command to launch etc.
If your reproducible case could not be posted here publicly, please send it to the forge.help#autodesk.com and remove sensitive data or information before you send.
=== Something I found in your codes:
I found here are some wrong types and missing actions in your ColorMaterial extension. The color property of an material should the a type of the THREE.Color. Here is my modification:
Autodesk.Viewing.Viewer3D.prototype.setColorMaterial = function(objectIds, color)
{
if( !(color instanceof THREE.Color) ) throw 'Invalid argument: Color';
var material = new THREE.MeshPhongMaterial
({
color: color,
opacity: 0.8,
transparent: true
});
viewer.impl.matman().addMaterial( 'ColorMaterial-' + new Date().getTime(), material, true );
// ...........
};
Its' result is here:
In the ColorOverlay extension, The type of material color property is also wrong, it should be a type of THREE.Color, too. Changing it into THREE.Color should work fine. In addition, overlay is covers on 3D objects, so you should call viewer.hide() with your setColorOverlay() together. Otherwise, it won't look like a transparent object.
Without hidding 3D object of the wall:
hide 3D object of the wall:

How can I transfer code inside of a symbol in Flash to my document class?

I am pretty new to coding in general so I'll admit my understanding of inheritance is poor. I have this code that works when it's embedded in a symbol in my Fla doc, but I can't figure out how to transfer it to the Main document.
stop();
stage.focus = input_txt;
var outputText:String;
input_txt.visible = true;
input_txt.addEventListener(KeyboardEvent.KEY_DOWN, pressEnter);
function pressEnter(e:KeyboardEvent):void {
if(e.charCode == 13) {
captureText();
this.nextFrame();
}
}
function captureText():void {
outputText=input_txt.text;
}
All that code occurred on frame2 of the office_mc symbol, and then frame 3 has this:
output_txt.text = outputText;
I'm aware that I needed to reference the txt objects as office_mc.input_txt inside the main document since they are embedded. I'm also aware that outputText would need to be a global variable. But no matter how I tried to move things around I kept having an error due to something being null. For a little background information, I'm just trying to have user input displayed in a different area within this symbol.
Could someone explain or give an example of how to execute this code in a document class? Also I'm just totally confused about how to communicate between classes in general so if anyone could point me towards tutorials or example code that could help with that understanding, it'd be greatly appreciated. :)
Don't code in timeline at all (this is a good practice).
You should use only classes which eventually points to objects from the timeline.
Here you have some good tutorials:
How to Use a Document Class
AS3 OOP (good tutorial)

Creating MovieClip 'components' that don't add to file size in Flash AS2/AS3

I want to create a re-usable Flash MovieClip (component maybe?) that can be dragged and dropped from the library onto the Flash IDE stage (for an example, a "stop all movieclips timer component").
I've created some attractive vector icon graphics for visual reference, so that when it's dragged onto the stage, the developer can visually see the component on the stage, similar to what Google does with it's DoubleClick components. It's not important for these icon graphics to be seen at runtime however, and I'd like their visual portions to not be compiled at runtime to save on filesize.
I'm often asked to create visually rich Flash units in extremely small file sizes. So basically I want my movieclip icon components to not add to filesize (except for the code portion), not compile and render visually but still have the code within them run.
How can I achieve this? Would creating them as components do anything for my issue? Is this even do-able?
Components are definitely the best way to achieve visually represented imported code, however it would be much easier, more compatible and more reliable to just use an imported code library...
Make a seperate .as file, put it in com/mycompany/animation in your swf folder (or use a global classpath), and add this code:
package com.mycompany.animation {
class MyTimerUtils {
public static function stopAllClipsAfterTime(ms){
setInterval(MyTimerUtils.stopAllClips, ms);
}
public static function stopAllClips(){
//etc
}
}
}
Then when you want to use it in a project, just put this code on frame 1 of your main timeline:
import code.mycompany.animation.MyTimerUtils;
MyTimerUtils.stopAllClipsAfterTime(3000); // 3 seconds
What could be easier? If another developer wants to know if a piece of code is implemented they need only look at the first few lines of code.

StageWebView Lack on URLs with target="_blank"

is there any solution on StageWebView.loadURL(), how I can handle URLs in HTML Pages which have target="_blank"?
It's a mobile Android App. (TabbedViewApplication)
Hope someone can help.
Thx
One option is StageWebViewBridge.
StageWebViewBridge is an extended version of flash.media.StageWebView.
Extends loadString method with AS3 - JS communication.
-Extends Bitmap class, you can modify his x,y,alpha,rotation,visible, etc ( Version 1 Beta )
-Communicates Actionscript with Javascript.
-Communicates Javascript with Actionscript.
-Load local files and resources in a easy way.
-Extends loadString method with AS3 - JS communication.
-Extends loadString method to load local resources.
-Lets you take an SnapShot to use as the bitmapData of the bitmap.
StageWebViewBridge source: https://code.google.com/p/stagewebviewbridge/
I never worked with the StageWebView but I know it's really limited. When using an HTMLLoader, you can set a custom HTMLHost instance that specifies to use current HTMLLoader when opening to _blank. However, I don't think it's possible with StageWebView.
public class MyHTMLHost extends HTMLHost
{
public function MyHTMLHost(defaultBehaviors:Boolean=false)
{
super(defaultBehaviors);
}
override public function createWindow(windowCreateOptions:HTMLWindowCreateOptions):HTMLLoader
{
// all JS calls and HREFs to open a new window should use the existing window
return htmlLoader;
}
}
OK, so the only solution for this problem i could found is to load the page (containing the links) as String with the URLLoader and replace its specified parts. Finally loading it via StageWebView.loadString() method.
Problems occur when the Site is dynamic and contains JavaScript. I had also replace some relative links with absolute pathes.
That's it... but I really hope that adobe makes it possible to load those "_blank" links with the StageWebView.loadURL() method.
If you want to capture when a user clicks on a link inside your StageWebView add an an event listener for location changing event (LocationChangeEvent).
This LocationChangeEvent will include the URL they are going to and target. Then you can prevent the URL from loading, let it continue (by doing nothing) or handle it any other way including loading another URL.
If you want to load another URL first stop the loading with stageWebView.stop(). You should also call event.preventDefault(). You can then attempt to
Note: There is another event called locationChange that may be helpful.
As it was declared as an official bug, adobe QA Owner Sanjay C. added a comment: "Able to reproduce the issue with the attached project. Sending to IRB."
So, hope the next Build will come up with the fix wit it.
Best regards

Is there a way to add a flex skin programmatically in ActionScript?

I have various components that are skinned through a programmatic skin. The skin class references a singleton class that holds various colors to be applied to different aspects of the component. The singleton class has default colors set to variations of black/grey etc. I'm loading in custom colors from an XML file that are then loaded into the singleton. I'm applying the custom skin through a css stylesheet that is included in the main Application mxml.
The problem is that when the swf initially loads, the components that are drawn on screen are black and don't reflect the changes in color loaded from the XML file. I have some dropdown windows that show on button clicks and those dropdowns do reflect the correct colors from the XML file. Therefore, the system is working correctly, but the initial drawing of components obviously happens before the XML is loaded and applied to the singleton.
My question is, is there a way to apply a skin to an element programmatically by calling the constructor?
I have this in my css file:
.PanControlsBackground {
borderSkin:ClassReference('skins.buttons.PanControlsBackground');
}
and I'm applying the class with this:
_app.panControls.styleName = "PanControlsBackground";
Is there a way to call:
_app.panControls.styleName = new PanControlsBackground();
or something to that effect? This way, I can remove the loading of the skins in the css file and control when they are instantiated to ensure that the correct colors are applied before displaying the various components.
You could use the styleManager to manipulate the style at run time. For example,
.PanControlsBackground {
/* leave it blank */
}
And then in some script block:
styleManager.getStyleDeclaration(".PanControlsBackground").setStyle("borderSkin", skins.buttons.PanControlsBackground);
So, that's one way of changing the skin in a programmatic way.
However, I don't know much about how the garbage collection is handled on the old skins. For instance, how would the GC differ on this method of switching the skin versus just having a bunch of different CSS classes for each of your skins and switching between them? I can't really answer that.
I think one could at least say that the above method would ensure that the default (or other minimal skin you might create) is used first, and one could control when in the initialization process the other skin get's instantiated.