I'm doing everything just like in the instruction.
Class Fonts.hx
import flash.text.Font;
#:font("assets/fonts/OPENSANS-REGULAR_0.TTF") class OpenSansFont extends Font { }
class Fonts
{
public static inline var OPEN_SANS_PATH = "assets/fonts/OPENSANS-REGULAR_0.TTF";
public static inline var OPEN_SANS_FONTNAME = "OPENSANS-REGULAR_0.TTF";
public function new()
{
Font.registerFont(OpenSansFont);
}
}
But when I try create TextFormat with this:
var tf:TextFormat;
var openSans:Font = Assets.getFont(Fonts.OPEN_SANS_PATH);
tf = new TextFormat(openSans.fontName);
I catch this error:
Assets.hx:257: [openfl.Assets] There is no Font asset with an ID of
"assets/fonts/OPENSANS-REGULAR_0.TTF"
What am I doing wrong?
My project structure:
You can't use openfl.Assets for Assets embedded via #:font / #:bitmap etc.
You should use the font's name for the TextFormat constructor. I assume you've already tried that, seeing how there's an OPEN_SANS_FONTNAME variable. However, that's not the font's name, just its file name.
On Windows, you should be able to find out the name by double-clicking on the font (right under the print / install buttons).
Alternatively, this should work as well:
import flash.text.Font;
#:font("assets/fonts/OPENSANS-REGULAR_0.TTF") class OpenSansFont extends Font { }
class Fonts
{
public static var OPEN_SANS_FONTNAME;
public function new()
{
Font.registerFont(OpenSansFont);
OPEN_SANS_FONTNAME = new OpenSansFont().fontName;
}
}
Related
In WinUI, I want to create a Decimal NumberBox (like a regular number box, but accepting and returning decimals instead of doubles) and base the style off the existing NumberBox control. How do I do this?
This is what the code behind the control looks like:
public class DecimalBox : NumberBox
{
public DecimalBox()
{
this.DefaultStyleKey = typeof(DecimalBox);
}
public new decimal Value
{
get { return Convert.ToDecimal(base.Value); }
set { base.Value = Convert.ToDouble(value); }
}
}
And this is how I tried to style it:
<Style TargetType="controls:DecimalBox" BasedOn="{StaticResource DefaultNumberBoxStyle}"/>
But I don't know what to put in for the existing DefaultNumberBoxStyle. There is no "DefaultNumberBoxStyle" in the default generic resource dictionary. In the old days, we'd use something like:
<Style TargetType="controls:DecimalBox" BasedOn="{StaticResource {x:Type NumberBox}}"/>
But I don't know what the analog is in WinUI.
If you just want to use the default NumberBox template, you can do it this way:
public sealed class DecimalBox : NumberBox
{
public DecimalBox()
{
this.DefaultStyleKey = typeof(NumberBox);
}
public new decimal Value
{
get => Convert.ToDecimal(base.Value);
set => base.Value = Convert.ToDouble(value);
}
}
If you want to modify the template, you need to bring the entire template from generic.xaml since there's no "DefaultNumberBoxStyle".
I've got this compiletime errors when I make some class implement an interface with properties that have been fromerly defined in some native sub class, like openfl.display.Sprite. It occurs when I'm targeting flash, not js.
Field get_someValue needed by SomeInterface is missing
Field set_someValue needed by SomeInterface is missing
Field someValue has different property access than in SomeInterface (var should be (get,set))
In contrast, there's no problem with interface definitions of 'native' methods or 'non-native' properties. Those work.
Do I have to avoid that (not so typical) use of interfaces with haxe and rewrite my code? Or is there any way to bypass this problem?
Thanks in advance.
Example:
class NativePropertyInterfaceImplTest
{
public function new()
{
var spr:FooSprite = new FooSprite();
spr.visible = !spr.visible;
}
}
class FooSprite extends Sprite implements IFoo
{
public function new()
{
super();
}
}
interface IFoo
{
public var visible (get, set):Bool; // Cannot use this ):
}
TL;DR
You need to use a slightly different signature on the Flash target:
interface IFoo
{
#if flash
public var visible:Bool;
#else
public var visible (get, set):Bool;
#end
}
Additional Information
Haxe get and set imply that get_property():T and set_property(value:T):T both exist. OpenFL uses this syntax for many properties, including displayObject.visible.
Core ActionScript VM classes (such as Sprite) don't use Haxe get/set, but are native properties. This is why they look different.
Overriding Core Properties
If you ever need to override core properties like this, here is an example of how you would do so for both Flash and other targets on OpenFL:
class CustomSprite extends Sprite {
private var _visible:Bool = true;
public function new () {
super ();
}
#if flash
#:getter(visible) private function get_visible ():Bool { return _visible; }
#:setter(visible) private function set_visible (value:Bool):Void { _visible = value; }
#else
private override function get_visible ():Bool { return _visible; }
private override function set_visible (value:Bool):Bool { return _visible = value; }
#end
}
Overriding Custom Properties
This is not needed for custom properties, which are the same on all platforms:
class BaseClass {
public var name (default, set):String;
public function new () {
}
private function set_name (value:String) {
return this.name = value;
}
}
class SuperClass {
public function new () {
super ();
}
private override function set_name (value:String):String {
return this.name = value + " Q. Public";
}
}
Need to provide the method signatures in an Interface. Currently its just a property declaration.
The error message is saying it all.
Field get_someValue needed by SomeInterface is missing
Field set_someValue needed by SomeInterface is missing
Hopefully that helps.
I'm trying to use TypeScript to create a common library for a set of related web sites. I started off code like this:
module Lib {
export module Tools {
export class Opener {
public Path: string;
public static Open(): boolean { /* ... */ }
}
export class Closer { /* ... */ }
}
export module Controls {
export class InfoDisplay { /* ... */ }
export class Logon { /* ... */ }
}
export module Entities {
export class BigThing { /* ... */ }
export class LittleThing { /* ... */ }
}
}
var Initial: boolean = Lib.Tools.Opener.Open();
var CustomOpener: Lib.Tools.Opener = new Lib.Tools.Opener();
This worked quite well and allowed me to use some of TypeScript's nice features, like static methods and namespaced class names. As the project has grown, however, the need to use a module system for dependency resolution has become clear. My problem is that I'm a RequireJS noob so I can't quite figure out how get preserve the desirable features mentioned above to work in my project once RequireJS is in the mix. Here's my best attempt so far (which, to save space, only shows the code trail for Opener):
// ---- Opener.ts --------------------------------------------------------
/// <reference path="../typings/requirejs/require.d.ts"/>
class Opener {
public Path: string;
public static Open(): boolean { /* ... */ }
}
export = Opener;
// ---- Tools.ts --------------------------------------------------------
/// <reference path="../typings/requirejs/require.d.ts"/>
import Opener = require("./Opener");
import Closer = require("./Closer");
class Tools {
public Opener: Opener = new Opener();
public Closer: Closer = new Closer();
}
export = Tools;
// ---- ReqLib.ts --------------------------------------------------------
/// <reference path="../typings/requirejs/require.d.ts"/>
import Tools = require("./Tools");
class ReqLib {
public Tools: Tools = new Tools();
}
export = ReqLib;
// ---- App.ts --------------------------------------------------------
import ReqLib = require("./ReqLib");
var RL: ReqLib = new ReqLib();
var Initial: boolean = RL.Tools.Opener.Open(); // <== red squiggles
var CustomerOpener: ReqLib.Tools.Opener = new ReqLib.Tools.Opener(); // <== red squiggles
Visual Studio doesn't like the last two lines. It can't see the static method in the first line and it just flat out doesn't like the second because it looks like instances are being used as types. It's also the more troubling case because TypeScript kind of needs to have types to work with.
In your code RL.Tools.Opener is resolving to new Opener(); The static public static Open() does not exist on an instance but instead exists on the class Opener, hence the compiler error.
Suggestion : don't make it static. There might be other suggestions but now you know the reason for the error.
UPDATE
for new ReqLib.Tools.Opener(); you need to do new ReqLib().Tools.Opener;
I am working on a C# class that imports text data from a web site. That works OK. Where I'm losing it is how to display the text in Unity 4.6 once I have all the text in a string variable. Any advice is appreciated.
Unity 4.6 UI system has component named Text. You can watch video tutorial here. Also I suggest you to check out its API.
As always, you have two options on how to add this component to the game object. You can do it from editor (just click on game object you want to have this component in hierarchy and add Text component). Or you can do it from script using gameObject.AddComponent<Text>().
In case you are not familiar with components yet, I suggest you to read this article.
Anyway, in your script you'll need to add using UnityEngine.UI; at the very top of it, because the Text class is in UnityEngine.UI namespace. Ok, so now back to script that will set the value of Text component.
First you need variable that refers to Text component. It can be done via exposing it to editor:
public class MyClass : MonoBehaviour {
public Text myText;
public void SetText(string text) {
myText.text = text;
}
}
And attaching gameObject with text component to this value in Editor.
Another option:
public class MyClass : MonoBehaviour {
public void SetText(string text) {
// you can try to get this component
var myText = gameObject.GetComponent<Text>();
// but it can be null, so you might want to add it
if (myText == null) {
myText = gameObject.AddComponent<Text>();
}
myText.text = text;
}
}
Previous script is not a good example, because GetComponent is actually expensive. So you might want to cache it’s reference:
public class MyClass : MonoBehaviour {
Text myText;
public void SetText(string text) {
if (myText == null) {
// looks like we need to get it or add
myText = gameObject.GetComponent<Text>();
// and again it can be null
if (myText == null) {
myText = gameObject.AddComponent<Text>();
}
}
// now we can set the value
myText.text = text;
}
}
BTW, the patter of ‘GetComponent or Add if it doesn’t exist yet’ is so common, that usually in Unity you want to define function
static public class MethodExtensionForMonoBehaviourTransform {
static public T GetOrAddComponent<T> (this Component child) where T: Component {
T result = child.GetComponent<T>();
if (result == null) {
result = child.gameObject.AddComponent<T>();
}
return result;
}
}
So you can use it as:
public class MyClass : MonoBehaviour {
Text myText;
public void SetText(string text) {
if (myText == null) {
// looks like we need to get it or add
myText = gameObject.GetOrAddComponent<Text>();
}
// now we can set the value
myText.text = text;
}
}
make sure you import the ui library - using UnityEngine.UI
gameObject.GetComponent<Text>().text - replace .text with any other field for UI Text
I assume that the issue is creating dynamic sized "textbox" rather than just assigning the string to a GUIText GameObject. (If not - just put a GUIText GameObject into your scene, access it via a GUIText variable in your script and use myGUIText.text = myString in Start or Update.)
If I am correct in my assumption, then I think you should just be using a GUI Label:
http://docs.unity3d.com/ScriptReference/GUI.Label.html
If you need to split the string up to place text into different labels or GUITexts, you will need to use substrings
I'm working on a AS3 script where I try to start a thread. I keep getting the 1009 error below when I try. I'm following a howto page from the internet pretty closely. I'm using (I think) version 11.4 of flash.
TypeError: Error #1009: Cannot access a property or method of a null
object reference.
This refers to the line where swfBytes is assigned this.loaderInfo.bytes.
package somepackage {
import flash.system.MessageChannel;
import flash.system.Worker;
import flash.system.WorkerDomain;
import flash.events.Event;
import flash.utils.ByteArray;
public class SomeClass extends Sprite{
public var mainToWorker:MessageChannel;
public var workerToMain:MessageChannel;
public var worker:Worker;
public function SomeClass() {
// constructor code
if (Worker.current.isPrimordial) {
var swfBytes:ByteArray = this.loaderInfo.bytes;// HERE
worker = WorkerDomain.current.createWorker( swfBytes );
mainToWorker = Worker.current.createMessageChannel(worker);
workerToMain = worker.createMessageChannel(Worker.current);
worker.setSharedProperty("mainToWorker", mainToWorker);
worker.setSharedProperty("workerToMain", workerToMain);
//workerToMain.addEventListener(Event.CHANNEL_MESSAGE, onWorkerToMain);
//worker.start();
}
else {
mainToWorker = Worker.current.getSharedProperty("mainToWorker");
workerToMain = Worker.current.getSharedProperty("workerToMain");
//mainToWorker.addEventListener("mainToWorker", onMainToWorker);
}
}
}
}
If anyone has seen this before or knows what I'm doing wrong I'd be most appreciative.
I'm instantiating this as part of a much larger group of classes. I thought that might be my problem, so I instantiated this class on it's own at the 'actions' script page of the root scene. I'm using Flash CS6. There is not much on the 'actions' page I was referring to.
var ai:SomeClass = new SomeClass();
addChild(ai);
EDIT 1:
Here I've included a 'addEventListener' line. This code seems to work in debug mode but not if I just play the movie regularly. If I play it regularly I get the 1009 error again, presumably for the line after the trace. What could I replace 'Event.ADDED_TO_STAGE' with that would allow this to run??
package somepackage {
public class SomeClass extends Sprite{
public var mainToWorker:MessageChannel;
public var workerToMain:MessageChannel;
public var worker:Worker;
public function SomeClass() {
if (Worker.current.isPrimordial) {
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
}
public function onAddedToStage(e:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
trace(this.loaderInfo);
var swfBytes:ByteArray = this.loaderInfo.bytes;
worker = WorkerDomain.current.createWorker( swfBytes );
mainToWorker = Worker.current.createMessageChannel(worker);
workerToMain = worker.createMessageChannel(Worker.current);
worker.setSharedProperty("mainToWorker", mainToWorker);
worker.setSharedProperty("workerToMain", workerToMain);
workerToMain.addEventListener(Event.CHANNEL_MESSAGE, onWorkerToMain);
worker.start();
}
}
}