How to programmatically correctly set drawable padding on button? - c#

I'm having trouble setting the padding for a button to center the content (text + drawable).
Here is where I've gone so far:
Button done = new Button(this)
{
Text = GetText((int)typeof(Resource.String).GetField("goalreached").GetValue(null))
};
done.LayoutParameters = doneButtonParams;
done.SetBackgroundResource(Resource.Drawable.DoneGreenYakaButton);
done.Typeface = Typeface.CreateFromAsset(Assets, "fonts/Ubuntu-Medium.ttf");
done.SetTextColor(Color.White);
done.SetTextSize(Android.Util.ComplexUnitType.Sp, 12);
doneButtonParams.ColumnSpec = GridLayout.InvokeSpec(0, 2); // Setting colspan = 2
var check = GetDrawable(Resource.Drawable.ic_check_16px);
check.SetBounds(0, 0, 32, 32); // Set the image size
check.SetTint(Color.White); // Set the image color
done.SetCompoundDrawables(null, null, check, null);
The result is this:
Obviously I want the check mark to be nearer the text and have the same padding as the one for the text on the left of the button.
What Am I missing here ?
Thanks in advance.

I'm not familiar with xamarin for mobile development but the native Android way of doing this is setting the drawable padding on the button itself. setCompoundDrawablePadding(int) is the native method to accomplish adjusting the distance between text and the drawable.
Ex:
done.setCompoundDrawablePadding(15);
Edit: I realized you are looking to add padding on the outside of the checkmark, this would be accomplished with plain old setPadding(int, int, int, int).
Ex:
setPadding(0,0,15,0);

Related

How to create a smooth animated text marquee?

I know that there are lot of different threads about horizontal text animation/text scrolling, but unfortunately none of them give smooth scrolling with repeatable text. I have tried double/thickness animation using various WPF controls containing text. Also tried animating with visual brush which gives me by far the most elegant scrolling compared to other approaches (for e.g. playing with Canvas.Left property etc.) but that too goes blur the text, if the text length or the animation speed is too high.
I'm over to a pure DirectX C# implementation using SharpDX library. Should also mention that I'm a beginner with DirectX programming. Here is the code:
public void RunMethod()
{
// Make window active and hide mouse cursor.
window.PointerCursor = null;
window.Activate();
var str = "This is an example of a moving TextLayout object with no snapped pixel boundaries.";
// Infinite loop to prevent the application from exiting.
while (true)
{
// Dispatch all pending events in the queue.
window.Dispatcher.ProcessEvents(CoreProcessEventsOption.ProcessAllIfPresent);
// Quit if the users presses Escape key.
if (window.GetAsyncKeyState(VirtualKey.Escape) == CoreVirtualKeyStates.Down)
{
return;
}
// Set the Direct2D drawing target.
d2dContext.Target = d2dTarget;
// Clear the target.
d2dContext.BeginDraw();
d2dContext.Clear(Color.CornflowerBlue);
//float layoutXOffset = 0;
float layoutXOffset = layoutX;
// Create the DirectWrite factory objet.
SharpDX.DirectWrite.Factory fontFactory = new SharpDX.DirectWrite.Factory();
// Create a TextFormat object that will use the Segoe UI font with a size of 24 DIPs.
textFormat = new TextFormat(fontFactory, "Verdana", 100.0f);
textLayout2 = new TextLayout(fontFactory, str, textFormat, 2000.0f, 100.0f);
// Draw moving text without pixel snapping, thus giving a smoother movement.
// d2dContext.FillRectangle(new RectangleF(layoutXOffset, 1000, 1000, 100), backgroundBrush);
d2dContext.DrawTextLayout(new Vector2(layoutXOffset, 0), textLayout2, textBrush, DrawTextOptions.NoSnap);
d2dContext.EndDraw();
//var character = str.Substring(0, 1);
//str = str.Remove(0, 1);
//str += character;
layoutX -= 3.0f;
if (layoutX <= -1000)
{
layoutX = 0;
}
// Present the current buffer to the screen.
swapChain.Present(1, PresentFlags.None);
}
}
Basically it creates an endless loop and subtracts the horizontal offset. Here are the challenges: I need repeatable text similar to HTML marquee without any gaps, Would probably need to extend it to multiple monitors.
Please suggest.
I don't know neither how to use DirectX nor sharpdx, but if you want you can consider this solution
I had a similar problem a while ago, but with the text inside a combobox. After a bounty i got what i was looking for. I'm posting the relevant piece of code as an example, but you can check the complete answer here
Basically, whenever you have a textblock/textbox that contain a string that cannot be displayed completely, cause the length exceed the textblock/box lenght you can use this kind of approach. You can define a custom usercontrol derived from the base you need (e.g. SlidingComboBox : Combobox) and define an animation for you storyboard like the following
_animation = new DoubleAnimation()
{
From = 0,
RepeatBehavior = SlideForever ? RepeatBehavior.Forever : new RepeatBehavior(1), //repeat only if slide-forever is true
AutoReverse = SlideForever
};
In my example i wanted this behaviour to be active only when the mouse was on the combobox, so in my custom OnMouse enter i had this piece of code
if (_parent.ActualWidth < textBlock.ActualWidth)
{
_animation.Duration = TimeSpan.FromMilliseconds(((int)textBlock.Text?.Length * 100));
_animation.To = _parent.ActualWidth - textBlock.ActualWidth;
_storyBoard.Begin(textBlock);
}
Where _parent represent the container of the selected item. After a check on the text lenght vs combobox lenght i start the animation and end it at the end of the text to be displayed
Note that in the question i mentioned there are also other soltions. I'm posting the one that worked for me

how to fit a long text into a UITextView or UILabel

i'm developing an ios app with xamarin.
i need to fit a long text into a content (UILabel or UITextView).
this is the code i used:
var descStrLabel = new UITextView(new CGRect(0, 250, w, 550));
descStrLabel.BackgroundColor = UIColor.Black;
descStrLabel.Font = UIFont.SystemFontOfSize(10.0f);
descStrLabel.TextAlignment = UITextAlignment.Center;
descStrLabel.TextColor = UIColor.LightGray;
descStrLabel.Text = #"HERE THE LONG TEXT...";
//descStrLabel.Lines = 0;
descStrLabel.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
View.Add(unified);
View.Add(subtitle);
View.Add(descStrLabel);
When i debug the application, the last part of the text is missing...
maybe i need to set the width at runtime...
thanks in advance for your help
I don't really know how you want to "fit" the text. If you want to show the text all in one line, try calling SizeToFit():
desc.SizeToFit();
documentation for SizeToFit():
Moves and resizes the UIView so that it tightly encloses its UIView.Subviews
If you want the UITextView to wrap lines, then you don't need to do anything! Line wrapping is enabled by default. If it doesn't for you, try setting LineBreakMode:
desc.TextContainer.LineBreakMode = UILineBreakMode.WordWrap;
documentation for WordWrap:
Wraps at the first word that does not fit.

MonoTouch.Dialog Image only cell

I'am working on a app where the user can put in some data and then take a image with the camera or from the device.
The problem i'am having is that i cant seem to get a cell or element to only display a image.
Width of the image would be the width of the cell(Grouped style) it's in. Height i would like to specify myself.
I've tried to subclass ImageElement but can't change the size of it.
Is the already a Element i could use for this or is there any other good way of doing it?
Try to use the UIViewElement with an UIImageView:
var imageView = new UIImageView(new RectangleF(0, 0, 300, 100));
imageView.ContentMode = UIViewContentMode.Center;
var element = new UIViewElement(String.Empty, imageView, true);

Label with an Image on the left - preventing the text to come over the picture?

I want to report status of an operation in a WinForm application written in C#.
To make it more user-friendly, I want to show an icon on the left depending on the status.
Animated GIF during the process
Ok or Error icon depending on the result.
I wanted to use the native WinForms Label control which works well with animated GIFs and looks as standard as it can get.
My problem however is that text comes is written over the picture.
There does not seem to be any property to set a margin for the text.
I tried the most obvious thing, which is to prefix it with spaces, which works, except when the text wraps to the next line, as shown below.
I would prefer not spend too much time writing/testing/debugging derived control for this if possible...
I could put a quick and dirty user-control, with a picturebox on the left of a label, but it doesn't feel very clean.
Is there any trick to get around this quickly and elegantly, or can someone point me to a Label derived class supporting this that is relatively lightweight? (I had a look at CodeProject but couldn't find much).
Thank you.
A simple alternative is to use a Button instead of a Label, as shown below:
By using the following properties, you can style the Button to look just like a Label, whilst also having the option to keep the image and text aligned next to eachother:
FlatAppearance ↴
BorderSize = 0
MouseDownBackColor = Control
MouseOverBackColor = Control
FlatStyle = Flat
Image = [Your image]
ImageAlign = MiddleLeft
Text = [Your text]
TextAlign = MiddleLeft
TextImageRelation = ImageBeforeText
A simple way to achieve the desired effect; no user controls!
The quick-and-dirty usercontrol with an image and a separate label is your best option. Just add a public string property to set the label's text and you're pretty much done.
Here's a different solution that I find less hacky than the "styled button" approach. It also allows you to set the distance (spacing) between the image and the text.
class ImageLabel : Label
{
public ImageLabel()
{
ImageAlign = ContentAlignment.MiddleLeft;
}
private Image _image;
public new Image Image
{
get { return _image; }
set
{
const int spacing = 4;
if (_image != null)
Padding = new Padding(Padding.Left - spacing - _image.Width, Padding.Top, Padding.Right, Padding.Bottom);
if (value != null)
Padding = new Padding(Padding.Left + spacing + value.Width, Padding.Top, Padding.Right, Padding.Bottom);
_image = value;
}
}
protected override void OnPaint(PaintEventArgs e)
{
if (Image != null)
{
Rectangle r = CalcImageRenderBounds(Image, ClientRectangle, ImageAlign);
e.Graphics.DrawImage(Image, r);
}
base.OnPaint(e); // Paint text
}
}
One alternative to a UserControl would be to use a TableLayoutPanel with two columns and one row, placing the image control in one cell and the text control in the other.
Its an old question, but maybe someone will look here just like I got here...
You can use the Align on the Image and on the text:
label.TextAlign = ContentAlignment.MiddleRight;
label.ImageAlign = ContentAlignment.MiddleLeft;
nameoftextlabel.hidden=1
That should work.

how to get a labels width before it is rendered in WPF

Tricky one to explain this. I have a custom built properties grid. The left hand column has the property labels. Sometimes depending on the property, I want a little elipsis button to show the user that they can launch a dialog. I want the buttons to be inline vertically to make the UI look neat. The labels vary in width depending on the name of the property "onEnterPressed" or "upLink" for example.
If I add the elipses button alone and use a margin like so ...
elipsisButton.Margin = new Thickness(135, 0, 0, 0);
135 from the left is exactly where I want to place the button.
I was hoping to be able to do something like
Label newLabel = new System.Windows.Controls.Label();
newLabel.Content = anInfo;
aPanel.Children.Add(newLabel);
elipsisButton.Margin = new Thickness(135 - newLabel.Width, 0, 0, 0);
It would appear however, that the label doesn't get a width until it's been rendered on screen so I can't find out what size margin to add to my elipsis button. Any ideas?
You can call the Measure() method in order to ask the control the size it needs to be displayed:
var l = new Label() { Content = "Hello" };
l.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
Size s = l.DesiredSize;
And then use the value of the DesiredSize property.

Categories