Correct GTK CSS selector to use from SWT widgets? - eclipse-plugin

I'm trying to apply GTK+ 3 CSS rules to widgets used in the Eclipse UI, specifically for a ComboBox right now. For example: say I want to make the background color of a selected text in a combobox to be red. The Style rule applied to the combobox widget would be
*.entry:selected { background-color: #FF0000; }
I have proven that rule using the Gtk+ CSS Inspector tool in Ubuntu and that works there but I do not find a way to apply that rule in code for ComboBoxes.
Inside SWT, there are places where CSS is used on Linux, such as this snippet to set the background color, however, adding the above rule to the CSS override does not have any apparent impact (yes, the background color does work).
#Override
void setBackgroundColor (long /*int*/ context, long /*int*/ handle, GdkRGBA rgba) {
// CSS to be parsed for various widgets within Combo
background = rgba;
String css = "* {\n";
if (rgba != null) {
String color = display.gtk_rgba_to_css_string (rgba);
css += "background: " + color + ";\n";
}
css += "}\n";
// Cache background color
cssBackground = css;
String finalCss = display.gtk_css_create_css_color_string (cssBackground, cssForeground, SWT.BACKGROUND);
//Injected code to make selected text red
finalCss += "\n.*:selected {background-color: #FF0000}";
if (entryHandle == 0 || (style & SWT.READ_ONLY) != 0) {
// For read only Combos, we can just apply the background CSS to the GtkToggleButton.
gtk_css_provider_load_from_css (OS.gtk_widget_get_style_context(buttonHandle), finalCss);
} else {
if (OS.GTK_VERSION >= OS.VERSION(3, 16, 0)) {
// For GTK3.16+, only the GtkEntry needs to be themed.
gtk_css_provider_load_from_css (OS.gtk_widget_get_style_context(entryHandle), finalCss);
} else {
// Maintain GTK3.14- functionality
setBackgroundColorGradient (OS.gtk_widget_get_style_context (entryHandle), handle, rgba);
super.setBackgroundColor (OS.gtk_widget_get_style_context (entryHandle), entryHandle, rgba);
}
}
// Set the background color of the text of the drop down menu.
OS.g_object_set (textRenderer, OS.background_rgba, rgba, 0);
}
I’ve tried various combinations of selectors and so far have not found a way to have the “selection” background color of the text to take effect.
Here is a link to the corresponding ComboBox class from SWT where it deals with CSS -- see the setBackgroundColor method.
https://github.com/eclipse/eclipse.platform.swt/blob/master/bundles/org.eclipse.swt/Eclipse%20SWT/gtk/org/eclipse/swt/widgets/Combo.java
I have proven that code runs and also managed to change the background for the entire combobox by changing the css rule there. However, if I inject my new rule it gets ignored.
Any help would be appreciated. Thanks!

Related

Custom CollapsingTopAppBar Jetpack Compose

The essence of the problem is that I want to write my own version of the AppBar that would include content as another Compose function. After looking at the source code of the current CollapsingTopAppBar implementation, I saw the following lines:
#Composable
private fun TwoRowsTopAppBar(
...
scrollBehavior: TopAppBarScrollBehavior?
) {
...
val pinnedHeightPx: Float = 64.dp
val maxHeightPx: Float = 152.dp
LocalDensity.current.run {
pinnedHeightPx = pinnedHeight.toPx()
maxHeightPx = maxHeight.toPx()
}
// Sets the app bar's height offset limit to hide just the bottom title area and keep top title
// visible when collapsed.
SideEffect {
if (scrollBehavior?.state?.heightOffsetLimit != pinnedHeightPx - maxHeightPx) {
scrollBehavior?.state?.heightOffsetLimit = pinnedHeightPx - maxHeightPx
}
}
...
Surface(...) {
Column {
TopAppBarLayout(
...
heightPx = pinnedHeightPx
...
)
TopAppBarLayout(
...
heightPx = maxHeightPx - pinnedHeightPx + (scrollBehavior?.state?.heightOffset
?: 0f),
...
)
}
}
}
As I understand it, scrollBehavior is used to handle the collapse and expansion behavior. In the current implementation, just constant values are put in heightOffsetLimit. And since I need my appbar implementation to be able to contain content of any size, I need to somehow know the size of this content in advance and put this value in heightOffsetLimit.
I have already written the code for my AppBar, so that it also contains content. But since I can't pass the height value of the content to scrollBehavior, the AppBar doesn't collapse to the end.
you need to calculate the height that the appbar will have before drawing it into the screen. I have followed this issue and solved my problem with the last solution. hope it helps:
Get height of element Jetpack Compose
use the content you can put (ex. an image or a huge text) as the MainContent
use your appbar as the DependentContent and use the size given in lambda to give the height to your appbar
finally set placeMainContent false as I believe you don't need to draw the image (or any other composable) directly in a box
and you will good to go

TornadoFx TabPane - Side = left and label rotate style

.tab-container {
-fx-background-color: transparent;
-fx-rotate: 90; }
how do convert to tornadofx? My Tab header label need to be aligned when side.Left.Please help on this
TornadoFX doesn't make any changes to the TabPane container, so exactly the same CSS and properties would work for a TornadoFX application. I think you meant .tab-pane instead of .tab-container though. If you want to write the same using type safe CSS, it would be:
tabPane {
backgroundColor += Color.TRANSPARENT
rotate = 90.deg
}

CUBA platform how to dynamically change field color

I'm trying to dynamically change some field color when it has changed due to some processing.
CUBA documentation explains how to do it statically through web theme extension (https://doc.cuba-platform.com/manual-6.2/web_theme_extension.html), but not dynamically. Although it is possible in Vaadin (https://vaadin.com/wiki/-/wiki/Main/Dynamically%20injecting%20CSS) on which platform web gui is built upon.
I suppose that if I use the Vaadin way of injecting CSS it will work (which I will try) but I will then have Vaadin specific code, which I'm trying to avoid.
Is there a CUBA way of doing so I'm missing ?
Edit:
I'm trying to have any field of a form to change background color when it has changed from its initial value. As per CUBA documentation (https://doc.cuba-platform.com/manual-6.2/web_theme_extension.html) I need to :
- create a SCSS mixin with background color
- inject the field in the editor class in order to have access to it
- react to a field change event and then define the style name of the field
I did create the SCSS mixin, but two issues I have :
1) I would like to retrieve the field instance dynamically instead of injecting it (keep code clean and light)
2) I would like to avoid defining the background color statically so that the color could be parameterized at runtime
For 1) I tried to injected the fieldGroup and used getFieldComponent(), then applied the style with setStyleName on it when it is changed. It worked but I would prefer to define this behavior for every field that is an input field.
For 2) apart from using Vaadin specific feature of injecting CSS (and tighing my code to Vaadin (and so leading me away of generic interface) I do not see how to do
Hope it's more clear
You cannot set truly dynamic color (any RGBA) from code to field but you can create many predefined colors for your field:
#import "../halo/halo";
#mixin halo-ext {
#include halo;
.v-textfield.color-red {
background: red;
}
.v-textfield.color-blue {
background: blue;
}
.v-textfield.color-green {
background: green;
}
}
I do not recommend using styles injected from code (as Vaadin Page does) since it is a mixing of logic and presentation. Instead you can create all predefined styles (30-50 styles should be enough) and assign it depending on some conditions using setStyleName method:
public class ExtAppMainWindow extends AppMainWindow {
#Inject
private TextField textField;
private int steps = 0;
public void changeColor() {
if (steps % 2 == 0) {
textField.setStyleName("color-red");
} else {
textField.setStyleName("color-blue");
}
steps++;
}
}
If you want to apply the logic of color change for all TextFields inside of FieldGroup you can iterate FieldGroup fields in the following way:
for (FieldGroup.FieldConfig fc : fieldGroup.getFields()) {
Component fieldComponent = fieldGroup.getFieldComponent(fc);
if (fieldComponent instanceof TextField) {
TextField textField = (TextField) fieldComponent;
textField.addValueChangeListener(e ->
textField.setStyleName("color-red")
);
}
}

How do you read localsettings variables in default.css file in a windows store app?

I am building a windows store app that has a default css and a default font size in that css. I am allowing the user to customize the font size from settings screen and that preference gets stored in local settings. How do I update my app to reflect the new font size? Are there any current patterns? This is a Html5/js app. Can I simply reload the css value from the change event?
When your app launches, read the font size from local settings and then set the document's font size with JavaScript:
document.body.style.fontSize = fontSizeFromSettings;
When the app is running and the user changes the font size, also call the above line. You could do this right after your code which saves the font size to local settings.
Naturally, you can also change the font size of individual elements using document.getElementById("myId").style.fontSize.
I read this as the OP having a class selector already defined, like
.myclass
{
font-size: 36px;
}
and wanting to modify all elements with the .myclass selector to be a new value, say 72px. If that's the intent, then you can dynamically modify the CSS.
Here's a simple (and fragile, not-suitable-for-production) function that looks for a specific style selector in a known CSS file and modifies it on the fly. You could probably generalize this, take a look at Changing External Stylesheets and How to change CSS Stylesheets with JavaScript for more details.
function updateFontSize(newFontSize) {
for (var i = 0; i < document.styleSheets.length; i++) {
if (document.styleSheets[i].href.indexOf("default.css") >= 0) {
var mySheet = document.styleSheets[i];
for (var r in mySheet.cssRules) {
if (mySheet.cssRules[r].selectorText == ".myclass") {
var myRule = mySheet.cssRules[r];
myRule.style.fontSize = newFontSize;
return;
}
}
}
}
};
Then somewhere you call it like (without hardcoding the value, of course):
updateFontSize("128px");

Nested Grid in GWT

I need to develop a control which is similar to the Nested Grid in the Smart GWT.
User will be having a column for expansion images, when user clicking on the image in a particular row, a sub grid has to be opened there itself. Here all remaining rows needs to move down.
How can i achieve that functionality? Can anybody give me some clues so that i can proceed.
I have already a grid which is a celltable with custom header(with search functionality implemented).
Thanks,
Saritha.
Create your nested widget (myNestedWidget) that you want to show. It should have a CSS style "position: absolute", unless your grid is added to the LayoutPanel (or similar), in which case you can position your widget directly. Let's call the parent widget of your grid gridParentWidget.
In your CellTable add the following handler:
myTable.addCellPreviewHandler(new Handler<myObject>() {
#Override
public void onCellPreview(CellPreviewEvent<myObject> event) {
if ("click".equals(event.getNativeEvent().getType())) {
if (event.getColumn() == 0) {
int top = myTable.getRowElement(event.getIndex()).getAbsoluteBottom();
int left = myTable.getRowElement(event.getIndex()).getAbsoluteLeft();
myNestedWidget.getElement().getStyle().setTop(top, Unit.PX);
myNestedWidget.getElement().getStyle().setLeft(left, Unit.PX);
gridParentWidget.add(myNestedWidget);
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
#Override
public void execute() {
int height = myNestedWidget.getOffsetHeight();
myTable.getRowElement(event.getIndex()).getStyle().setHeight(height + "px");
]
});
}
}
});
}
This is obviously an outline of the solution. The details of the implementation may vary slightly depending on which widgets you use for your parent widget and your nested widget. If you change z-indexes somewhere, you have to take it into account too. You also need to make sure that your nested widget fits into the width of your grid, or you'll need to wrap it in a ScrollPanel and set a width to it explicitly.