GtkCellRenderer g_object_set crush if multiple columns defined - gtk3

I want to set style to combobox item. Tried to use css - not working.
So I tried to set properties directly via g_object_set.
In case of object gtk_list_store_new(1, G_TYPE_STRING); all goes fine and styles applied. But if gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); app crushes on g_object_set.
Code:
GError * error =0;
GtkComboBox* cb = GTK_COMBO_BOX(widget);
// GtkListStore *store = gtk_list_store_new(2, GDK_TYPE_PIXBUF, G_TYPE_STRING);
GtkListStore *store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
GtkTreeIter iter;
gtk_list_store_insert_with_values(GTK_LIST_STORE(store), &iter, -1, 0, "Netherlands",1, "Netherlands", -1);
gtk_list_store_insert_with_values(GTK_LIST_STORE(store), &iter, -1, 0, "Japan",1, "Netherlands", -1);
gtk_combo_box_set_model(cb, GTK_LIST_STORE(store));
GtkCellRendererText* cell = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(cb), cell, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(cb), cell, "text", 0, NULL);
GtkCellRendererText* cell2 = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(cb), cell2, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(cb), cell2, "text",1, NULL);
g_object_set(cell, "font", "Proxima Nova Rg 15");
g_object_set(cell, "foreground", "#a5adbe");
g_object_set(cell, "background", "#ffffff");
g_object_unref(store);
Stack trace:
strstr()
?? ()
g_object_set_valist()
g_object_set
Code is executed on realize signal of combobox
Thanks in advance!

When I've found cell-background property in docs, it became obvious that I am using wrong properties. But it will not work alone, you have to specify cell-background-set" = TRUE as I found here. Now it completely works for me - backgrounds, fonts, all set as needed.
My working code:
G_MODULE_EXPORT void on_countries_show(GtkWidget* widget, gpointer user_data)
{
GError * error =0;
GtkComboBox* cb = GTK_COMBO_BOX(widget);
GtkListStore *store = gtk_list_store_new(2, GDK_TYPE_PIXBUF, G_TYPE_STRING);
GtkTreeIter iter;
int h = gtk_widget_get_allocated_height(widget);
h = 18;
GdkPixbuf *nl = gdk_pixbuf_new_from_file_at_scale ("flags/NL.png", h, h, TRUE, &error);
GdkPixbuf *jp = gdk_pixbuf_new_from_file_at_scale ("flags/JP.png", h, h, TRUE, &error);
gtk_list_store_insert_with_values(GTK_LIST_STORE(store), &iter, -1, 0, nl, 1, "Netherlands", -1);
gtk_list_store_insert_with_values(GTK_LIST_STORE(store), &iter, -1, 0, jp, 1, "Japan", -1);
gtk_combo_box_set_model(cb, GTK_LIST_STORE(store));
GtkCellRenderer* pb = gtk_cell_renderer_pixbuf_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(cb), pb, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(cb), pb, "pixbuf",0, NULL);
GtkCellRenderer* cell = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(cb), cell, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(cb), cell, "text", 1, NULL);
g_object_set(pb,
"cell-background", "white",
"cell-background-set", TRUE,
NULL);
g_object_set(cell,
"font", "Proxima Nova Rg 15",
"background", "white",
"foreground", "#a5adbe",
"cell-background-set", TRUE,
NULL);
g_object_unref(store);
}
If anybody will stuck like me - you are welcome ;-)

Related

Mapbox GL JS: How to draw an horizontal separator inside a circle point

I'm trying to display two values separated by a horizontal separator inside a cluster point rendered using Mapbox GL JS.
Example (using leaflet) :
So far I've achieved to have this kind of point but I'm missing the 1px bar in the center.
How would you do this?
The code I'm using:
this.map.addLayer({
id: 'clusters',
type: 'circle',
source: 'markers',
filter: ['has', 'point_count'],
paint: {
'circle-color': '#ffffff',
'circle-radius': 20,
'circle-stroke-width': 3,
'circle-stroke-color': '#5eb3e4',
}
});
this.map.addLayer({
id: 'cluster-count',
type: 'symbol',
source: 'markers',
filter: ['has', 'point_count'],
layout: {
'text-field': '{point_count}\n{sum}',
'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'],
'text-size': 12,
},
paint: {
'text-color': '#00214e'
}
});
So I've managed to do this using a generated image, added as an icon to the layer:
const createLineImage = (width) => {
const bytesPerPixel = 4; // Each pixel is 4 bytes: red, green, blue, and alpha.
const data = new Uint8Array(width * bytesPerPixel);
for (let x = 0; x < width; x++) {
const offset = x * bytesPerPixel;
data[offset] = 0; // red
data[offset + 1] = 0; // green
data[offset + 2] = 0; // blue
data[offset + 3] = 255; // alpha
}
return { data, width, height: 1 };
};
this.map.addImage('line', createLineImage(25));
this.map.addLayer({
id: 'cluster-count',
type: 'symbol',
source: 'markers',
filter: ['has', 'point_count'],
layout: {
'text-field': '{point_count}\n{sum}',
'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'],
'text-size': 12,
'text-line-height': 1.5,
'icon-image': 'line',
},
});
Result is

How does google-visualization-tooltip calculate the left and top values?

How does google-visualization-tooltip calculate the left and top values for style ?
example - on debugging i can see that :-
<div class="google-visualization-tooltip" style="width: 1px; height: 0px; left: 453.25px; top: 44.91px;"</div>
How can i calculate this relatively, so that the tooltip shows on top and is center aligned to the point that is hovered upon, irrespective of the width of the element?
most charts in the 'corechart' package,
have methods for getting the position of various chart elements.
first, get the chart's layout interface...
var chartLayout = chart.getChartLayoutInterface();
the layout interface has method --> getBoundingBox(id)
where id is a string id of the chart element.
to find the position of a point, use this format for id --> point#series#row -- point#0#0
we can use chart event onmouseover to know when a point has been hovered,
and the tooltip is being shown.
the onmouseover event sends an argument with the row and column from the data table,
of the point that is being hovered.
as such, we can get the layout, find the point, and position the tooltip.
google.visualization.events.addListener(chart, 'onmouseover', function (sender) {
// ensure point is hovered
if (sender.row !== null) {
var padding = 16;
var chartLayout = chart.getChartLayoutInterface();
var pointBounds = chartLayout.getBoundingBox('point#' + (sender.column - 1) + '#' + sender.row);
var tooltip = chart.getContainer().getElementsByClassName('google-visualization-tooltip');
if (tooltip.length > 0) {
var tooltipBounds = tooltip[0].getBoundingClientRect();
tooltip[0].style.top = (pointBounds.top - tooltipBounds.height - padding) + 'px';
tooltip[0].style.left = ((pointBounds.left + (pointBounds.width / 2)) - (tooltipBounds.width / 2)) + 'px';
}
}
});
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = new google.visualization.DataTable({
"cols": [
{"label": "x", "type": "number"},
{"label": "y", "type": "number"}
],
"rows": [
{"c":[{"v": 2015}, {"v": 1}]},
{"c":[{"v": 2016}, {"v": 2}]},
{"c":[{"v": 2017}, {"v": 3}]},
{"c":[{"v": 2018}, {"v": 4}]},
{"c":[{"v": 2019}, {"v": 5}]},
{"c":[{"v": 2020}, {"v": 6}]}
]
});
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
google.visualization.events.addListener(chart, 'onmouseover', function (sender) {
// ensure point is hovered
if (sender.row !== null) {
var padding = 16;
var chartLayout = chart.getChartLayoutInterface();
var pointBounds = chartLayout.getBoundingBox('point#' + (sender.column - 1) + '#' + sender.row);
var tooltip = chart.getContainer().getElementsByClassName('google-visualization-tooltip');
if (tooltip.length > 0) {
var tooltipBounds = tooltip[0].getBoundingClientRect();
tooltip[0].style.top = (pointBounds.top - tooltipBounds.height - padding) + 'px';
tooltip[0].style.left = ((pointBounds.left + (pointBounds.width / 2)) - (tooltipBounds.width / 2)) + 'px';
}
}
});
var options = {
chartArea: {
bottom: 32,
left: 32,
right: 32,
top: 48,
width: '100%',
height: '100%'
},
hAxis: {
format: '0',
ticks: data.getDistinctValues(0)
},
legend: {
position: 'top'
},
pointSize: 4,
tooltip: {
isHtml: true,
trigger: 'both'
}
};
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Blink1 mk2 Chrome connectivity via WEBUSB API Light Blink Issue

I am working on a project that need notification alert via browser using Blink(1) mk2 device.
I have tried the following code for connection to the usb using WEBUSB API.
const VENDOR_ID = 0x27b8;
navigator.usb.requestDevice({
filters: [{
vendorId: VENDOR_ID
}]
}).then(selectedDevice => {
device = selectedDevice;
console.log("open")
var tOpen = device.open();
console.log("opened")
return tOpen;
}).then(() => {
console.log("selectConfiguration")
return device.selectConfiguration(1);
}).then(() => {
console.log("claimInterface")
return device.claimInterface(0);
}).then(() => {
console.log("controlTransferOut")
const r = Math.floor((Math.random() * 255) + 0);
const g = Math.floor((Math.random() * 255) + 0);
const b = Math.floor((Math.random() * 255) + 0);
// not entirely sure what is going on below...
const fadeMillis = 500;
const th = (fadeMillis / 10) >> 8;
const tl = (fadeMillis / 10) & 0xff;
const data = new Uint8Array([0x01, 0x63, r, g, b, th, tl, 0x00, 0x00]).buffer;
var rgb = new Uint8Array(3);
rgb[0] = r;
rgb[1] = g;
rgb[2] = b;
return device.controlTransferOut({
requestType: 'standard',
recipient: 'interface',
request: 0x09,
value: 1,
index: 0
},data);
}).then(result => {
console.log(result);
}).catch(error => {
console.log(error);
});
I am able to connect to usb after setting the permissions popup. After that above code opens it, selectConfiguration, claimInterface also worked fine and when I call controlTransferOut it also sends out the command and return the result as:
USBOutTransferResult {bytesWritten: 8, status: "ok"}
But blinking or color change on the USB does not reflected.
Am I missing something or is there any other configuration I need to use in order to get the light up on USB?
I ran this code myself and found that when I set requestType to "standard" I got a "stall" but if I set it to "class" (which is correct since this is the HID class control transfer SET_REPORT) then I get "ok" and the color of the LED on my blink(1) mk2 changes.
Note, the RGB values in your snippet above are set randomly so you may be getting a very dim color.

MATLAB how to detect double click on tree node

I have the MATLAB code which deals with a uitree structure. I want to detect when the user double clicks a node, now I managed to make it work only on node click :(
% Tree
function test()
clc;
set(groot,'Units','characters')
figure('Position',[200,200,400,400]);
root = uitreenode('v0', 'Datatypes', 'Datatypes', [], false);
root.add(uitreenode('v0', 'Potato', 'Potato', [], true));
root.add(uitreenode('v0', 'Tomato', 'Tomato', [], true));
root.add(uitreenode('v0', 'Carrot', 'Carrot', [], true));
[mtree,container] = uitree('v0', 'Root', root,'Position',[50,50,150,150],SelectionChangeFcn, #callback);
uiwait(gcf,2);
root2 = uitreenode('v0', 'Datatypes2', 'Datatypes2', [], false);
root2.add(uitreenode('v0', 'Carrot2', 'Carrot2', [], true));
root2.add(uitreenode('v0', 'Tomato2', 'Tomato2', [], true));
mtree.setRoot(root2);
%displ tthe root and its children
root=mtree.getRoot();
rootName = root.getName();
for i=0:root.getChildCount()-1
childNode = root.getChildAt(i);
childName = childNode.getName();
disp(childName);
end
end
function callback(src, data)
persistent x;
if isempty(x)
x=0;
end
x=x+1;
disp([num2str(x) ' tree_Datatypes_Selection_Callback called']);
end
How do I make the callback be called on mouse double click? Now it works only on mouse node select click :(
I found the solution by own experimenting :
% Tree
function test()
clc;
global jtree;
set(groot,'Units','characters')
figure('Position',[200,200,400,400]);
root = uitreenode('v0', 'Datatypes', 'Datatypes', [], false);
root.add(uitreenode('v0', 'Potato', 'Potato', [], true));
root.add(uitreenode('v0', 'Tomato', 'Tomato', [], true));
root.add(uitreenode('v0', 'Carrot', 'Carrot', [], true));
[mtree,container] = uitree('v0', 'Root', root,'Position',[50,50,150,150]);
jtree = mtree.getTree;
% MousePressedCallback is not supported by the uitree, but by jtree
set(jtree, 'MousePressedCallback', #mousePressedCallback);
uiwait(gcf,2);
root2 = uitreenode('v0', 'Datatypes2', 'Datatypes2', [], false);
root2.add(uitreenode('v0', 'Carrot2', 'Carrot2', [], true));
root2.add(uitreenode('v0', 'Tomato2', 'Tomato2', [], true));
mtree.setRoot(root2);
%displ tthe root and its children
root=mtree.getRoot();
rootName = root.getName();
for i=0:root.getChildCount()-1
childNode = root.getChildAt(i);
childName = childNode.getName();
disp(childName);
end
end
function mousePressedCallback(hTree, eventData) %,additionalVar)
% if eventData.isMetaDown % right-click is like a Meta-button
% if eventData.getClickCount==2 % how to detect double clicks
persistent x;
global jtree;
if isempty(x)
x=0;
end
x=x+1;
clickX = eventData.getX;
clickY = eventData.getY;
treePath = jtree.getPathForLocation(clickX, clickY);
if ~isempty(treePath)
nr=eventData.getClickCount();
disp([num2str(x) ': click count:' num2str(nr)]);
% check if the checkbox was clicked
node = treePath.getLastPathComponent;
nodeValue = node.getValue;
else
disp('you clicked outside the tree')
end
end % function mousePressedCallback

How can I expand a Gtk.Scale in a Gtk.ListBox

I would like to expand the Gtk.Scale widgets (they are inside a Gtk.ListBox) and get rid of the indentation of the bottom two. The indentation seems to be connected to the length of the text in the left column.
#!/usr/bin/python3
from gi.repository import Gtk
from matplotlib.figure import Figure
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
from matplotlib.backends.backend_gtk3 import NavigationToolbar2GTK3 as NavigationToolbar
from numpy import pi
window = Gtk.Window()
window.set_default_size(800, 500)
window.connect("delete-event", Gtk.main_quit)
boxvertical = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
window.add(boxvertical)
toolbar = Gtk.Toolbar()
context = toolbar.get_style_context()
context.add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)
boxvertical.pack_start(toolbar, False, True, 0)
horizontalbox = Gtk.Box()
boxvertical.pack_start(horizontalbox, True, True, 0)
listcontainer = Gtk.Box(spacing=5)
horizontalbox.pack_start(listcontainer, False, True, 0)
listbox = Gtk.ListBox()
listbox.set_selection_mode(Gtk.SelectionMode.NONE)
listcontainer.pack_start(listbox, False, False, 5)
def amplitude_changed(event):
print(amplitude_scale.scale.get_value())
def wavelength_changed(event):
print(wavelength_scale.scale.get_value())
row = Gtk.ListBoxRow()
listcontainer = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=100)
row.add(listcontainer)
label = Gtk.Label("<b>Settings</b>", xalign=0.5)
label.set_use_markup(True)
listcontainer.pack_start(label, True, True, 0)
listbox.add(row)
class ListBox():
def __init__(self, name, lower_range, upper_range):
self.name = name
self.lower_range = lower_range
self.upper_range = upper_range
# two adjustments (initial value, min value, max value,
# step increment - press cursor keys to see!,
# page increment - click around the handle to see!,
# page size - not used here)
#self.adjustment = Gtk.Adjustment(0, 0, 20,
self.row = Gtk.ListBoxRow()
self.listcontainer = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=100)
self.row.add(self.listcontainer)
self.label = Gtk.Label(self.name, xalign=0)
self.scale = Gtk.Scale()
self.scale.set_range(self.lower_range, self.upper_range)
#self.scale.set_hexpand(True)
self.listcontainer.pack_start(self.label, False, False, 0)
self.listcontainer.pack_start(self.scale, True, True, 0)
listbox.add(self.row)
amplitude_scale = ListBox("Amplitude", 0.0, 5.0)
amplitude_scale.scale.connect("value-changed", amplitude_changed)
wavelength_scale = ListBox("Wavelength", 0.0, 20.0)
wavelength_scale.scale.connect("value-changed", wavelength_changed)
displacement_scale = ListBox("Displacement", 0.0, 10.0)
row = Gtk.ListBoxRow()
listcontainer = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=100)
row.add(listcontainer)
label = Gtk.Label("Color", xalign=0)
combo = Gtk.ComboBoxText()
combo.insert(0, "0", "Red")
combo.insert(1, "1", "Green")
combo.insert(2, "2", "Blue")
listcontainer.pack_start(label, False, False, 0)
listcontainer.pack_start(combo, True, True, 0)
listbox.add(row)
fig = Figure(figsize=(10,10), dpi=80)
ax = fig.add_subplot(111)
canvas = FigureCanvas(fig)
horizontalbox.pack_start(canvas, True, True, 0)
window.show_all()
Gtk.main()
your self.listcontainer inside ListBox class should have the property:
self.listcontainer.set_property ("homogeneous", True)