GtkImage File Name - gtk

How can I get the file name of the image used in a GtkImage widget?
I have a GtkImage widget that displays different images. I want to be able to click on the GtkImage, determine which image has been clicked i.e. get the file name, then display a larger version.
Thanks,

You can get the value of "file" property of GtkImage using g_object_get_property. Something on these lines:
GValue value = {0,};
/* If you have glib version 2.30 or higher use:
* GValue value = G_VALUE_INIT;
*/
g_value_init (&value, G_TYPE_STRING);
/* Assuming image is a valid GtkImage */
g_object_get_property(G_OBJECT(image), "file", &value);
printf("\n Filename = %s\n", g_value_get_string(&value));
Side note: To make use of the Glib's type system, g_type_init() should have been called. g_type_init() is called internally as a consequence of Gtk initialization through gtk_init.
Hope this helps!

Related

GTK+ / GTKMM Signal on "changed" on a textbuffer does not receive data

On the same window, I have 20 text views and I need to handle in only one callback the "changed" signal coming from the text buffers under them.
What is the best way to implement this? I mean, how to retrieve the text view widget concerned by the text change ?
I tried to pass the text view widget object itself on connect for the signal "changed" but it is not working. I also tried the same kind of implementation for buttons and it works perfectly for the "clicked" signal. Why isn't it working for text views with underlying text buffers?
The code for connect:
g_signal_connect(G_OBJECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(WidgetSecret))), "changed", G_CALLBACK(on_SecretText_changed), WidgetSecret);
and the callback:
void on_SecretText_changed(GtkWidget *p)<
I found another way to make it work. First is to conform to Gtkmm only, and not to mix up Gtk and Gtkmm:
Gtk::TextView* pSecret[21];
Then, retrieve all objects from Glade:
for (int i=1; i<=20; i++) {
sprintf(Bidon, "tvCh%0d", i);
pBuilder->get_widget(Bidon, pSecret[i]);
}
Finally, use sigc::bind to transmit an integer:
int id = 1; // this is the Id to pass to callback for this TextView
pSecret[id]->get_buffer()->signal_changed().connect(sigc::bind<int>(sigc::ptr_fun(&on_SecretText_changed), id));
with the following callback:
void on_SecretText_changed(int id)
{
// id is retrieved and used here
}

Gtk (mm) limit width of combobox

Because I use Comboboxes that may contain text entries of very long size,
which leads to the combobox increasing its width far beyond reasonable size,
I am trying to give a maximum width to the combobox.
If I am doing this like this:
class MyCombo : public Gtk::ComboBox {
private:
CellRendererText render;
public:
MyCombo() {
render.property_width_chars() = 10;
render.property_ellipsize() = Pango::ELLIPSIZE_END;
pack_start(render, true);
}
};
The result will be an empty cell of the desired width, which seems logical since I did not specify which column to show. But how can I do this with that attempt? Using pack_start will just bypass the renderer...
Another approach is this one:
class MyCombo : public Gtk::ComboBox {
private:
CellRendererText render;
public:
MyCombo() {
pack_start(render, true);
set_cell_data_func(render, sigc::mem_fun(*this, &MyCombo::render_iter));
}
void render_iter(const TreeModel::const_iterator& iter) {
Glib::ustring data = get_string_from_iter(iter);
int desired_width_chars = 10; //for example
render.property_text() = ellipsize_string(data, desired_width_chars);
}
};
Using that approach, it works, but the text in the popup (what opens up when u click the combobox) is also shortened which is not what I want (obviously the user should be able to read the whole string and I dont care about the popup widht.)
Can you please help me with this? I would be happy for any advice/alternative solutions.
Regards tagelicht
NOTE: set_wrap_width is a function that wraps the total number of entries in the combo box over a number of columns specified; it does not answer the question.
Using set_wrap_width(1) | Using set_wrap_width(5)
Following Noup's answer as a guide I managed to get the below code; which directly answers the question and its requirements (C++/Gtkmm).
// Get the first cell renderer of the ComboBox.
auto v_cellRenderer = (Gtk::CellRendererText*)v_comboBox.get_first_cell();
// Probably obsolete; Sets character width to 1.
v_cellRenderer->property_width_chars() = 1;
// Sets the ellipses ("...") to be at the end, where text overflows.
// See Pango::ELLIPSIZE enum for other values.
v_cellRenderer->property_ellipsize() = Pango::ELLIPSIZE_END;
// Sets the size of the box, change this to suit your needs.
// -1 sets it to automatic scaling: (width, height).
v_cellRenderer->set_fixed_size(200, -1);
Result (image):
Result of code
BE AWARE: Depending on where you perform the above code; either all the cells will be the same size, or just the box itself (intended).
From experimenting, I've found:
In the parent object constructor: All cell sizes are the same.
In a separate function: Only the first cell (the box) is affected.
I'd recommend you put the code in a function that's connected to the comboBox's changed signal, such as:
v_comboBox.signal_changed().connect(sigc::mem_fun(*this, &YourClass::comboBox_changedFunction));
This may be what you are looking for:
cell_renderer_text.set_wrap_width(10)
This is for Python, but you get the idea :-)
Unfortunately, the documentation is scarce. I found this by poking around in Anjuta/Glade.
Edit:
the docs are here. They are not overly helpful, but they do exist.
As an alternative, the following works for me without having to set wrap_width nor to subclass ComboBox (in Gtk#):
ComboBoxText cb = new ComboBoxText();
cb.Hexpand = true; //If there's available space, we use it
CellRendererText renderer = (cb.Cells[0] as CellRendererText); //Get the ComboBoxText only renderer
renderer.WidthChars = 20; //Always show at least 20 chars
renderer.Ellipsize = Pango.EllipsizeMode.End;
Note: I'm using Expand to use space if it's available. If you just want to keep the combo box on a fixed width, just remove that bit.

3DText - Change Text Through Script - Unity

I have read lot of questions on how to change text of a 3DText from script.
Lot of them suggested the following :::
GetComponent(TextMesh).text = "blah";
But when I try to use this, I get an error Expression denotes atype', where a variable',value' or method group' was expected
I tried a lot of examples and couldn't really get it to work.
TextMesh textMesh;
textMesh = (TextMesh) descriptionObject.transform.GetComponent("Text Mesh");
textMesh.text = "Name : ABC";
The above code though Compiles without errors doesn't change the text. Can someone help me out with this? How do I change the TEXT of a 3DText Object.
Thanks...
This would be a prettier solution than one already given(C# script used in example) :
//define a Textmesh that we want to edit
public TextMesh tm;
// here in start method (run at instantiating of script) i find component of type
// TextMesh ( <TextMesh> ) of object named"nameOfTheObject" and reference it
// via tm variable;
void Start () {
tm = (TextMesh)GameObject.Find ("nameOfTheObject").GetComponent<TextMesh>();
// here we change the value of displayed text
tm.text = "new Text u want to see";
}
Or if u want to do it the shortest way possible (syntax wise):
//keep in mind this requires for the script to be attached to the object u
// are editing (the 3dText);
//same as above, the only difference is the note in the line above as this
// method is run from gameObject.GetComponent....
// gameObject is a variable which would be equivalent of this.GetComp...
// in some other programming languages
GetComponent<TextMesh>().text ="new Text u want";
This Works !!!!
textMesh = (TextMesh) descriptionObject.transform.GetComponent(typeof(TextMesh));
textMesh.text = "Name : ABC";

GWT Dynamically Changing an Image

I want to change dynamically an image by using the ID and a Ressource Bundle.
Element changedImage;
/* imageID is the Id for the previous image */
changedImage = Document.get().getElementById("imageId");
/* And myImageBundle is the resource Bundle and icon the new image*/
changedImage.setInnerHTML(myImageBundle.icon().getHTML());
But nothing happens , it's the same image . Did i miss something ?
Thanks a lot for answer(s) or suggestions(s).
-------- Solution ---------------
I've found a solution , it works properly, but somehow i think it's not the best one . Everything is on the next function :
private void switchImage( AbstractImagePrototype imageBundled) {
String newStyleFromImageBundle, value;
value = "style=";
newStyleFromImageBundle = extractStyle(value ,imageBundled.getHTML());
Element e = Document.get().getElementById("imageHeaderLogo");
// removing the current style
e.removeAttribute("style");
// setting the new style with the previous one retrieved from the image bundled's html
e.setAttribute("style",newStyleFromImageBundle );
}
Hope it helps, feel free to tell if there's a better way to do it or this the worst you 've ever seen .. :-) .
I think this is specifically what applyTo is for. Why don't you just do the following:
/*assuming that the element with id "imageId" is a real image
element and is not undefined:*/
myImageBundle.icon().applyTo(Image.wrap(Document.get().getElementById("imageId")));
//editted to use Image.wrap
The above should apply the image you have defined in icon() to the image with id "imageId"

Eclipse RCP ListProvider tweaking

I have problem with changing this image list provider in to thumbnail provider. In case of need I will post View for it too.
public Object[] getElements(Object inputElement) {
if (iDirname == null)
return null;
File dir = new File(iDirname);
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File directory, String filename) {
if (filename.endsWith("jpg") || (filename.endsWith("bmp")) || (filename.endsWith("png") || (filename.endsWith("JPG") || (filename.endsWith("BMP")) || (filename.endsWith("PNG")))))
return true;
else
return false;
}
};
String[] dirList = null;
if (dir.isDirectory()) {
dirList = dir.list(filter);
for (int i=0; i<dirList.length;++i){
//dirList2[i] = new Image(device, dirList2[i]); added this to try passing array of Images - failed.
dirList[i] = iDirname + File.separatorChar + dirList[i];
}
}
return dirList;
}
And the view
public void createPartControl(Composite parent) {
iViewer = new ListViewer(parent);
iViewer.setContentProvider(new DirListProvider());
getSite().setSelectionProvider(iViewer);
makeActions();
hookContextMenu();
contributeToActionBars();
}
I don't know how to change provided path lists to the thumbnail displaying. Should I get the provided content in to Array and iterate through it creating Images? If so how?
Thanks in advance for your help.
EDIT:
I added
ImageDescriptor[] dirList = null;
if (dir.isDirectory()) {
String[] dirList2 = dir.list(filter);
for (int i=0; i<dirList2.length;++i){
dirList[i] = ImageDescriptor.createFromImageData(new ImageData(iDirname + File.separatorChar + dirList2[i]));
//dirList[i] = iDirname + File.separatorChar + dirList[i];
}
}
return dirList;
but this is not showing anything at all.
When you are telling me to use Composite, is it my parent variable? I still don't know how to display the images from paths passed by ListProvider. I am really green in this :/
What you are missing here is a LabelProvider. You can use a LabelProvider to provide an image for each element in your viewer's input.
However, Francis Upton is right, I don't think ListViewer will really suit your needs as you will end up with a single column of images. Although you won't be able to add the images directly to your Composite, you will need to set them as the background image of a label.
There are a couple of other things to consider:
You need to dispose() of your Images once you're done with them as they use up System handles. Therefore you need to keep track of the Images you create in your getElements(Object) method.
If the directories you are reading the images from do not already contain thumbnails, you will need to scale the images before presenting them on your UI.
Remember, the array type you return from your ContentProvider's getElements(Object) method defines the type that will get passed into your LabelProvider's methods. So you started off returning an array of strings representing paths to the images. Your LabelProvider would need to load these into images to be returned from the provider's getImage method - but bear in mind what I said about disposing of these images! Then you switched to returning an Array of image descriptors, in this case you would need to cast your incoming Object to an ImageDescriptor and use that to create the Image in the getImage method. Maybe once you have this working you can think about whether this meets your needs, and then possibly look at doing a different implementation, such as the composite/gridlayout/label approach.
I would not use a ListViewer for this. I would just create a Composite and then using GridLayout set up the number of columns you want and margins and so forth, and then just add the images directly to the composite. As far as I know you cannot put arbitrary things like imagines in an SWT List, so the ListViewer is not going to help you. You can do all of this in the createPartControl method.