How can I change the font size of a Gtk.Label in vala? - linux

I'm a Vala/Gtk newbie and I'm trying to change the font size of a Gtk.Label, but I can't find a good way to do it.
I find out that I can use the markup like this :
var welcome_message = new Gtk.Label ("<span size='17000'>Hello</span>");
welcome_message.set_use_markup (true);
But it seems a little hackish.
What is the right way to do it ?

Thanks lethalman and nemequ.
I think it might help someone so here is a little example of how to use css with Vala.
using Gtk;
public class StyleApp1 : Gtk.Window
{
public StyleApp1()
{
this.title = "Style app example";
this.set_border_width (10);
this.set_position (Gtk.WindowPosition.CENTER);
this.set_default_size (350, 200);
this.destroy.connect (Gtk.main_quit);
var screen = this.get_screen ();
var css_provider = new Gtk.CssProvider();
string path = "styleapp1.css";
// test if the css file exist
if (FileUtils.test (path, FileTest.EXISTS))
{
try {
css_provider.load_from_path(path);
Gtk.StyleContext.add_provider_for_screen(screen, css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER);
} catch (Error e) {
error ("Cannot load CSS stylesheet: %s", e.message);
}
}
var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 10);
this.add (box);
var label = new Gtk.Label ("Thank you");
box.add (label);
var label2 = new Gtk.Label ("Stackoverflow");
label2.get_style_context().add_class("my_class");
box.add (label2);
}
}
static int main(string[] args) {
Gtk.init(ref args);
StyleApp1 win = new StyleApp1();
win.show_all();
Gtk.main();
return 0;
}
and the styleapp1.css file :
GtkWindow {
font-size: 17px;
}
.my_class {
color: pink;
}
NB : if you use add_provider instead of add_provider_for_screen. You have to use add_provider for every widget that you want to customize.

You could try with css, I think lately this is the preferred way. Give your label a class, then load a css. If you are going to change the font size of a label, I bet you are also going to customize other things so the css may be useful for you.

Related

How to customize the UIContextualAction in tableview when swipe

I need to create an action button with a image and text. below image provide
an example.
![1]: https://i.stack.imgur.com/KEuHn.png
i have created a method like
public UIContextualAction ContextualFlagAction(int row)
{
var action = UIContextualAction.FromContextualActionStyle(UIContextualActionStyle.Normal, "Flag", Handler);
(contextualAction, view, handler) =>
{
Console.WriteLine("Hello World!");
handler(false);
});
action.Image = UIImage.FromFile(ResourceIdentifiers.DocumentIcon);
return action;
}
but this is not what i need to do.
how can i customize this action as the image in the above.
Maybe your problem showed is the image result,your code have set action.image
If you have a image that contains picture and label , picture is up,label is down,there will be you want.
public UIContextualAction ContextualFlagAction(int row)
{
var action = UIContextualAction.FromContextualActionStyle(UIContextualActionStyle.Normal, "Flag", Handler);
(contextualAction, view, handler) =>
{
Console.WriteLine("Hello World!");
handler(false);
});
action.Image = UIImage.FromFile(ResourceIdentifiers.DocumentIcon);
//this is your setted image
return action;
}
More info:
You can custom a TableViewCell in Xamarin.ios.
Write the following method in UITableViewCell, Rewrite DidTransitionToState method in viewcell, you can replace the action with button
private UITableView tableViewThis;
public TableViewCellClass(UITableView tableView)
{
this.tableViewThis = tableView;
}
public override void DidTransitionToState(UITableViewCellState mask)
{
base.DidTransitionToState(mask);
if ((mask & UITableViewCellState.ShowingDeleteConfirmationMask) == UITableViewCellState.ShowingDeleteConfirmationMask)
{
foreach (UIView subview in tableViewThis.Subviews)
{
if (subview.Class.Equals("UIContextualAction"))
//Delete the delete button of the system
tableViewThis.WillRemoveSubview(subview);
subview.BackgroundColor = UIColor.Clear;
UIButton editBtn = new UIButton(UIButtonType.Custom);
editBtn.Frame = new CGRect(10, 4, 50, 65);
editBtn.SetBackgroundImage(UIImage.FromFile("1.png"), UIControlState.Normal);
editBtn.AdjustsImageWhenHighlighted = false;
editBtn.TouchUpInside += (sender, e) =>
{
//do something you need
};
subview.AddSubview(editBtn);
}
}
}
UIButton can set both Title and Image. UIButton has two properties:
titleEdgeInsets(top,left,bottom,right)
and imageEdgeInsets(top,left,bottom,right).
By setting these two, you can implement the style you need.

Detecting doubleTap in PhaserJS

I am a complete newbie in PhaserJS. I am trying to develop a game in PhaserJS where tapping the screen once should make the user avatar move on the screen and double-tapping should make it jump. However, I am not being able to figure out how to catch the double tap event. I have seen this tutorial in their official documentation, but that didn't work. When I am putting this line
game.input.onTap.add(onTap, this);
in the
function create(){
.....
}
function, it is showing this error
Uncaught TypeError: Cannot read property 'add' of undefined
I am being able to detect single tap events using this code:
if(game.input.onTap && player.body.touching.down){
player.setVelocity(-530);
}
I've read another thread where the members have commented that to detect double click, one should start a timer and check both the clicks are coming within a threshold value. However, I think this is not a fool-proof method and there must be a better way of doing it. Can anyone please help?
Edit:
Relevant code:
<script type="text/javascript">
var width = 800;
var height = 600;
var config = {
type: Phaser.AUTO,
width: width,
height: height,
physics: {
default: 'arcade',
arcade: {
gravity: { y:300 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
var game = new Phaser.Game(config);
function preload (){
this.load.image("sky", "{% static 'task_scheduler/assets/sky.png' %}");
this.load.image("ground", "{% static 'task_scheduler/assets/platform.png' %}");
this.load.image("star", "{% static 'task_scheduler/assets/star.png' %}");
this.load.image("bomb", "{% static 'task_scheduler/assets/bomb.png' %}");
this.load.spritesheet("dude", "{% static 'task_scheduler/assets/dude.png' %}", {frameWidth: 32, frameHeight: 48});
}
var platforms;
var player;
var cursors;
var stars;
var bombs;
var score = 0;
var scoreText;
function create (){
//some other code here
//mouse and touch
this.input.onTap.add(onTap, this);
}
function onTap(pointer, doubleTap){
if (doubleTap){
player.setVelocityY(-530);
}else{
player.setVelocityX(160);
player.anims.play('right', true);
}
}
function create (){
//some other code here
//mouse and touch
this.input.onTap.add(onTap, this);
}
Here you should use game.input.onTap.add(onTap, this);
because this would reference to context from which create function is called. So, this wouldn't have property add and other properties that are available with game variable.
As far as the Double Tap is concerned that would be detected by phaser. I don't think you need to write any explicit code for that. onTap function would work just fine.

HaxeFlixel. Access violation reading location 0x00000008

I have a sprite that I can drag around on screen. I want to be able to drag this sprite into an area (box). As it stands now I can only drop the sprite into the box, but when I drag it directly inn, the the program crashes.
*Im developing in FlashDevelop but windows gave me av option to debug in VS.
I debugged in VS and got this ERROR:
Unhandled exception at 0x00ACCEE9 in Proj.exe: 0xC0000005: Access violation reading location 0x00000008.
Relevant code:
class Drag extends FlxGroup {
var mouseJoint:DistanceJoint;
public inline function registerPhysSprite(spr:FlxNapeSprite)
{
MouseEventManager.add(spr, createMouseJoint);
}
function createMouseJoint(spr:FlxSprite)
{
var body:Body = cast(spr, FlxNapeSprite).body;
mouseJoint = new DistanceJoint(FlxNapeState.space.world, body, new Vec2(FlxG.mouse.x, FlxG.mouse.y),
body.worldPointToLocal(new Vec2(FlxG.mouse.x, FlxG.mouse.y)), 0, 0);
mouseJoint.space = FlxNapeState.space;
}
override public function update():Void
{
super.update();
if (mouseJoint != null)
{
mouseJoint.anchor1 = new Vec2(FlxG.mouse.x, FlxG.mouse.y);
if (FlxG.mouse.justReleased)
{
mouseJoint.space = null;
}
}
}
}
class PlayState extends FlxNapeState {
override public function create()
{
super.create();
bgColor = FlxColor.BLACK;
napeDebugEnabled = true;
var light = new Light(10, 10);
var box = new Box(100, 100);
var drag:Drag;
createWalls(1, 1, 1024, 768, 10, new Material(1, 1, 2, 1, 0.001));
add(light);
add(box);
drag = new Drag();
add(drag);
drag.registerPhysSprite(light);
light.body.velocity.y = 200;
FlxNapeState.space.listeners.add(new InteractionListener(
CbEvent.BEGIN,
InteractionType.COLLISION,
Light.CB_TYPE,
Box.CB_TYPE,
collideLightBox));
}
function collideLightBox(callback:InteractionCallback)
{
var light:Light = cast callback.int1.castBody.userData.sprite;
light.kill();
}
}
class Light extends FlxNapeSprite {
public static var CB_TYPE(default, null) = new CbType();
public function new(x:Float, y:Float)
{
super(x, y);
makeGraphic(10, 10, FlxColor.TRANSPARENT);
var radius = 5;
drawCircle(5, 5, radius, FlxColor.WHITE);
createCircularBody(radius);
body.cbTypes.add(CB_TYPE);
body.userData.sprite = this;
}
}
class Box extends FlxNapeSprite {
public static var CB_TYPE(default, null) = new CbType();
public function new(x:Float, y:Float)
{
super(x, y);
makeGraphic(100, 50, FlxColor.GREEN);
createRectangularBody(width, height);
body.cbTypes.add(CB_TYPE);
body.type = BodyType.STATIC;
}
}
If you're possibly accessing a null pointer, consider the answer given in this question:
Why is this Haxe try-catch block still crashing, when using Release mode for C++ target
That way you can turn on null pointer checks in hxcpp so you can get better debug information.
Also, if you're trying to debug hxcpp directly in FlashDevelop (step-through and all that), that feature isn't released yet, but I spoke with the team recently and they're working on it.

How do I create an editable Label in javafx 2.2

I am looking to create an editable label at an arbitrary position on the pane on which I am writing. I am under the impression that TextField or TextArea objects are what I could use to implement that capability. There is obviously more to it as I don't know how to position the object when I create it. I have found an example on the "Chaotic Java" website but I need to do a bit more work to understand what's going on there. http://chaoticjava.com/posts/another-javafx-example-the-editable-label/
I am looking for more input from this group.
(There are no errors because I have not written any code.)
I was kind of curious about how to achieve this, so I gave it a try. This is what I came up with.
The approach used is pretty the same as that suggested by James in his comment:
I would start with a Pane, . . ., TextFields to represent text while being edited. Register mouse listeners with the Pane and Text objects, and use the layoutX and layoutY properties to position things . . . just to use text fields, and to use CSS to make them look like labels when not focused and text fields when focused.
The only significantly tricky part was working out how to correctly size the text fields as the Text inside the text field is not exposed via public API to allow you to listen to it's layout bounds. You could perhaps use a css lookup function to get at the enclosed Text, but I chose to use a private sun FontMetrics API (which may be deprecated in the future), to get the size of the text. In the future with Java 9, you should be able to perform the task without using the private API.
The solution doesn't try to do anything tricky like deal with multi-format or multi-line text, it is just for short, single line comments of a few words that can be placed over a scene.
TextCreator.java
// ## CAUTION: beware the com.sun imports...
import com.sun.javafx.tk.FontMetrics;
import com.sun.javafx.tk.Toolkit;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
* Displays a map of the lonely mountain upon which draggable, editable labels can be overlaid.
*/
public class TextCreator extends Application {
private static final String MAP_IMAGE_LOC =
"http://images.wikia.com/lotr/images/archive/f/f6/20130209175313!F27c_thorins_map_from_the_hobbit.jpg";
public static void main(String[] args) throws Exception {
launch(args);
}
#Override
public void start(final Stage stage) throws Exception {
Pane pane = new Pane();
pane.setOnMouseClicked(event -> {
if (event.getTarget() == pane) {
pane.getChildren().add(
new EditableDraggableText(event.getX(), event.getY())
);
}
});
EditableDraggableText cssStyled =
new EditableDraggableText(439, 253, "Style them with CSS");
cssStyled.getStyleClass().add("highlighted");
pane.getChildren().addAll(
new EditableDraggableText(330, 101, "Click to add a label"),
new EditableDraggableText(318, 225, "You can edit your labels"),
cssStyled,
new EditableDraggableText(336, 307, "And drag them"),
new EditableDraggableText(309, 346, "Around The Lonely Mountain")
);
StackPane layout = new StackPane(
new ImageView(
new Image(
MAP_IMAGE_LOC
)
),
pane
);
Scene scene = new Scene(layout);
scene.getStylesheets().add(getClass().getResource(
"editable-text.css"
).toExternalForm());
stage.setScene(scene);
stage.setResizable(false);
stage.show();
}
/**
* A text field which has no special decorations like background, border or focus ring.
* i.e. the EditableText just looks like a vanilla Text node or a Label node.
*/
class EditableText extends TextField {
// The right margin allows a little bit of space
// to the right of the text for the editor caret.
private final double RIGHT_MARGIN = 5;
EditableText(double x, double y) {
relocate(x, y);
getStyleClass().add("editable-text");
//** CAUTION: this uses a non-public API (FontMetrics) to calculate the field size
// the non-public API may be removed in a future JavaFX version.
// see: https://bugs.openjdk.java.net/browse/JDK-8090775
// Need font/text measurement API
FontMetrics metrics = Toolkit.getToolkit().getFontLoader().getFontMetrics(getFont());
setPrefWidth(RIGHT_MARGIN);
textProperty().addListener((observable, oldTextString, newTextString) ->
setPrefWidth(metrics.computeStringWidth(newTextString) + RIGHT_MARGIN)
);
Platform.runLater(this::requestFocus);
}
}
/**
* An EditableText (a text field which looks like a label), which can be dragged around
* the screen to reposition it.
*/
class EditableDraggableText extends StackPane {
private final double PADDING = 5;
private EditableText text = new EditableText(PADDING, PADDING);
EditableDraggableText(double x, double y) {
relocate(x - PADDING, y - PADDING);
getChildren().add(text);
getStyleClass().add("editable-draggable-text");
// if the text is empty when we lose focus,
// the node has no purpose anymore
// just remove it from the scene.
text.focusedProperty().addListener((observable, hadFocus, hasFocus) -> {
if (!hasFocus && getParent() != null && getParent() instanceof Pane &&
(text.getText() == null || text.getText().trim().isEmpty())) {
((Pane) getParent()).getChildren().remove(this);
}
});
enableDrag();
}
public EditableDraggableText(int x, int y, String text) {
this(x, y);
this.text.setText(text);
}
// make a node movable by dragging it around with the mouse.
private void enableDrag() {
final Delta dragDelta = new Delta();
setOnMousePressed(mouseEvent -> {
this.toFront();
// record a delta distance for the drag and drop operation.
dragDelta.x = mouseEvent.getX();
dragDelta.y = mouseEvent.getY();
getScene().setCursor(Cursor.MOVE);
});
setOnMouseReleased(mouseEvent -> getScene().setCursor(Cursor.HAND));
setOnMouseDragged(mouseEvent -> {
double newX = getLayoutX() + mouseEvent.getX() - dragDelta.x;
if (newX > 0 && newX < getScene().getWidth()) {
setLayoutX(newX);
}
double newY = getLayoutY() + mouseEvent.getY() - dragDelta.y;
if (newY > 0 && newY < getScene().getHeight()) {
setLayoutY(newY);
}
});
setOnMouseEntered(mouseEvent -> {
if (!mouseEvent.isPrimaryButtonDown()) {
getScene().setCursor(Cursor.HAND);
}
});
setOnMouseExited(mouseEvent -> {
if (!mouseEvent.isPrimaryButtonDown()) {
getScene().setCursor(Cursor.DEFAULT);
}
});
}
// records relative x and y co-ordinates.
private class Delta {
double x, y;
}
}
}
editable-text.css
.editable-text {
-fx-background-color: transparent;
-fx-background-insets: 0;
-fx-background-radius: 0;
-fx-padding: 0;
}
.editable-draggable-text:hover .editable-text {
-fx-background-color: yellow;
}
.editable-draggable-text {
-fx-padding: 5;
-fx-background-color: rgba(152, 251, 152, 0.2); // translucent palegreen
}
.editable-draggable-text:hover {
-fx-background-color: orange;
}
.highlighted {
-fx-background-color: rgba(255, 182, 93, 0.3); // translucent mistyrose
-fx-border-style: dashed;
-fx-border-color: firebrick;
}
If you have time, you could clean the sample implementation up and donate it to the ControlsFX project.
You can use a function of label: setGraphic().
Here is my code:
public void editableLabelTest(Stage stage){
Scene scene = new Scene(new VBox(new EditableLabel("I am a label"),
new EditableLabel("I am a label too")));
stage.setScene(scene);
stage.show();
}
class EditableLabel extends Label{
TextField tf = new TextField();
/***
* backup is used to cancel when press ESC...
*/
String backup = "";
public EditableLabel(){
this("");
}
public EditableLabel(String str){
super(str);
this.setOnMouseClicked(e -> {
if(e.getClickCount() == 2){
tf.setText(backup = this.getText());
this.setGraphic(tf);
this.setText("");
tf.requestFocus();
}
});
tf.focusedProperty().addListener((prop, o, n) -> {
if(!n){
toLabel();
}
});
tf.setOnKeyReleased(e -> {
if(e.getCode().equals(KeyCode.ENTER)){
toLabel();
}else if(e.getCode().equals(KeyCode.ESCAPE)){
tf.setText(backup);
toLabel();
}
});
}
void toLabel(){
this.setGraphic(null);
this.setText(tf.getText());
}
}

Using WebKit to work with the SVG DOM

I'm trying to access elements of an SVG file using WebKitGtk but I'm failing miserably. The program is in Vala, it's very simple and is just an attempt at getting data from a couple of elements:
using Gtk;
using WebKit;
public class WebKitTest : Window {
private WebView web_view;
private const string uri = "file:///tmp/test.svg";
public WebKitTest () {
set_default_size (800, 600);
web_view = new WebView ();
var scrolled_window = new ScrolledWindow (null, null);
scrolled_window.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
scrolled_window.add (this.web_view);
var vbox = new VBox (false, 0);
vbox.add (scrolled_window);
add (vbox);
this.destroy.connect (Gtk.main_quit);
show_all ();
this.web_view.load_uri (WebKitTest.uri);
var dom = web_view.get_dom_document ();
var el = dom.get_document_element ();
var child = el.first_element_child;
stdout.printf ("%s\n", child.tag_name);
var list = dom.get_elements_by_tag_name ("svg");
stdout.printf ("%lu\n", list.length);
assert (list == null);
var length = list.length;
assert (length == 0);
var svg = list.item (0);
var res = dom.evaluate ("//path", svg, null, 0, null);
DOMNode node;
while ((node = res.iterate_next ()) != null) {
stdout.printf ("%s\n", (node as DOMElement).tag_name);
}
}
public static void main (string[] args) {
Gtk.init (ref args);
var test = new WebKitTest ();
Gtk.main ();
return 0;
}
}
This compiles with valac --pkg webkitgtk-3.0 --pkg gtk+-3.0 webkittest.vala but if you've only got Gtk3 installed like I have you unfortunately need to do copy the webkit-1.0 .vapi and .deps files to new webkitgtk-3.0 ones and replace the occurrences of gdk-2.0 and gtk-2.0 in the .deps file to be gdk-3.0 and gtk-3.0 respectively.
I would think that using the DOM to access sub elements of an SVG would be simple, but as soon as this code gets to the print statement for child.tag_name it gives "HEAD" and nowhere in the file is that found. The file I'm loading should be pretty standard seeing as I used inkscape to make it.
Does WebKit do something funny that I'm not seeing to documents that it loads?
Thanks.
Update:
It definitely seems that WebKit loads everything into an HTML document because when I use GObject to retrieve the Type and print it for the node returned by get_elements_by_tag_name("body") I get WebKitDOMHTMLBodyElement. Be that as it may I tried to do the following XPath query on the DOMDocument
var nsres = dom.create_ns_resolver (body);
DOMXPathResult res = null;
try {
res = dom.evaluate ("//*", body, nsres, 0, null);
} catch (Error e) {
stderr.printf ("%s\n", e.message);
}
DOMNode node;
try {
while ((node = res.iterate_next ()) != null) {
stdout.printf ("%s\n", (node as DOMElement).tag_name);
}
} catch (Error e) {
stderr.printf ("%s\n", e.message);
}
and all I get for output is
HTML
HEAD
BODY
I'm lost now. The SVG file clearly loads correctly but it isn't part of the document?
I believe Webkit has a quirk where, if it doesn't know the MIME type of a document, it will wrap it in <html> tags. So I suspect the document you are trying to access has been transformed by Webkit into something like:
<html>
<head />
<body>
<svg>...etc...</svg>
</body>
</html>
That's why you are seeing a <head> tag in your code.
As a suggestion, try using Vala's equivalent of getElementsByTagName() to find your <svg> tag. From a quick look at the docs, it should be something like:
var dom = web_view.get_dom_document();
var el = dom.get_elements_by_tag_name("svg").item(0);
var child = var child = el.first_element_child;
Alternatively, if there is a way to tell WebKit/WebFrame that the MIME type of the file is "image/svg+xml", then that should also solve your problem.

Resources