I would like to have a button in Perspective where I can have text in multiple places and the text will grow and shrink with content. There would be a left middle justified text, right middle justified text, and then also a bottom right justified text.
A couple of ideas:
- create a coordinate view with labels over the top of the button. This has proven to be difficult to get the labels and buttons to grow with the text. Maybe I am missing how to calculate the size of the labels based on the string sent in.
- use a flex view and create several buttons right next to each other vertically. I feel like this will auto size a lot better then one, but it looks bad when a user clicks a button because only part of the button changes color on the click.
What you want to do is avoid the Button entirely.
- Create a new View with a Coordinate container as the root.
root.props.mode to “percent”
- Modify the style of the root to approximate the appearance of your desired “default” button. I recommend including a border radius modification and at least a background color.
- Place a Label into the root container, and set position the position to be
x=0, y=0.4, width=0.4, height=0.2. Follow this up with a change to the textAlign property of the Label so that it is aligned to the left.
- Repeat the Label steps for your other desired text positions, modifying the alignment as necessary.
- Create a new Perspective Named Style which contains the desired style changes for when a user hovers over your “button”.
- Create a second named style to be used when a user depresses a mouse button on your button.
- Right click the Root layer of the View and select “Configure Events”.
- Create a onMouseEnter Event and an accompanying Script Action. Configure the script to set
self.props.style.classes to the name of your hover class.
- Create an onMouseExit Event and an accompanying Script Action. Configure this action to set
self.props.style.classes to an empty string (
'') - this will remove the hover class from the previous step when a user leaves the “button”.
- Create an onMouseDown Event and apply your “click” named style to
- Create an onMouseUp Event and set
self.props.style.classes to the hover named style (you don’t want to use the empty string solution here because a user is 99% of the time still going to be hovering over your “button”.
You’ll need to get creative in applying a text size which will update as your element grows, but this percent layout will hold your alignments as the button changes size and allow you to style it as you’d like as well.
I did a flex container with a style class (on the root container, crucially) - the meta props are what you’re after:
I went with a flex container and the style containing element states of hover and active. I assigned the style to the root container style classes. Then I put my action code on the root container’s onClick event. Everything seems to work just like it was a real button.
Thanks for the help.
So I've used this method to create buttons that stylistically reflect what I want from my project, unfortunately since these flex containers aren't input elements I can't tab to them and use purely keyboard commands to access them. Is there a way around this without having to go back to the default button? This is compounded by the fact that the action is based off of explicitly a click action and so something like enter or the spacebar wouldn't work if I could tab to them in the first place. I feel like I'm looking for something like a generic input container that I could define my own view from, that would be tab-able and have the action performed listener as an option
I guess you could make it a coordinate container and overlay the whole thing with an invisible button ?
Not the cleanest solution but clean things are not a common sight in web development anyway
But even with that you would lose the visual indication that you were tabbed over it so in my case where I have a column of "faux-buttons" it would be neigh impossible to know which one is currently under selection.
Just push the dirty one step further and make a style class for the button to give it a transparent background, and a border on focus.
Obviously, make sure to remove the text of the button.
bonus effect: now it has an
onActionPerformed event !