How to set the background color of an enaml window? - enaml

I am trying to use enaml for creating the view for my application. I would like to know how to set the background color of the Window widget. I see that I can use a stylesheet for setting colors for things that are inside the window, but I can't seem to find a way to set the color of the window.
enamldef Main(MainWindow):
StyleSheet:
Style:
element = 'PushButton'
Setter:
field = 'background'
value = 'indianred'
title << ""
initial_size = (1000,500)
initial_position = (300,150)
icon = loadIcon(normpath('TitleIcon.png'))
visible = True
always_on_top = True
style_class << "WindowStyle"
MyMenuBar:
pass
Container:
#constraints = [vbox(label, label, spacing=0)]
PushButton:
text = "one"
pass

You just have to style the correct element:
enamldef Main(MainWindow):
StyleSheet:
Style:
element = 'Main'
Setter:
field = 'background'
value = 'indianred'
Container:
PushButton:
text = "one"

Related

Removing background image from label in tornadofx

I have two css classes on a tornadofx label bound to a SimpleBooleanProperty. One which has a background image and a blue border and one which has no background image and a yellow border.
Snippet from View containing label:
val switch: SimpleBooleanProperty = SimpleBooleanProperty(false)
label("my label"){
toggleClass(UIAppStyle.style1, switch.not())
toggleClass(UIAppStyle.style2, switch)
}
Snippet from UIAppStyle:
s(style1){
textFill = Color.YELLOW
maxWidth = infinity
maxHeight = infinity
alignment = Pos.CENTER
backgroundImage += this::class.java.classLoader.getResource("img.png")!!.toURI()
backgroundPosition += BackgroundPosition.CENTER
backgroundRepeat += Pair(BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT)
borderColor += box(Color.BLUE)
}
s(style2){
textFill = Color.YELLOW
maxWidth = infinity
maxHeight = infinity
alignment = Pos.CENTER
borderColor += box(Color.YELLOW)
}
When switch = false, there is a background image and a blue border. When switch = true, there is the same background image and a yellow border. I'm not finding out how to get the background image to remove. Interestingly enough, if I add a different background image to style2, it changes correctly.
Edit: To remove two toggleClasses and introduce new strange problem:
class MyView : View(){
...
init{
...
row{
repeat(myviewmodel.numSwitches){
val switch = myviewmodel.switches[it]
val notSwitch = switch.not()
label("my label"){
addClass(UIAppStyle.style2)
toggleClass(UIAppStyle.style1, notSwitch)
}
}
}
}
This code snippet does not work for me. However, if I add private var throwsArray = mutableListOf<ObservableValue<Boolean>>() as a field of MyView and add notSwitch to the array, then the same exact code works. It's almost as if notSwitch is going out of scope and becoming invalidated unless I add it to a local array in the class?
I don’t understand why you want to have two different toggleClass for the same control. As you pointed out, the problem in your case is that when the backgroundImage is set, you need to set a new one in order to change it. But in your case, you only have to add the style without backgroundImage first and them set toggleClass with the style with backgroundImage. Like this:
label("my label"){
addClass(UIAppStyle.style2)
toggleClass(UIAppStyle.style1, switch)
}
button {
action {
switch.value = !switch.value;
}
}
Edit: This ilustrate what I'm talking about in comments:
class Example : View("Example") {
override val root = vbox {
val switch = SimpleBooleanProperty(false)
val notSwitch = switch.not()
label("my label"){
addClass(UIAppStyle.style2)
toggleClass(UIAppStyle.style1, notSwitch)
}
button("One") {
action {
switch.value = !switch.value;
}
}
button("Two") {
action {
notSwitch.get()
}
}
}
}
You can put the notSwitch.get() in any action and without trigger that action it does the work. Check how I put it in the action of button Two, but without clicking that button even once, it works.
This is actually some kind of hack, in order to achieve what you want. But I don’t see the reason why my initial solution with true as default value for property shouldn’t work.
Edited to do inverse of status
Here is simple example of a working toggle class using your styling:
class TestView : View() {
override val root = vbox {
val status = SimpleBooleanProperty(false)
label("This is a label") {
addClass(UIAppStyle.base_cell)
val notStatus = SimpleBooleanProperty(!status.value)
status.onChange { notStatus.value = !it } // More consistent than a not() binding for some reason
toggleClass(UIAppStyle.smiling_cell, notStatus)
}
button("Toggle").action { status.value = !status.value }
}
init {
importStylesheet<UIAppStyle>()
}
}
As you can see, the base class is added as the default, while styling with the image is in the toggle class (no not() binding). Like mentioned in other comments, the toggleClass is picky, additive in nature, and quiet in failure so it can sometimes be confusing.
FYI I got to this only by going through your github code and I can say with confidence that the not() binding is what screwed you in regards to the toggleClass behaviour. Everything else causing an error is related to other problems with the code. Feel free to ask in the comments or post another question.

xamarin forms: button text wrap

I tried to text wrap in a button inside a grid, but only the first line appears, the code is:
grid.Children.Add(new Button {
Text = la[0].Floor,
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
BorderWidth = 1,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.CenterAndExpand,
} , column, row );
You probably need to change your Grid.RowDefinitions's Height to Auto for what ever row that button is being placed on. Using Auto instead of GridUnitType.Star should give the Button as much height as it needs to show it's content.
That being said, if the text is super long, it still might not work.
If that button is on the first row, then your would change that row's Height to:
Grid grid = new Grid {
RowDefinitions = new RowDefinitions {
new RowDefinition { Height = GridLength.Auto }
}
}
If that does not help, please show your Grid's initialization code.

Is it possible to set column name dynamically on a dojo grid?

Is there any way to set a dynamic name for column header, for example in a formatter function!?
I'll have a popup menu on the grid and depending on the chosen option it should change the name displayed in the column header.
Its quite easy if you use dojo.query
var grid = dijit.byId('myGridId'), NewHeader = "Foo Bar Text Content";
var columnHeaderNodes = dojo.query(
'.dojoxGridHeader table th',
grid.viewsHeaderNode)
var nthColumn = 12;
// if has child and its not a textnode - this may happen
// when there is a listener (dnd, click) attached for sorting etc.
if(columnHeaderNodes[nthColumn].firstChild && columnHeaderNodes[nthColumn].firstChild.nodeType != 3)
tgt = columnHeaderNodes[nthColumn].firstChild;
else tgt = columnHeaderNodes[nthColumn];
tgt.innerHTML = NewHeader;

cObject in Typolink assigned with border-content

Basically, I (think I ) need to know how to assign borderContent to a cObject, when it is a typolink parameter.
To tell the whole story: I'm using perfect lightbox, and I want it to open the lightbox when a text is clicked, and display the images that are in a single content element in the border section.
Looking through the manual, i found this code:
page.20 = TEXT
page.20.value = Open an image in a lightbox
page.20.typolink {
title = This is my caption
parameter.cObject = IMG_RESOURCE
parameter.cObject = fileadmin/image2.jpg
parameter.cObject.file.maxW = 600
parameter.cObject.file.maxH = 600
ATagParams = rel="lightbox[mySet]"
}
which is working fine. But I don't want the path to be hard set, but the content to be loaded from the border section, as I said. But if I try the following:
page.20 = TEXT
page.20.value = Open an image in a lightbox
page.20.typolink {
title = This is my caption
parameter.cObject = IMG_RESOURCE
parameter.cObject < styles.content.getBorder
parameter.cObject.file.maxW = 600
parameter.cObject.file.maxH = 600
ATagParams = rel="lightbox[mySet]"
}
the link is gone.
So I GUESS I'm assigning the content wrong. Somebody knows the answer?
Thanks!
(If of any help, I use automaketemplate..)
Assigning styles.content.getBorder will just assign the full content elements from the border column. This will not get you anywhere.
You will need to manually load the content elements from the border column, of course this can be done with TypoScript. It should be something like this:
page.20 = TEXT
page.20 {
value = Open an image in a lightbox
typolink {
ATagParams = rel="lightbox[mySet]"
title = This will be the title attribute
parameter.cObject = CONTENT
parameter.cObject {
table = tt_content
select {
pidInList = this
where = colPos = 3
}
renderObj = IMG_RESOURCE
renderObj.file {
import = uploads/pics
import.field = image
import.listNum = 0
width = 600
height = 600
}
}
}
}
Basically this will load all content elements on the border position from the current page. Render the first image in the list of images and return you the resource.

How do I enable a Text class to accept html text and will I be able to calculate height and width?

When showing the html I would need to know the height of the text box in order to align things below it properly.
In order to pass it html and have it rendered as such you would set the htmlText property instead of the text property. Once the text box has been added to the display list you can get it's height just like normal.
If you are trying to get the value of the height and width immediately after setting insance.htmlText, you are not going to get the calculated size of the container. You can add an event listener for FlexEvent.UPDATE_COMPLETE or force validation to do it synchronously and use getExplicitOrMeasuredHeight(). Be careful when forcing validation, it is expensive and does not necessarily need to be done in most cases. I've included a right and wrong way of making it synchronous that was not entirely obvious to me at first.
Wrong:
var container : Box = new Box;
var text : Text = new Text;
container.addChild(text);
text.htmlText = "<b>THIS IS A TEST</b>";
trace( text.getExplicitOrMeasuredHeight() > 0 ) // False
Right:
var container : Box = new Box;
var text : Text = new Text;
container.addChild(text);
text.htmlText = "<b>THIS IS A TEST</b>";
text.validateNow(); // Forces the validation methods to run and update the component
trace( text.getExplicitOrMeasuredHeight() > 0 ) // True

Resources