CSS from code? How to use CSS decoration directly from Vala? - gtk

How to use CSS customization directly from Vala? Not like in this example with file. Let's say I want the button to turn red by clicking on it, without using an external css file, as this action is too simple to create a css file with a single field.
I mean smth like this:
label.set_styleSheet("font-size: 17px;")

You still have to create a CssProvider, like in the code you linked to:
var screen = this.get_screen ();
var css_provider = new Gtk.CssProvider();
You can call load_from_data () instead of load_from_path () to load it from a string in memory instead of a file:
https://valadoc.org/gtk+-3.0/Gtk.CssProvider.load_from_data.html
css_provider.load_from_data(".my_class { font-size: 17px; }");
Gtk.StyleContext.add_provider_for_screen(screen, css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER);
When the CSS provider has loaded the custom styles to be used, you can manipulate every Gtk+ widget with get_style_context ().
The style context has methods to add, remove and query a class, etc.
https://valadoc.org/gtk+-3.0/Gtk.StyleContext.html
label.get_style_context().add_class("my_class");
Since you only have to setup the style provider once, I don't think it is too much overhead.

For anyone who is reading this I have posted both examples with and without file to Git https://gitlab.com/gavr123456789/vala-css-examples/tree/master

Related

How to get html of a SAP UI5 control

Normally when using SAP UI5, we use the following code
this.appContent.placeAt('content');
This will render the content element.
But I just want the html of appContent UI5 control without rendering it. How to do that?
The reason I want to do it is because I want to use sap.ui.template to build a carousel and I want to add get raw HTML of UI5 control and add it as a string to a template instead of rendering it directly.
Assuming this.appContent is a control, then after the contol has been rendered just call
var $domRef = this.appContent.$():
or getDomRef() (visibility is protected!)
var domRef = this.appContent.getDomRef():
Be aware when to call this after the control has been rendered, i.e. like this:
this.appContent.addEventDelegate({
onAfterRendering : function(oEvent){
var $domRef = oEvent.srcControl.$();
// now do something
}
});
this.appContent.placeAt('content');
However, I would try to avoid using placeAt.

Dyamic Color Change of Ionic's ion-toggle and ion-checkbox (use color string at runtime)

I'm trying to dynamically change the color of Ionic's Ion-Toggle and Ion-Checkbox at runtime. I know I can change it to a pre-defined sass variable like this:
<ion-toggle [color]="somePredefinedColor"></ion-toggle>
where "somePredefindedColor" is the string of the predefined sass variable...but because there is a section in my app that adapts to the corporate design colors of a company (which it gets from server as hex-strings) this is not possible.
The closest I got was to query the document by the component's class ".toggle-icon" and set its background color. This works at the first load but as soon as the page is loaded again it falls back to the sass predefined colors...
Have you tried this:
<ion-toggle [style.color]="colorVariable"></ion-toggle>
Where colorVariable is a variable in your component in .ts file, which you can change it dynamically:
if (this.redCondition)
this.colorVariable = 'red';
else
this.colorVariale = 'black';
Alternatively, you can define two CSS classes in your SCSS file, call it red-toggle, and black-toggle. Then you can:
<ion-toggle [class.red-toggle]="redCondition" [class.black-toggle]="!redCondition"></ion-toggle>
These methods are called style and class binding respectively.
If you want to dynamically change a value in your css style, you can use ngStyle directive:
[ngStyle]="{ 'background-color': hexColorString}"
EDIT:
The problem is that ion-toggle after transpile will have two child nodes, and you want to change the style of those child nodes dynamically. These nodes are toggle-icon, and toggle-inner:
This is not the cleanest way of doing it, but you can use the following typescript code, and modify it so that the colors change dynamically:
var div1 = document.getElementById('mytoggle').getElementsByTagName('div');
if(div1[0]){
div1[0].style.backgroundColor = '#0F0';
var div2 = div1[0].getElementsByTagName('div');
if(div2[0])
div2[0].style.backgroundColor = '#00F';
}
Notice that you have to set "mytoggle" as the id of the ion-toggle element in your html file.
Disclaimer: This code is rather hacky and may not work correctly with future versions of Ionic!
You just need to add square brackets on the dynamic attribute that is receiving the variable.
<ion-toggle [color]="somePredefinedColor"></ion-toggle>
Predefined colors can be setup in the theme/variables.scss file under $colors
$colors: (
primary:#48B0F7,
secondary:#10CFBD,
....
somePredefinedColor:#000
)
Which can then be added to the [color] attribute
<ion-toggle [color]="somePredefinedColor"></ion-toggle>

How to remove the injected CSS Resource in GWT?

I want to remove the injected CSSResource in GWT application.
I used the following code MyClass.INSTANCE.ensureInjected();
I want the above CSSResource for a particular page only. So the remaining pages should be work as per the actual css/theme.
Once I inject this then its applicable for the whole application. How can I overcome this?
You can inject your css bundle using directly StyleInjector utility class, instead of the ensureInjected() method
Then you will have a reference of the injected element which you can remove when you want.
// Equivalent to MyClass.INSTANCE.ensureInjected()
StyleElement e = StyleInjector.injectStylesheet(MyClass.INSTANCE.css().getText());
// Remove the injected css element
e.removeFromParent();
Theoretically you could try to remove the injected style block from the DOM, but this would be quite difficult (and maybe not very reliable).
Much better to organize your 'special' CSS style sheet in a different way:
Turn selectors like
.some {
color: green;
}
.other {
color: red;
}
into
.special .some {
color: green;
}
.special .other {
color: red;
}
and then add/remove the 'special' class e.g. to/from your body element to activate/deactivate the special styles.
If you have embedded the same GWT application in more than 1 page and you want a different behavior based on the given page, you can for example call the
MyClass.INSTANCE.ensureInjected();
if a bootstrap parameter is set.
In the host page, set the parameter, like YourGwtApp.nocahe.js?css=inject and read it as it's explained here
In the onLoadMethod, call the ensureInjected accordingly to your bootstrap parameter.

GWT StackLayoutPanel: how to change header background color

I want to change stacklayoutpanel header back ground color using css and I tried everything.
.gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader .gwt-StackLayoutPanelContent .gwt-StackLayoutPanelItem {
color: red;
border:red;
border-color: red;
background:red;
background-color:red;
}
But only changed the text color and I don't want that. Please can you explain how can I do that?
StackLayoutPanel wraps hour header widget/text to an internal class named Header, which is not publicly accessible. One approach is to override default clean.css .gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader styles by copying it to your own css file, then appending !important to styles you want to change.
However, better and cleaner solution is to do the following:
// add/insert your item first
myStackLayoutPanel.add(widget, header, size);
// retrieve the Header internal widget (AFTER ADDING!)
Widget internHeader = header.getParent();
// replace default style
internHeader.setStyleName("my_custom_style");
If you don't like using class css styles, you may alternatively do something like:
... same as above
// reset the default style
internHeader.setStyleName("");
// then add your styles programmatically
Style style = internHeader.getElement().getStyle();
style.setBackgroundColor();
etc.
It is important to retrieve the internal header widget after call to add/insert!
Your CSS style is incorrect. It's trying to target classes with the following hierarchy:
.gwt-StackLayoutPanel
.gwt-StackLayoutPanelHeader
.gwt-StackLayoutPanelContent
.gwt-StackLayoutPanelItem
Which is completely incorrect. If you want ALL elements with those classes to have the same background color, you would write your CSS rule like this:
.gwt-StackLayoutPanel,
.gwt-StackLayoutPanelHeader,
.gwt-StackLayoutPanelContent,
.gwt-StackLayoutPanelItem
{
background-color: red;
}
You better create your own css file based on gwt's default and make changes there. You also need to exclude gwt default css from your_module.gwt.xml and put there your newly created

Using <wicket:message> tag to produce partially formatted text

I've read about wicket:message here, but can't seem to make it do everything I'd like.
Say I have a HTML page with <wicket:message key="text"/> and a properties file containing text=Blah blah: important point, foo bar. I'm wondering how to make part of the text bold (or apply arbitrary CSS to it), to achieve output like:
Blah blah: important point, foo bar
Note that none of this is actually dynamic, so I wouldn't want to do anything in Java, if that can be avoided.
I've tried nesting tags with something like the following, but no luck.
<wicket:message key="text">
<span class="bold"><wicket:message key="text2"/></span>
</wicket:message>
text=Blah blah: ${text2}, foo bar
text2=important point
Is this even possible in Wicket without 1) injecting the formatted part from Java side or 2) just splitting the text into (in this case) three different properties?
The easiest way is to put the tags inside your localization file:
text=Blah blah: <strong>text2</strong>, foo bar
You could also use a Label and a ResourceModel to replace it later:
text=Blah blah: [b]text2[/b], foo bar
And in your model getObject(), or in your Label:
string.replace("[b]", "<strong>");
string.replace("[/b]", "</strong>");
Or, even better, try to reuse a Markdown implementation in your Label.
I've managed to do this for my own application, albeit with a rather ugly hack. I did it by exposing a customized version of WicketMessageResolver.
Here's what to try:
Wholesale copy and paste org.apache.wicket.markup.resolver.WicketMessageResolver into your own class (say com.acme.CustomWicketMessageResolver) (the hack begins!)
Inside your CustomWicketMessageResolver change
WicketTagIdentifier.registerWellKnownTagName( "message" ); to something else like WicketTagIdentifier.registerWellKnownTagName( "msg" );.
Inside of
private void renderMessage(final MarkupStream markupStream, final ComponentTag openTag, final String key, final String value), you'll find the line getResponse().write( text );.
Immediately before that line you have the opportunity to screw around with the value of "text". There, I do something like text = MyLabelUtils.replaceWikiMarkup(text) which post-processes some wiki-like markup syntax used by the content authors for my application.
For example, I use this method to take a Label using a ResourceModel pointing to the key:
propertyKey=I found the answer on [acronym SO].
and a render it as
I found the answer on <acronym title="Stack Overflow">SO</acronym>.
and that method handles i18n and all that fun stuff.
You can, of course, extend that wiki syntax (or anything similar) to be as simple or complex as you'd need.
Note that you'll have to change <wicket:message key='foo'> to <wicket:msg key='foo> in all of your markup files (or at least in ones where you want this behaviour).
I'd obviously prefer a more standard way to customize the behaviour of the built-inwicket message resolver, but if you need this functionality in a pinch, like I did, this will work for now.
If you need something more standard, you could raise the issue on the Wicket mailing list. It's pretty good.
Starting from Wicket 1.4 you can nest components within a wicket:message element. For example:
<wicket:message key="myKey">
This text will be replaced with text from the properties file.
<span wicket:id="amount">[amount]</span>.
<a wicket:id="link">
<wicket:message key="linkText"/>
</a>
</wicket:message>
Then
myKey=Your balance is ${amount}. Click ${link} to view the details.
linkText=here
and
add(new Label("amount",new Model("$5.00")));
add(new BookmarkablePageLink("link",DetailsPage.class));
Results in:
Your balance is $5.00. Click here to view the details.
So maybe, nesting <wicket:message>s without a component could work as well. Not sure.
Source: https://cwiki.apache.org/confluence/display/WICKET/Wicket%27s+XHTML+tags#Wicket%27sXHTMLtags-Elementwicket%3Amessage