Very small material font - codenameone

I'm trying to use the material icon font in my title commands without transforming them in a FontImage but I can only obtain very little chars.
Style s = UIManager.getInstance().getComponentStyle("TitleCommand");
s.setFont(FontImage.getMaterialDesignFont().derive(s.getFont().getHeight(),
Font.STYLE_PLAIN));
UIManager.getInstance().setComponentStyle("TitleCommand", s);
this should give me the possibility to have multiple icons in a single command but the chars/glyphs I get are very small (on iphone3 simulator they are scaled to a single pixel!).
What is wrong?

This code worked for me:
Toolbar.setGlobalToolbar(true);
Style s = UIManager.getInstance().getComponentStyle("TitleCommand");
s.setFont(FontImage.getMaterialDesignFont().derive(s.getFont().getHeight(), Font.STYLE_PLAIN));
UIManager.getInstance().setComponentStyle("TitleCommand", s);
Form hi = new Form("Test");
hi.getToolbar().addCommandToRightBar("" + FontImage.MATERIAL_3D_ROTATION, null, e -> Log.p("Invoked"));
hi.show();
To produce this:
I usually use a more conventional way of creating an icon with a millimeter size but this should work.

Related

How to add name below to FontImage on toolbar?

I am using fontImages in codename one to the Toolbar. So our requirement is to set name below to that Font Images.
Something like this:
Command cmd = toolbar.addMaterialCommandToRightSide("Name", FontImage.MATERIAL_INFO, e -> {});
Button b = toolbar.findCommandComponent(cmd);
b.setTextPosition(Component.BOTTOM);

Layout issue with Codename One

At this moment I'm only testing my app in the simulator (as I'm having issues with "Send iOS Build" mentioned in another thread [Errors with Codename One "Send iOS Build" and "Send Android Build")
I'm experiencing some layout issues where it is not making use of the width and height correctly. The elements are left-aligned and there is unused space on the right side. And I need to scroll up and down instead of having everything fit within the visual area. Please see images.
The code are:
private final void show() {
loginSignupForm = new Form("Company", new BoxLayout(0));
Tabs loginSignupTabs = new Tabs();
Style loginSignupStyle = UIManager.getInstance().getComponentStyle("Tab");
prepareAndAddSignupTab(loginSignupTabs, loginSignupStyle);
prepareAndAddLoginTab(loginSignupTabs, loginSignupStyle);
loginSignupForm.add(loginSignupTabs);
loginSignupForm.show();
}
private void prepareAndAddLoginTab(Tabs loginSignupTabs, Style loginSignupStyle) {
loginID = new TextField();
loginPassword = new TextField();
Button loginButton = getLoginButton();
Component[] loginComponents = {
new Label("Email Address"),
loginID,
new Label("Password"),
loginPassword,
loginButton,
};
Container loginContainer = BoxLayout.encloseY(loginComponents);
FontImage loginIcon = FontImage.createMaterial(FontImage.MATERIAL_QUESTION_ANSWER, loginSignupStyle);
loginSignupTabs.addTab("Login", loginIcon, loginContainer);
}
What do I need to changenter code heree to get the elements to:
1. expand to the maximum width (no free space on the right)
2. fit within the visual area (for top-to-bottom)
Please note that I'm coding the elements because I find the (new) GUI Builder quite a challenge to use.
Firstly, don't pass a constant value as an argument to Layouts, coz the values might change in future Codename One updates and this will be difficult for you to debug. new BoxLayout(0) should be new BoxLayout(BoxLayout.Y_AXIS) or simply BoxLayout.y().
The above is where the problem arose but not the only problem because BoxLayout doesn't recognize 0 as a valid argument as it has only 3 which are X_AXIS = 1, Y_AXIS = 2, and X_AXIS_NO_GROW = 3.
If you change the above to use BoxLayout.Y_AXIS, it will work, but from the screenshot above, that's not the best solution.
In conclusion, change your code to below:
private final void show() {
loginSignupForm = new Form("Company", new BorderLayout());
Tabs loginSignupTabs = new Tabs();
Style loginSignupStyle = UIManager.getInstance().getComponentStyle("Tab");
prepareAndAddSignupTab(loginSignupTabs, loginSignupStyle);
prepareAndAddLoginTab(loginSignupTabs, loginSignupStyle);
loginSignupForm.add(BorderLayout.CENTER, loginSignupTabs);
loginSignupForm.show();
}

Codenameone: Alert Dialog message

we want dialog message in this format and look and fill
Can you please let me know how to resolve it. My application needs to be supported on all platforms (Android, iOS, Windows) and I don't want to write native code for all platforms separately.
Actually customizing the look is easier in Codename One as everything is written in Java you can customize literally everything about the look of anything.
For simplicity sake I used code rather than styles which would be better, you can customize the Dialog UIID and other UIID's in the theme designer to get more flexibility and have this easier. However, this would require many screenshots and explanations so I did the customization in code:
Form f = new Form("Test");
Button b = new Button("Show Dialog");
f.add(b);
b.addActionListener(e -> {
Dialog dlg = new Dialog("Authentication");
Style dlgStyle = dlg.getDialogStyle();
dlgStyle.setBorder(Border.createEmpty());
dlgStyle.setBgTransparency(255);
dlgStyle.setBgColor(0xffffff);
Label title = dlg.getTitleComponent();
title.setIcon(finalDuke.scaledHeight(title.getPreferredH()));
title.getUnselectedStyle().setFgColor(0xff);
title.getUnselectedStyle().setAlignment(Component.LEFT);
dlg.setLayout(BoxLayout.y());
Label blueLabel = new Label();
blueLabel.setShowEvenIfBlank(true);
blueLabel.getUnselectedStyle().setBgColor(0xff);
blueLabel.getUnselectedStyle().setPadding(1, 1, 1, 1);
blueLabel.getUnselectedStyle().setPaddingUnit(Style.UNIT_TYPE_PIXELS);
dlg.add(blueLabel);
TextArea ta = new TextArea("This is the text you want to appear in the dialog, this might line break if the text is too long...");
ta.setEditable(false);
ta.setUIID("DialogBody");
ta.getAllStyles().setFgColor(0);
dlg.add(ta);
Label grayLabel = new Label();
grayLabel.setShowEvenIfBlank(true);
grayLabel.getUnselectedStyle().setBgColor(0xcccccc);
grayLabel.getUnselectedStyle().setPadding(1, 1, 1, 1);
grayLabel.getUnselectedStyle().setPaddingUnit(Style.UNIT_TYPE_PIXELS);
dlg.add(grayLabel);
Button ok = new Button(new Command("OK"));
ok.getAllStyles().setBorder(Border.createEmpty());
ok.getAllStyles().setFgColor(0);
dlg.add(ok);
dlg.showDialog();
});
f.show();
I would recommend doing the dialog customization in the theme designer and using a 9-piece image border which is better looking.

Codename One rounded image from an internet source

I am trying to display a rounded image that I get straight from the Internet.
I used the code below to create a round mask, get the image from the Internet, then tried to either set the mask on the image or the label itself. None of these approaches worked. If I remove the mask, the image is displayed fine. If I keep the code to set the mask then all I see is an empty white circle.
I have the idea that if I apply the mask on the image itself, then it may not take effect because the image was not downloaded at the time the mask was applied.
But I don't seem to understand why calling setMask on the label is also not working.
// Create MASK
Image maskImage = Image.createImage(w, l);
Graphics g = maskImage.getGraphics();
g.setAntiAliased(true);
g.setColor(0x000000);
g.fillRect(0, 0, w, l);
g.setColor(0xffffff);
g.fillArc(0, 0, w, l, 0, 360);
Object mask = maskImage.createMask();
// GET IMAGE
com.cloudinary.Cloudinary cloudinary = new com.cloudinary.Cloudinary(ObjectUtils.asMap(
"cloud_name", "REMOVED",
"api_key", "REMOVED",
"api_secret", "REMOVED"));
// Disable private CDN URLs as this doesn't seem to work with free accounts
cloudinary.config.privateCdn = false;
Image placeholder = Image.createImage(150, 150);
EncodedImage encImage = EncodedImage.createFromImage(placeholder, false);
Image img2 = cloudinary.url()
.type("fetch") // Says we are fetching an image
.format("jpg") // We want it to be a jpg
.transformation(
new Transformation()
.radius("max").width(150).height(150).crop("thumb").gravity("faces").image(encImage, "http://upload.wikimedia.org/wikipedia/commons/4/46/Jennifer_Lawrence_at_the_83rd_Academy_Awards.jpg");
Label label = new Label(img2);
label.setMask(mask); // also tried to do img2.applyMask(mask); before passing img2
So I tried various things:
1) Removing the mask that was set through cloudinary - That did not work
2) applied the mask to the placeholder & encoded image (as expected these shouldnt affect the final version that is getting published)
3) This is what works! I am not sure if the issue is really with downloading the picture before or after applying the mask.. time can tell down the road
Label label = new Label();
img2.applyMask(mask); // If you remove this line , the image will no longer be displayed, I will only see a rounded white circle ! I am not sure what this is doing, it might be simply stalling the process until the image is downloaded? or maybe somehow calling repaint or revalidate
label.setIcon( img2.applyMask(mask));
Here is what worked for me if anyone else is having similar issues:
//CREATE MASK
Image maskImage = Image.createImage(w, l);
Graphics g = maskImage.getGraphics();
g.setAntiAliased(true);
g.setColor(0x000000);
g.fillRect(0, 0, w, l);
g.setColor(0xffffff);
g.fillArc(0, 0, w, l, 0, 360);
Object mask = maskImage.createMask();
//CONNECT TO CLOUDINARY
com.cloudinary.Cloudinary cloudinary = new com.cloudinary.Cloudinary(ObjectUtils.asMap(
"cloud_name", "REMOVED",
"api_key", "REMOVED",
"api_secret", "REMOVED"));
// Disable private CDN URLs as this doesn't seem to work with free accounts
cloudinary.config.privateCdn = false;
//CREATE IMAGE PLACEHOLDERS
Image placeholder = Image.createImage(w, l);
EncodedImage encImage = EncodedImage.createFromImage(placeholder, false);
//DOWNLOAD IMAGE
Image img2 = cloudinary.url()
.type("fetch") // Says we are fetching an image
.format("jpg") // We want it to be a jpg
.transformation(
new Transformation()
.crop("thumb").gravity("faces")
.image(encImage, url);
// Add the image to a label and place it on the form.
//GetCircleImage(img2);
Label label = new Label();
img2.applyMask(mask); // If you remove this line , the image will no longer be displayed, I will only see a rounded white circle ! I am not sure what this is doing, it might be simply stalling the process until the image is downloaded? or maybe somehow calling repaint or revalidate
label.setIcon( img2.applyMask(mask));
Shai, I seriously appreciate your time!! Thank you very much. Will have to dig more into it if it gives me any other problems later but it seems to consistently work for now.
The Cloudinary API returns a URLImage which doesn't work well with the Label.setMask() method because, technically, a URLImage is an animated image (it is a placeholder image until it finishes loading, and then "animates" to become the target image).
I have just released a new version of the cloudinary cn1lib which gives you a couple of options for working around this.
I have added two new image() methods. One that takes an ImageAdapter parameter that you can use to apply the mask to the image itself, before setting it as the icon for the label. Then you wouldn't use Label.setMask() at all.
See javadocs for this method here
The other method uses the new Async image loading APIs underneath to load the image asynchronously. The image you receive in the callback is a "real" image so you can use it with a mask normally.
See javadocs for this method here
We are looking at adding a soft warning to the Label.setMask() and setIcon() methods if you try to add an "animated" image and mask it so that it is more clear.
I think the making code you set to the label might be conflicting with the masking code you get from Cloudinary.

How to flex TextField in qooxdoo mobile

I'm trying to add a row on a qx.ui.mobile.page.NavigationPage consisting of a label, a text field, and a button. I want the text field to take up any extra horizontal space (the row should span the screen horizontally). I thought this would work:
var comp = new qx.ui.mobile.container.Composite();
comp.setLayout(new qx.ui.mobile.layout.HBox(null, 'middle'));
comp.add(new qx.ui.mobile.basic.Label("Filtering:"));
var f = new qx.ui.mobile.form.TextField();
comp.add(f, {flex:1});
var b = new qx.ui.mobile.form.Button("Update");
comp.add(b);
this.getContent().add(comp);
but it doesn't (see http://tinyurl.com/nwlhtwq for a playground example).
What am doing wrong? Thanks!
Have a look at this example:
http://tinyurl.com/nmw6lgs
It is because the textfield has a "display:inline-block" by default, and width of 100%.
Please set these properties:
qx.bom.element.Style.set(textField.getContentElement(),"display","block");
qx.bom.element.Style.set(textField.getContentElement(),"width","auto");
We will fix that in framework, too.

Resources