TLDR; When trying to change the background color of a listview using inline CSS with style { ... } it works but addClass using a copy-pasted CSS does nothing.
The following code (using inline CSS) works:
listview(monsterController.monsters) {
vgrow = Priority.ALWAYS
cellFormat {
// addClass(StatBlockStyles.monsterListCell)
style {
backgroundColor += Color.color(253.0 / 255.0, 241.0 / 255.0, 220.0 / 255.0)
}
graphic = label(it.name)
}
But if I comment the style { ... } and uncomment the addClass(...) it seems to have no effect.
The CSS class is a literaly copy-paste of the inline CSS:
import javafx.scene.paint.Color
import tornadofx.*
class StatBlockStyles: Stylesheet() {
companion object {
val monsterListCell by cssclass()
}
init {
monsterListCell {
backgroundColor += Color.color(253.0 / 255.0, 241.0 / 255.0, 220.0 / 255.0)
}
}
}
Why does this happen and what should I do to be able to actually separate the styling from the rest of the code?
Try adding this to your init section of the view/fragment containing your listview:
init {
importStylesheet(StatBlockStyles::class)
}
Note: You only need to use the import function once. The styling will remain for the rest of the program, even in other windows/views/fragments.
Related
I have created a directive and using HostListner , want to add a CSS style on Click event on the tag.Also remove on the click again.I have the following CSS .
CSS
.strikethrough { text-decoration: line-through;}
HTML
<p optionalIngredient>ABCD</p>
Directive
constructor(private elRef: ElementRef ,private renderer: Renderer2)
{ }
#HostListener('mouseenter') onMouseEnter() {
this.renderer.addClass(this.elRef.nativeElement, 'strikethrough');
}
#HostListener('mouseleave') onMouseLeave() {
this.renderer.removeClass(this.elRef.nativeElement,strikethrough');
}
You can use a boolean to keep track of whether the style is applied.
styled = false;
#HostListener('click')
onClick(){
if (!styled) this.renderer.addClass(this.elRef.nativeElement, 'strikethrough');
else this.renderer.removeClass(this.elRef.nativeElement, 'strikethrough');
this.styled = !this.styled;
}
I've installed svg.js using NPM and imported the module into my custom element file via import "svg.js";,
import "svg.js";
class MyView2 extends PolymerElement {
static get template() {
return html`
<div id="drawing"></div>
`;
}
connectedCallback() {
super.ready();
var draw = SVG("drawing").size(300, 300);
var rect = draw.rect(100, 100).attr({ fill: "#f06" });
}
}
This should insert an SVG inside of the div, but is it's throwing this error in the console instead:
svg.js:3060 Uncaught TypeError: Cannot read property 'nodeName' of null
at new create (svg.js:3060)
at globalRef.SVG (svg.js:33)
at HTMLElement.connectedCallback (my-view2.js:42)
at my-view2.js:50
I'm fairly new to Polymer so not sure if i'm missing something obvious.
Your component has a Shadow Dom so SVG can't find it. Please try this:
let node = this.shadowRoot.querySelector('drawing');
let draw = SVG.adopt(node);
let rect = draw.rect(100, 100).attr({ fill: "#f06" });
I have got my themes all working perfectly, but for some reason my mat-menu will only get themed on whatever default is called and not otherwise.
So for its theme to not be broken I have to call
#include angular-material-theme($dark-theme);
right at the top of my styles.scss and then have my custom classes that I set, which my light is loaded by default as shown here:
import {OverlayContainer} from "#angular/cdk/overlay";
#Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.scss']
})
export class NavbarComponent implements OnInit, AfterViewInit {
title:string = "Callum.Tech";
themeClass: string = "light-theme";
overlay;
constructor(
private overlayContainer: OverlayContainer
) {
this.overlay = overlayContainer;
}
setDarkTheme(): void {
this.themeClass = "dark-theme";
}
setLightTheme(): void {
this.themeClass = "light-theme";
}
ngOnInit() {
this.overlay.themeClass = this.themeClass;
}
}
Everything else will re-theme and work fine without calling the start include I mentioned but mat-menu will throw a fit and only use the first theme its fed on the site launching, and doesnt change with the rest of the theme.
Here is what it looks like with the dark theme called at the start of styles.scss and the light theme loaded like normal
And here is the dark theme chosen, but the dark theme not called at the start of styles.scss:
In the breaking changes for 2.0.0-beta.11:
overlay: Now that the Overlay is part of the cdk rather than Angular Material directly, the themeClass property has been removed. To add a class to the overlay for theming, you can do
overlayContainer.getContainerElement().classList.add('my-theme-class');
So, you can change your code as follows:
constructor(
private overlayContainer: OverlayContainer
) {
this.overlay = overlayContainer.getContainerElement();
}
toggleTheme(): void {
if (this.overlay.classList.contains("dark-theme") {
this.overlay.classList.remove("dark-theme");
this.overlay.classList.add("light-theme");
} else if (this.overlay.classList.contains("light-theme") {
this.overlay.classList.remove("light-theme");
this.overlay.classList.add("dark-theme");
} else {
this.overlay.classList.add("light-theme");
}
}
ngOnInit() {
this.toggleTheme();
}
In a GWT application i am declaring the .css styles inside the UiBinder (ui.xml)
For example:
<ui:Style>
.input {
background:green;
}
</ui:Style>
And if i declare a Widget inside the UiBinder i reference the Style i was like below:
<g:Button styleName="{Style.input}"/>
which is fine.
My problem is that i want to apply that style in a Widget that i add at run time. For example a text box:
TextBox box = new TextBox();
box.setStyleName("input");
I have tried all the possible compinatations (e.g. "input", "{Style.input}"), but without any luck. I know that GWT compiles the styles inside a UiBinder file so the Widgets end up with something like "class="GLIX78"".
Is there any way i can achieve adding a style which is declared at UiBinder in a Widget at runtime?
Thanks,
You can reference the style, which you have declared in UiBinder. But you need to take some additional steps. Look at this example:
UiBinder
<!-- (1) declare your style , remember to set the type attribute correctly - you should place your package.WidgetName.StyleName in there -->
<ui:style type='z.client.TEstWidget.MyStyle'>
.blackBG {
background-color: black;
}
.grayBG {
background-color: gray;
}
</ui:style>
<g:HTMLPanel>
<g:Label ui:field="myLabel" styleName="{style.grayBG}">test</g:Label>
<g:Button ui:field="myButton">change style</g:Button>
</g:HTMLPanel>
Widget code
public class TEstWidget extends Composite {
private static TEstUiBinder uiBinder = GWT.create(TEstUiBinder.class);
interface TEstUiBinder extends UiBinder<Widget, TEstWidget> {
}
// declare the style (2)
interface MyStyle extends CssResource {
String blackBG();
String grayBG();
}
// (3) here you make reference to the style declared in uibinder
#UiField
MyStyle style;
#UiField
Button myButton;
#UiField
Label myLabel;
public TEstWidget() {
initWidget(uiBinder.createAndBindUi(this));
}
#UiHandler("myButton")
public void onClick(ClickEvent event) {
// change the background of the label
// (4) this is how you can use your style
myLabel.removeStyleName( style.grayBG());
myLabel.addStyleName(style.blackBG());
}
}
I have a few different views & screens which all use a few variants of Group, VGroup or HGroup and to have them laid out correctly, I find myself having to write and rewrite again with either
gap="0"
or with TileLayout
horizontalGap="0" verticalGap="0"
to get them all to layout correctly, and how I want. Currently the only option I see of being able to set them to zero globally is to set up a heavy global listener, ie.
protected function globalListener():void
{
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage, true);
}
protected function onAddedToStage(event:Event):void
{
var g:Group = event.target as Group;
if(g)
{
if( g.layout.hasOwnProperty('gap') )
{
g.layout['gap'] = 0;
}
else
{
var l:TileLayout = g.layout as TileLayout;
if(l)
{
l.verticalGap = l.horizontalGap = 0;
}
}
}
}
or creating a new package with these layouts, and adding gap=0 to them,
package overrides.gapless
{
import spark.components.HGroup;
public class HGroup extends spark.components.HGroup
{
public function HGroup()
{
gap = 0;
}
}
}
and
package overrides.gapless
{
import spark.layouts.TileLayout;
public class TileLayout extends spark.layouts.TileLayout
{
public function TileLayout()
{
horizontalGap = 0;
verticalGap = 0;
}
}
}
and the like. I've checked the source code of the relevant files (mainly VerticalLayout, HorizontalLayout and TileLayout) and can see the values hardcoded in, but still can't fully believe there's no other way to do it.
I've only recently started delving into Flex, and am loving it's skinning options, but am a bit mystified about this one.
Thanks for any and all help as to how to do this.