Libgdx Scene2d - Set actor ( TextField ) padding? - android

i have been having trouble setting padding or something similar to an actor. Cant figure out the way. I guess that I must add something in the skin maybe?
I have this TextField:
textboxskin = new Skin();
textboxskin.add("textfieldback", new Texture("data/textfieldback.png"));
textboxskin.add("cursor", new Texture("data/cursortextfield.png"));
textboxskin.add("selection", new Texture("data/selection.png"));
textboxskin.add("font", font);
TextFieldStyle textfieldstyle = new TextFieldStyle();
textfieldstyle.background= textboxskin.getDrawable("textfieldback");
textfieldstyle.disabledFontColor=Color.BLACK;
textfieldstyle.font=textboxskin.getFont("font");
textfieldstyle.fontColor=Color.WHITE;
textfieldstyle.cursor=textboxskin.getDrawable("cursor");
textfieldstyle.selection=textboxskin.getDrawable("selection");
textfieldusername = new TextField("username", textfieldstyle);
which looks like this:
As you can see it looks horrible left centered...

EDIT:
I tried to do the following and it worked in my tests:
textfieldstyle.background.setLeftWidth(textfieldstyle.background.getLeftWidth() + 10);
Searching the libgdx API I couldn't find a way to specify padding for the text inside the TextField component.
As a workaround, yout could copy the original TextField source and create a new TextField, with another name providing a way to implement the padding.
Copy the contents of the libgdx TextField (https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/scenes/scene2d/ui/TextField.java?source=cc)
to another file and call it MyTextField (as an example). Replace the broken TextField references with the new class name.
Create a new variable called paddingLeft, for example:
public float paddingLeft = 0.0f;
In the draw() method, you can add your padding to the sum to define a new position for the String. Where the code says:
font.draw(batch, displayText, x + bgLeftWidth + textOffset, y + textY + yOffset, visibleTextStart, visibleTextEnd);
replace with:
font.draw(batch, displayText, x + bgLeftWidth + textOffset + leftPadding, y + textY + yOffset, visibleTextStart, visibleTextEnd);
(notice the " + leftPadding" in the second code)
Then, if you are using skins, remember to reference your TextField in the uiskin.json file:
mypackage.MyTextField$TextFieldStyle: {
default: { selection: selection, background: textfield, font: default-font, fontColor: white, cursor: cursor }
}
and use it in your code:
MyTextField txtTest = new MyTextField("Test", skin);
txtTest.leftPadding = 10.0f;
This is not the ideal way, but will work.

Use the Table class to lay out scene2d UIs. To set up the Table:
stage = new Stage();
Table table = new Table();
table.setFillParent(true);
stage.addActor(table);
table.add(textFieldUsername).padBottom(20f); //also use padTop, padLeft, and padRight
table.row();
In the main loop, call:
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
For more information on tables, see: http://code.google.com/p/table-layout/

You could use a NinePatch. This separates your texture into nine "patches" you define their height and width, and then you give it to a NinePatchDrawable which you can give to a TextButton. I believe the outer "patches" act as margins and with some tweaking (not strenuous) it would look great and accomplish your goals.
I learned about them from this post:
Loading nine-patch image as a Libgdx Scene2d Button background looks awful

Related

StaticLabelsFormatter and setXAxisBoundsManual issue in Graphview

I am using Graphview in Android. Inside my graph, I am showing bargraph with some custom static labels.
If I am not manually adjusting the Xbounds, then static labels show up , but they are not placed at the middle of bar. Also the bars don't have proper spacing.
series.resetData(graphDataPoints.toArray(new GraphDataPoint[graphDataPoints.size()]));
StaticLabelsFormatter mLabelsFormatter = new StaticLabelsFormatter(graph);
mLabelsFormatter.setHorizontalLabels(horizontalLabels.toArray(new String[horizontalLabels.size()]));
mGridLabelRenderer.setLabelFormatter(mLabelsFormatter);
If I manually adjust Xbounds, then bars show up nicely, but the static labels are distorted. In my case one label doesn't show up.
series.resetData(graphDataPoints.toArray(new GraphDataPoint[graphDataPoints.size()]));
graph.getViewport().setXAxisBoundsManual(true);
graph.getViewport().setMinX(series.getLowestValueX() -0.5);
graph.getViewport().setMaxX(series.getHighestValueX() +0.5);
StaticLabelsFormatter mLabelsFormatter = new StaticLabelsFormatter(graph);
mLabelsFormatter.setHorizontalLabels(horizontalLabels.toArray(new String[horizontalLabels.size()]));
mGridLabelRenderer.setLabelFormatter(mLabelsFormatter);
Please help!
In my case the problem was that I created the DataPoints as DataPoint(i+1,y), so there was an offset in the horizontal direction. Then I put minX to 0 and maxX to NBRBARS+1 so that you could see everything of the bars.
To compensate for the labels I had to add one space " " on each side of the array, i.e. String labels[] = {" ", "label 1", "label 2", " "}.

Set ascent, descent, baseline of text in TextView

I need two TextViews to have same baseline, ascent, bottom, descent values. Is it possible to change the FontMetrics of TextView after text has been drawn?
It is so late, but I also confronted with this issue, and I solve with some tricks. (just modify baseline, not ascent, descent or something)
note that fontMetrics' values(ascent, descent, bottom, top) are depend on textSize.
so we must use fontMetrics' values after view is drawn. (if it is autoSizing or something)
to do something after view drawn, using Sa Qada's answer
baseline is always 0. descent, ascent, top, bottom is relative values.
refer this Suragch's answer.
change fontMetrics' values does not affect to UI.
to set custom baseline(text position of textview), just use padding.
below code is align to baseline with two TextView.
// this is kotlin code, but I'm sure you can understand
// align textview2 to textview1's baseline
val tv1Baseline = tv1.paddingBottom + tv1.paint.fontMetrics.bottom
val tv2Baseline = tv2.paddingBottom + tv2.paint.fontMetrics.bottom
val newPaddingOffset = tv1Baseline - tv2Baseline
tv2.setPadding(tv2.paddingLeft, tv2.paddingTop, tv2.paddingRight,
tv2.paddingBottom + newPaddingOffset)
Here's solution to align baselines (note the difference from bottom in Suragch answer and definition of return value of TextView.getBaseline()) which alignes tv2 baseline to tv1s':
private void alignWeatherTextBaseline(View tv1, View tv2) {
int tv1Baseline = tv1.getTop() + tv1.getBaseline();
int tv2Baseline = tv2.getTop() + tv2.getBaseline();
int newPaddingOffset = tv1Baseline - tv2Baseline;
if (newPaddingOffset != 0) {
tv2.setPadding(tv2.getPaddingLeft(),
tv2.getPaddingTop(), tv2.getPaddingRight(),
tv2.getPaddingBottom() - newPaddingOffset);
}
}
Be aware of the following:
if multiline text is possible, you need to write proper getLastLineBaseline() and use it instead of standard getBaseline()
you can get invalid value (0 or -1) from getBaseline() if a view hasn't been layout yet

resize/scale text dynamically in andengine

I created a simple game where move the objects from one place to another and each moves increment count of moves in score table. After all objects are moved correct I want set opacity to screen and slowly resizing score from initial size(e.g. 15px) to whole screen(e.g. 50px). I load font like this:
FontFactory.setAssetBasePath("font/");
final ITexture mainFontTexture = new BitmapTextureAtlas(activity.getTextureManager(), 256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
font = FontFactory.createStrokeFromAsset(activity.getFontManager(), mainFontTexture, activity.getAssets(), "font.ttf", 15, true, Color.WHITE, 2, Color.BLACK);
font.load();
In createScene() method I create HUD with text and I initial text:
Int mMoves = 0;
HUD gameHUD = new HUD();
Text mText = new Text(25, 25, font, "Moves: " + "123456789", getVertexBufferObjectManager());
And each moves set text with actual moves count:
mText.setText("Moves: " + mMoves++);
And when level was complete I don't know how can I resize this text. I mean something like scale with transition in CSS3..
Thanks for all comments
You can set the size of the text by using the setscale function.
If you just want to set the size use the following :
Example : mText.setScale(1.5f);
You can also use Entity modifiers to create an animation:
ScaleModifier scale = new ScaleModifier(1f, 1f, 1.1f);
LoopEntityModifier loop = new LoopEntityModifier(scale);
mText.registerEntityModifier(loop);
This will give a animation effect re-sizing the text in a loop.

scene2d button scaling with libgdx

I don't know if it is just me, but drawables confuse me. Are they intended to keep the size they are given, or is there a way to scale the image within them? I understand they can use ninepatch to fill certain areas by stretching an image, but I want to scale the image that it stretches. I am using a TextButton
for my menu buttons, but they are way too big, and I would love to know how to scale them. I am retrieving the skin from an atlas, which has ninepatch images in it.
Here is the settings screen:
Here are the images in the pack I am using:
Here is the initialization of the TextureAtlas, and Skin:
buttonAtlas = new TextureAtlas(Gdx.files.internal("buttons/buttons.pack"));
buttonSkin = new Skin(buttonAtlas);
Here is the initialization of that menu button.
TextButtonStyle textButtonStyle = new TextButtonStyle();
textButtonStyle.up = Assets.buttonSkin.getDrawable("bluebutton");
textButtonStyle.down = Assets.buttonSkin.getDrawable("redbutton");
textButtonStyle.font = font;
buttonMenu = new TextButton("Menu", textButtonStyle);
buttonMenu.pad(20.0f);
buttonMenu.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
game.fade.startFadeOut();
super.clicked(event, x, y);
}
});
And perhaps I could change how I put it in the table, or how I put the table in the stage?
table.add(buttonMenu).width(Gdx.graphics.getWidth()/4);
stage.addActor(table);
As a last resort I suppose I could attempt creating my own text button actor that I could scale, thank you for your time.
First of all if you know that your images are too big: The best would be to scale the images themselves to a smaller size and then use the TexturePacker too generate a new TextureAtlas that contain the smaller images.
Anyhow you can scale the image button with the TableLayout if you really want to, see example:
table.add(buttonMenu).width(100).height(100);
The above answer didnt work for me, but i have a solution.
You can make a secondary camera and attach it to your stage.
To scale the table just scale the viewport size of the secondary camera
An example would be:
//Heres where you set the scale of your buttons and your table
Camera secondaryCamera = new Camera(Gdx.graphics.getWidth() * scale,
Gdx.graphics.getHeight() * scale);
Stage stage = new Stage();
Table table = new Table();
ImageButton button = new ImageButton(drawableUp, drawableDown, drawableChecked);
table.setFillParent(true);
stage.getViewport().setCamera(secondaryCamera);
table.add(ImageButton);
stage.addActor(table);
This works great when your using it for touch controls. You can use a table for the entire UI and scale it to your liking independent of your other game items;
table.add(buttonMenu).width(100).height(100); should work, and you just need to adjust the width and height parameters to your liking, or you can use the setBounds method. Here is an example:
TextButton myButton = new TextButton("Press Me", style);
myButton.setBounds(xCoordinate, yCoordinate, width, height);
You can set size of Drawable in ButtonStyle to resize your Button:
float scale = 0.5f;
float currentHeight = textButtonStyle.up.getMinHeight();
textButtonStyle.up.setMinHeight(currentHeight * scale);
For more information, see official document for layout:
UI widgets do not set their own size and position. Instead, the parent widget sets the size and position of each child. Widgets provide a minimum, preferred, and maximum size that the parent can use as hints. Some parent widgets, such as Table and Container, can be given constraints on how to size and position the children. To give a widget a specific size in a layout, the widget's minimum, preferred, and maximum size are left alone and size constraints are set in the parent.
And you can find the implementation of Button.getPrefHeight() in the source code:
public float getPrefHeight () {
float height = super.getPrefHeight();
if (style.up != null) height = Math.max(height, style.up.getMinHeight());
if (style.down != null) height = Math.max(height, style.down.getMinHeight());
if (style.checked != null) height = Math.max(height, style.checked.getMinHeight());
return height;
}

Android button not resizing when put in table programmatically

I need to change the size (specifically the height) of a button in an Android app where the button resides in a table and is created programmatically. I have tried about 20 different approaches and failed miserably. If I create a button outside the table, I can change the size without a problem, but as soon as it goes in a table, the height stays fixed even though I can change the width.
I have tried creating and using, LinearLayout params, ViewGroup layout params, TableLayout params, etc. and setting their heights either via that constructor (e.g WRAP_CONTENT) or using setHeight(). I have also tried simply calling button.setHeight(). I have changed settings in my xml manifest for the table as well. I have used pixel values and Dpi values. All of this has failed. Here is the basics of what I have so far (just showing a call to b.setHeight()):
TableRow row = new TableRow(getApplicationContext());
row.setId(counter);
TextView t = new TextView(getApplicationContext());
t.setText("BLH " + counter);
t.setTextColor(Color.BLACK);
//I have also tried table.getContext() in this constructor...
Button b = new Button(getApplicationContext());
b.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v)
{
//blah blah blah
});
//Convert from pixels to Dpi
final float scale = getResources().getDisplayMetrics().density;
int heightDp = (int) (33 * scale + 0.5f);
int widthDp = (int) (60 * scale + 0.5f);
b.setText(R.string.removeButtonText);
b.setTextSize(12);
b.setTag(counter);
b.setHeight(heightDp);
b.setWidth(widthDp);
b.setId(counter);
counter++;
row.addView(t);
row.addView(b);
// add the TableRow to the TableLayout
table.addView(row,new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
This correctly results in a button being placed in the table, but the height does not change no matter what values I use. In my xml file, here is what the table declaration looks like:
<TableLayout
android:id="#+id/myTable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:stretchColumns="0">
</TableLayout>
I have tried messing with stretchColumns and other settings here; again, to no avail. Does anyone have any idea why I can't change the height of a button added to my table programmatically, but have no problems doing so outside the table? I am sure it is some setting or adjustment that I just haven't found. Any help is appreciated as I am at my wits end. Thanks in advance.
I fixed my problem. Turns out it was an ordering issue. The problem is that I was setting the height before adding the button to the table. This caused the button's LayoutParams to not have any parent as explained here: ViewGroup.getLayoutParams(). Here is what I needed to do (basically, change height after adding the button to the table):
table.addView(row,new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
//now change the height so the buttons aren't so big...
final float scale = getResources().getDisplayMetrics().density;
int heightDp = (int) (33 * scale + 0.5f);
ViewGroup.LayoutParams params = b.getLayoutParams();
params.height = heightDp;
b.setLayoutParams(params);
b.requestLayout();
table.requestLayout();
The last two lines were suggested above by Lawrence. The table and button seemed to update without these. However, it seemed to me to be a good idea to update just in case.
Try this
int heightDp = (int) (33 * scale + 0.5f);
int widthDp = (int) (60 * scale + 0.5f);
ViewGroup.LayoutParams bLp = new ViewGroup.LayoutParams(widthDp,heightDp);
b.setLayoutParams(bLp);
instead of
b.setHeight(heightDp);
b.setWidth(widthDp);
I think you need to call View.requestLayout, this is not done automatically every time you add/remove child views.

Categories

Resources