In Glade (version 3.8.5 as I am targetting gtk 2.24), I have created a label that sits in a row of a vbox. I have set the background color of the label (in Attributes) to blue, and the label appears to fill the entire row. But the blue background only extends as far as the text extent, not the entire width of the label.
How can I make the blue bar extend to the edges of the panel?
I read a while ago that Gtk labels don't actually have a color of their own, but they take whatever color their background widget has. I don't remember the source of this piece of information, but I do remember the solution, which is to put the label in a Gtk EventBox and change the color of said EventBox. I tested this solution in my gtk project with good results.
This is the function I use to change the color of the EventBox, by the way I'm using slightly older versions of Gtk and Glade, and I'm using C++ so if you're working with C you'll have to find the C equivalents of every function:
void GuiUtil::changeColor(Gtk::Widget* widget, double r, double g, double b) {
Glib::RefPtr<Gdk::Colormap> colormap = widget->get_colormap();
Glib::RefPtr<Gtk::Style> style = widget->get_style()->copy();
// STATE_NORMAL (most of the time)
{
Gdk::Color color;
color.set_rgb_p(r,g,b);
colormap->alloc_color(color);
style->set_bg(Gtk::STATE_NORMAL, color);
}
// STATE_PRELIGHT (when mouse hovers)
{
Gdk::Color color;
color.set_rgb_p(r*0.9,g*0.9,b*0.9);
colormap->alloc_color(color);
style->set_bg(Gtk::STATE_PRELIGHT, color);
}
// STATE_ACTIVE (when clicked)
{
Gdk::Color color;
color.set_rgb_p(r*0.8,g*0.8,b*0.8);
colormap->alloc_color(color);
style->set_bg(Gtk::STATE_ACTIVE, color);
}
widget->set_style(style);
}
As far as I know there isn't a way of doing this with Glade only.
Related
In the Java source code of my class, I saw that color is integrated as a method call with the input color as a word. So it seems that you can't implement any code, because color is defined with shape.setFillColor().
Is there a way around this? Otherwise a more complicated coloring would not be possible.
I have attached an example here in this screenshot how I could imagine it, however I get some errors because semicolons are missing and I have not declared the variables. So my problem is that i don't know how and if i can query if-else as well as embed switch case. So how can I write various functions for a color setting?
Can someone help me?
Example code for a color change of a rectangle
You could define a function that returns Color type, e.g. chooseColor(<your parameters>) and you could call shape.setFillColor(chooseColor(<your parameters>)). The body of the chooseColor() function can be based on the example code you posted.
Or you could call the chooseColor() function directly at the Fill color property of your shape if it is not too computation heavy, otherwise it could slow down the simulation.
Not quite sure what you need, tbh. You can make coloring as complex as you like. But once you decide on a color, you must call shape.setFillColor(theColorYouChose) to actually do it...
You can, however, create any possible color using Color myNewColor = new Color(x,y,z,a) where x, y and z are RGB values (0-255) and the last is the transparency you want (also 0-255)
To use this with switch/if statements, you can create a local Color variable and use it at the end for the shape:
Color myColor = new Color(0,0,0,0);
switch(someThing) {
case myCase:
myColor = yellowGreen;
break;
case myOtherCase:
if (someCondition) {
myColor = new Color(12, 222,45,122);
} else {
myColor = blue;
}
break;
}
shape.setFillColor(myColor);
I'm trying to display multiple cairo drawings overlapping each other:
extern crate cairo;
extern crate gio;
extern crate gtk;
use std::f64::consts::PI;
use gio::prelude::*;
use gtk::prelude::*;
use gtk::DrawingArea;
use std::env::args;
fn build_ui(application: >k::Application) {
let window = gtk::ApplicationWindow::new(application);
window.set_default_size(300, 300);
let overlay = gtk::Overlay::new();
// Draw first circle
let drawing_area1 = Box::new(DrawingArea::new)();
drawing_area1.connect_draw(|_, ctx| draw(ctx, 0.5, 0.4));
overlay.add(&drawing_area1);
// Draw second circle
let drawing_area2 = Box::new(DrawingArea::new)();
drawing_area2.connect_draw(|_, ctx| draw(ctx, 0.2, 1.0));
overlay.add(&drawing_area2);
window.add(&overlay);
window.show_all();
}
fn draw(ctx: &cairo::Context, width: f64, color: f64) -> Inhibit {
ctx.scale(300., 300.);
ctx.arc(0.5, 0.5, width, 0.0 * PI, 2.0 * PI);
ctx.set_source_rgba(color, 0.0, 0.0, 0.8);
ctx.fill_preserve();
Inhibit(false)
}
fn main() {
let application =
gtk::Application::new(Some("example.overlay"), Default::default())
.expect("Initialization failed...");
application.connect_activate(|app| {
build_ui(app);
});
application.run(&args().collect::<Vec<_>>());
}
Running this code gives me this warning:
(test_overlay_gtk:25534): Gtk-WARNING **: 19:12:05.573: Attempting to add a widget with type GtkDrawingArea to a GtkOverlay, but as a GtkBin subclass a GtkOverlay can only contain one widget at a time; it already contains a widget of type GtkDrawingArea
I understand that the overlay object can display only one of the drawing areas. I thought the overlay class is for exactly this purpose, to show overlapping widgets. I can't find a way to display the second overlapping drawing area.
add adds the widget to the overlay as the primary child - you can only have one of these. This is inherited from the container class in older versions of gtkmm (which I assume you're using) and is replaced by set_child in gtkmm 4 (which no longer inherits add from Gtk::Container).
add_overlay is the Gtk::Overlay specific method that allows you to add any number of widgets to be displayed on top of the child widget.
Try replacing your second add method with add_overlay and it should work.
First: I have no idea what I am doing here.
I simply asked Google for GtkOverlay and found this page: https://developer.gnome.org/gtk3/stable/GtkOverlay.html
The documentation for gtk_overlay_add_overlay says:
Adds widget to overlay.
The widget will be stacked on top of the main widget added with gtk_container_add().
So, apparently there is a main widget which you .add() and overlays which you .add_overlay().
For your example code: Can't you just draw the two drawings to the same overlay widget? Something like drawing_area1.connect_draw(|_, ctx| draw(ctx, 0.5, 0.4); draw(ctx, 0.2, 1.0));
I am trying to customize the horizontal slider such that its major tick labels appear above sliding track (by default they appear below sliding track) and major tick label values appear in reverse order. Do I need to use CSS somehow to display the labels above sliding track?
So far I have reversed the labels ordering using setLabelFormatter:
final double sliderMax = slider.getMax();
slider.setLabelFormatter(new StringConverter<Double>() {
#Override
public String toString(Double d) {
return String.valueOf((int)(sliderMax - d));
}
#Override
public Double fromString(String str) {
return (sliderMax - Double.parseDouble(str));
}
});
Any pointers will be helpful.
This is certainly possible with CSS.
This will only work for horizontal Slider though. Theoretically there is the pseude CSS class horizontal on the Slider which could be used to restict the CSS to horizontal Sliders, but I was unable to test this, maybe you can make it work.
Check out the CSS-Refrence and inspect your application with ScenicView.
I'm trying to create a label decorator to add an icon to the top left of my file icons. I see that the little red X can be drawn off of the edge of the icon, but my radiation symbol is cut off at the edge.
l
#Override
public Image decorateImage(Image image, Object element) {
Image failureImg = Activator.imageDescriptorFromPlugin(IMAGE PATH).createImage();
GC gc = new GC(image);
gc.drawImage(failureImg, 0, 0, failureImg.getImageData().width, failureImg.getImageData().height,
0, 0, 11, 11);
gc.dispose();
return image;
}
Any ideas on how to draw outside of the bounds of the file icon?
It is easier to use a lightweight label decorator (implement ILightweightLabelDecorator and specify lightweight="true" in the extension point).
You can then add the decoration image with:
#Override
public void decorate(final Object element, final IDecoration decoration)
{
ImageDescriptor imageDescriptor = Activator.imageDescriptorFromPlugin(IMAGE PATH);
decoration.addOverlay(imageDescriptor, IDecoration.TOP_LEFT);
}
Since lightweight decorators are run in a background thread they also make the UI more responsive.
Note: Your code is creating Image objects and not arranging for them to be disposed - this leaks resource handles. The lightweight decorator does not have this issue.
I am in the process of adding drag and drop support to an existing Mono/C#/GTK# application. I was wondering whether it was possible to use RGBA transparency on the icons that appear under the mouse pointer when I start dragging an object.
So far, I realized the following:
I can set the bitmap in question by calling the Gtk.Drag.SourceSetIconPixbuf() method. However, no luck with alpha transparency: pixels that are not fully opaque would get 100% transparent this way.
I also tried calling RenderPixmapAndMask() on the GdkPixbuf so that I could use Gtk.Drag.SourceSetIcon() with an RGBA colormap of my Screen. It didn't work either: whenever I started dragging, I got the following error:
[Gdk] IA__gdk_window_set_back_pixmap: assertion 'pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap)' failed.
This way, the pixmap doesn't even get copied, only a white shape (presumably set by the mask argument of SetSourceIcon()) shows up on dragging.
I'd like to ask if there's a way to make these icons have alpha transparency, despite the fact that I failed to do so. In case it's impossible, answers discussing the reasons of the lack of this feature would also be helpful. Thank you.
(Compositing is - of course - enabled on my desktop (Ubuntu/10.10, Compiz/0.8.6-0ubuntu9).)
Ok, finally I solved it. You should create a new Gtk.Window of POPUP type, set its Colormap to your screen's RGBA colormap, have the background erased by Cairo to a transparent color, draw whatever you'd like on it and finally pass it on to Gtk.Drag.SetIconWidget().
Sample code (presumably you'll want to use this inside OnDragBegin, or at a point where you have a valid drag context to be passed to SetIconWidget()):
Gtk.Window window = new Gtk.Window (Gtk.WindowType.Popup);
window.Colormap = window.Screen.RgbaColormap;
window.AppPaintable = true;
window.Decorated = false;
window.Resize (/* specify width, height */);
/* The cairo context can only be created when the window is being drawn by the
* window manager, so wrap drawing code into an ExposeEvent delegate. */
window.ExposeEvent += delegate {
Context ctx = Gdk.CairoHelper.Create (window.GdkWindow);
/* Erase the background */
ctx.SetSourceRGBA (0, 0, 0, 0);
ctx.Operator = Operator.Source;
ctx.Paint ();
/* Draw whatever you'd like to here, and then clean up by calling
Dispose() on the context's target. */
(ctx.Target as IDisposable).Dispose ();
};
Gtk.Drag.SetIconWidget(drag_context, window, 10, 10);