I am currently working on my own implementation of a tab bar for a BlackBerry app, where each tab bar has a title that is right aligned (i.e. the last character in each should be the same distance from the right hand side of the screen). To work out where to draw the text I am using the following calculation:
screen width - advance of title - indent.
The font I am using is 'BBAlpha Sans' (height 28). Using BlackBerry OS 4.6 everything seems to be calculated properly and the text is aligned when I move between tabs, however I am finding that when I use OS 5.0 it doesn't calculate the advance properly and as a result the alignment is off by maybe 5 pixels or so. With the default font (also BBAlpha Sans, but height 24 - for OS 5.0 at least) it works fine in both versions.. but I don't necessarily always want to use the default font/size, so any ideas what could be going wrong? Is this a bug in the 5.0 API?
Thanks.
Code:
public class TitleBarBackground extends Background {
..
public void draw(Graphics graphics, XYRect rect) {
graphics.pushRegion(rect);
..
Font titleBarFont = FontFamily.forName("BBAlpha Sans").getFont(Font.PLAIN, 28);
...
int textWidth = titleBarFont.getAdvance(title);
graphics.drawText(title, rect.width - textWidth - TITLE_OFFSET, textYOffset);
graphics.popContext();
}
..
}
Are you calling graphics.setFont(titleBarFont) before graphics.drawText()?
Related
I've been trying to embed a youtube video within a codename one application. When I run the simulator for both Android and iOS it looks fine, but when I actually run the application on my Galaxy S7, nothing shows. I've tried using both BrowserComponent and WebBrowser and neither work. My code is below:
Form hi = new Form("Hi World", BoxLayout.y());
Display display = Display.getInstance();
BrowserComponent browser = new BrowserComponent();
//WebBrowser browser = new WebBrowser();
String videoUrl = "https://www.youtube.com/embed/r6VO3zaBJGY";
int videoWidth = (int) ((double) display.getDisplayWidth());
int videoHeight = (int) ((double) videoWidth*0.5625);
String integrationCode= "<iframe src=\"" +videoUrl+"\" frameborder=\"0\" width=\"" + videoWidth + "\" height=\"" + videoHeight + "\" allow=\"autoplay; encrypted-media\" allowfullscreen></iframe>";
browser.setPage(integrationCode, null);
browser.getAllStyles().setPadding(0, 0, 0, 0);
browser.getAllStyles().setMargin(0, 0, 0, 0);
Container browserContainer = new Container(new BorderLayout(CENTER_BEHAVIOR_CENTER));
browserContainer.add(CENTER, browser);
hi.add(browserContainer);
hi.show();
There are two mistakes in the code: BoxLayout and CENTER_BEHAVIOR_CENTER.
The reason this won't work has to do with the way layouts work. Layout managers use the preferred size to give components the right size. BrowserComponent doesn't have a proper preferred size as the rendering of HTML is asynchronous and it's pretty flexible to begin with. In this case you used two layout managers that respect preferred size. They get a size that amounts to zero and place the browser component appropriately...
BoxLayout.Y_AXIS needs the preferred height and CENTER_BEHAVIOR_CENTER needs the preferred size to position the component in the center.
The typical workaround is to use a regular BorderLayout which defaults to the scaled behavior. This stretches the center component to take up available space. Notice you need to set it on the Form itself as it has a hardcoded size of the entire screen. The center location ignores the preferred size and gives the component the full size.
It also solves another problem. Form is scrollable by default on the Y axis. Scrollability for Codename One components and native widgets (e.g. web) can collide so by using the border layout you implicitly disable scrolling which in this case might provide superior UX.
Note that you can get the code above to work by overriding calcPreferredSize() in BrowserComponent and returning the size you want for the component. I don't think this will result in a good UX because of scrollability issues.
So far I have tested this one :
mainLabel.Canvas.TextHeight( 'TT' );
which returns 16.5 which is far from correct text height (it's actually about 30) on FireMonkey - Android/iOS.
How to get the actual Text Height under Firemonkey platform / Delphi XE6 ?
It sounds like you're using devices with high-resolution displays.
Try multiplying the TextHeight by the Canvas.Scale property, and see if you get anything closer to what you expect.
I'm trying to center vertically and horizontally a label in a vertical field manager. I have succeeded to center it horizontally but not vertically. The problem is that none of the style constants I've tried (Field.FIELD_VCENTER, DrawStyle.VCENTER etc.). I get the debugger for BlackBerry JRE 6 and I develop for Bold 9900 device. Can anyone help?
VerticalFieldManager vfm_listeAeroport=new VerticalFieldManager (USE_ALL_WIDTH){
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(2*Display.getWidth()/3,70);
setExtent(2*Display.getWidth()/3,70);
}
protected void paint(Graphics g){
super.paint(g);
setBackground(BackgroundFactory.createSolidBackground(0xefc94c));
}
};
String mText = "Liste des AĆ©roports";
LabelField Label = new LabelField(mText,Field.FIELD_HCENTER) {
public void paint(Graphics graphics){
graphics.setColor(0xffffff);
super.paint(graphics);
}
};
vfm_listeAeroport.add(Label);
add(vfm_listeAeroport);
Thanks!
DrawStyle.VCENTER will center the text within the label, not within it's manager. Eg, the labelfield may have a height of 50px and the manager 100px, DrawStyle will center in the 50px.
I think FIELD_VCENTER is not working because it's within a VerticalFieldManager.
In this case I would just set a margin for the label.
int margin_top = (Display.getHeight() - label.getPreferredHeight()) / 2;
int margin_left = (Display.getWidth() - label.getPreferredWidth()) / 2;
label.setMargin(margin_top,0,0,margin_left);
Just commenting on Kevin's suggested solution that positions the label by using margins and sets the margins based on the Screen height and width.
Kevin is 100% correct. VerticalFieldManager only takes up as much vertical space as is needed, not the whole screen. Use setBackground to set a different background colour to see this in operation.
Kevin's solution makes the size of the contained label bigger, so now the VFM will take up more space.
You do not need to use Kevin's solution to set the left and right Margin - as you have already seen, VFM will centre things horizontally using Field_HCENTER.
The problem with Kevins' solution, and in fact with any solution that attempts to guess how much space is required, is that it will fail when there are other things on the screen, for example a Title area or Banner. The issue is the use of Display.getHeight(), which gets the actual height required, rather than the 'free' space on the screen.
The only time when you know the free space, is when the Field is being laid out. Managers do this in their sublayout() method. So to create a generic 'centring' manager, you need to understand how to create a Manager. You will also need to know a little more about MainScreen and its internal processing. To this end, I recommend the following KB articles from the official BB site:
Custom Manager
Extend Manager
MainScreen explained
I'm learning Corona SDK and am new to lua as well (i mainly do ruby and some javascript).
I have a bar that i want to fill up as the user does stuff. I've set it up as follows:
--outer rectangle
powerBar = display.newRect(210, 6, 24, 9)
powerBar.strokeWidth = 1
powerBar:setStrokeColor(254,203,50)
powerBar:setFillColor(0,0,0,0)
--inner rectangle which fills up
powerBarFill = display.newRect(211,7,0,7)
powerBarFill:setFillColor(234,183,30)
When the "stuff" happens, i add 1 to powerBarFill.width, which i thought would make it grow from left to right. But, it's actually growing out from the centre, ie its x is in the centre and the width extends either side from that.
Whats the best way to keep the left side static and grow the right side? Can i set it so that it's x position is actually on the left hand side rather than in the middle? Seems like that might do it.
cheers in advance
I've run into this problem as well when creating a progress bar. The problem is with the rect's reference point. The default reference point is in the center of an object, as you've noticed. You can use object:setReferencePoint() to change it. I believe you want to use the display.BottomLeftReferencePoint value:
powerBar:setReferencePoint(display.BottomLeftReferencePoint)
Keep in mind that you have to set this value before you set your x,y values. So in your case you'll need to set the reference point after creating the rectangle, and then assign values to x,y again (even though you already did this in the newRect constructor):
powerBar = display.newRect(210, 6, 24, 9)
powerBar:setReferencePoint(display.BottomLeftReferencePoint)
powerBar.x, powerBar.y = 210, 6
If it's width is from the X position on both sides:
1) It should start at:
Centre - (Width when it's full / 2)
2) Every frame, add:
incrs = 1 --Amount to increase by
width = width + incrs
x = x + incrs / 2
I've been trying to layout fields in blackberry and when I think I have it working I try another simulator and my field's are laid out differently.
If I call setPositionChild(field, 0, 100); I would expect on all phone resolutions that
the fields would be positioned at position x=0, y=100. This is not the case.
Reading the RIM doc for setPositionChild, the y parameter is - "y - Offset of the top of the field in its manager." The y offset returned by field.getTop is consistently 0, so position should be consistent across screens? Maybe a good explanation of how setpositionChild works would suffice.
Thank you.
I suspect your variable results are from extending MainScreen. That class contains separators etc that will be offsetting your 0,100 to something else.
Either try using FullScreen which is a single VerticalFieldManager
Or override sublayout on your MainScreen and set its width and height to the full size of the display.