I am creating my first tizen app, for a watch. I have started with the SettingUI sample code, and have added a 'name' item to the genlist, which I want to push a view where I enter my name. I will enter my name using an entry (on screen keyboard) component.
I see the keyboard in the emulator but the "A short text" text is partially cutoff at the top and left of the screen. It's as if the text flows in a SQUARE shape, but should flow in a CIRCLE shape. (But I do have a circle surface applied to the naviframe). If I switch the entry to single line (not multiline) then the text is actually hidden behind the keyboard). And the naviframe is inside the conformant.
Can anyone explain how I would make the entry (keyboard) text appear properly onscreen?
void _setting_name_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
appdata_s *ad = data;
Evas_Object *naviframe = ad->naviframe;
Elm_Object_Item *nf_it = NULL;
/* Unhighlight Item */
elm_genlist_item_selected_set((Elm_Object_Item *)event_info, EINA_FALSE);
// Create a keyboard (entry) and add to naviframe
Evas_Object *entry;
entry = elm_entry_add(naviframe);
elm_entry_entry_set(entry, "A short text.");
// Push the entry onto the naviframe to show it
nf_it = elm_naviframe_item_push(naviframe, _("Slider"), NULL, NULL, entry, "empty");
// Set the callback of the naviframe when layout popped off
elm_naviframe_item_pop_cb_set(nf_it, _setting_name_finished_cb, ad);
}
You can use size_hint property with ui containers.
void _setting_name_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
appdata_s *ad = data;
Evas_Object *naviframe = ad->naviframe;
Elm_Object_Item *nf_it = NULL;
/* Unhighlight Item */
elm_genlist_item_selected_set((Elm_Object_Item *)event_info, EINA_FALSE);
// Create a Box
Evas_Object *box;
box = elm_box_add(naviframe);
evas_object_show(box);
// Create a keyboard (entry) and add to box
Evas_Object *entry;
entry = elm_entry_add(box);
elm_entry_entry_set(entry, "A short text.");
evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, 0.5);
evas_object_size_hint_padding_set(entry, 50, 50, 30, 240);
elm_entry_single_line_set(entry, EINA_TRUE);
elm_entry_scrollable_set(entry, EINA_TRUE);
evas_object_show(entry);
elm_box_pack_end(box, entry);
// Push the entry onto the naviframe to show it
nf_it = elm_naviframe_item_push(naviframe, _("Slider"), NULL, NULL, box, "empty");
// Set the callback of the naviframe when layout popped off
elm_naviframe_item_pop_cb_set(nf_it, _setting_finished_cb, ad);
}
Related
Unable to navigate between the two screens while using grid layout in Tizen native. I click on a button1 on SCREEN1 which will open SCREEN2 which has YES and NO buttons. When I click on No button it should go back to the SCREEN1 - but what happens now is when I click on NO button a black screen is displayed. If I click on YES button it opens a popup screen with a message which is displayed for 5 seconds and then it should go back to the SCREEN1 but now it goes back to SCREEN2. The following code is what is used could anyone please check and help. thanks
static void
screen1_button_clicked(void *data, Evas_Object *obj, void *event_info){
Evas_Object *nf = data;
Evas_Object *grid;
/* Grid Layout */
grid = elm_grid_add(nf);
evas_object_show(grid);
elm_object_content_set(nf, grid);
elm_naviframe_item_push(nf, "Screen 2", NULL, NULL, grid, NULL);
/* Decline Button */
no_button = elm_button_add(grid);
elm_object_style_set(no_button, "circle");
elm_grid_pack(grid, no_button, 5, 35, 50, 50);
evas_object_show(no_button);
evas_object_smart_callback_add(no_button, "clicked",no_button_clicked, nf);
/* Decline Button - Icon */
no_button_icon = elm_icon_add(no_button);
elm_image_file_set(no_button_icon,ICON_DIR"/no_button.png",NULL);
evas_object_size_hint_min_set(no_button_icon, 100, 100);
evas_object_size_hint_max_set(no_button_icon, 100, 100);
elm_object_part_content_set(no_button,"icon",no_button_icon);
evas_object_show(no_button_icon);
/* Confirm Button */
yes_button = elm_button_add(grid);
elm_object_style_set(yes_button, "circle");
elm_grid_pack(grid, yes_button, 45, 35, 50, 50);
evas_object_show(yes_button);
evas_object_smart_callback_add(yes_button, "clicked", yes_button_clicked, nf);
/* Confirm Button - Icon */
yes_button_icon = elm_icon_add(yes_button);
elm_image_file_set(yes_button_icon,ICON_DIR"/yes_button.png",NULL);
evas_object_size_hint_min_set(yes_button_icon, 100, 100);
evas_object_size_hint_max_set(yes_button_icon, 100, 100);
elm_object_part_content_set(yes_button,"icon",yes_button_icon);
evas_object_show(yes_button_icon);
}
static void
no_button_clicked(void *data, Evas_Object *obj, void *event_info){
Evas_Object *nf = data;
elm_naviframe_item_pop(nf);
}
/* Base Gui */
/* Naviframe */
ad->navi = elm_naviframe_add(ad->conform);
evas_object_show(ad->navi);
elm_object_content_set(ad->conform, ad->navi);
/* Grid Layout */
ad->grid = elm_grid_add(ad->navi);
elm_object_content_set(ad->navi, ad->grid);
evas_object_show(ad->grid);
ad->navi_item = elm_naviframe_item_push(ad->navi, "Screen 1", NULL,NULL, ad->grid, NULL);
/* Button */
screen1_button = elm_button_add(ad->grid);
elm_object_style_set(screen1_button, "circle");
elm_grid_pack(ad->grid, screen1_button, 15, 37, 35, 50);
evas_object_show(screen1_button);
screen1_button_icon = elm_icon_add(screen1_button);
elm_image_file_set(screen1_button_icon,ICON_DIR"/button1.png",NULL);
evas_object_size_hint_min_set(screen1_button_icon, 123, 123);
evas_object_size_hint_max_set(screen1_button_icon, 123, 123);
elm_object_part_content_set(screen1_button,"icon",screen1_button_icon);
evas_object_show(screen1_button_icon);
evas_object_smart_callback_add(screen1_button, "clicked",screen1_button_clicked, ad->navi);
It seems to be an issue caused by unnecessary parent and child composition between widgets.
elm_object_content_set(ad->navi, ad->grid);
The naviframe widget itself does not have a container area to put the grid in,
but the grid was added to the sub object of the naviframe due to the above API call.
after that the same API was called with a different grid object.
elm_object_content_set(nf, grid);
When this happens, the naviframe subtracts the old sub object and constructs a new object as a child.
The sub-object that has been dropped becomes an isolated object and does not appear on the screen.
there is no need to call content_set for naviframe.
The item of naviframe becomes one view, and each view has a container area.
https://docs.tizen.org/application/native/guides/ui/efl/container-naviframe/
See above guide you can understand how naviframe works with items.
Anyway solution for your problem is delete
"elm_object_content_set(nf, grid);"
Objective: I am using the library Uiautomation.h to retrieve the window handle (hwnd) and window name when the user clicks on one element of that window. I need a solution with plain C.
Example: If the User clicks on the button 8 of the windows calculator, I need to identify the window handle and name as follow:
I am retrieving no window when the user clicks into a element of the windows calculator:
hwnd = 0
Window name = none
I am retrieving always 0 as hwnd. However, when I click in the header of the window, I can retrieve the hwnd and the window name as "Calculator". This is part of my code in plain C:
UIA_HWND hwnd;
PWSTR win_name = NULL;
static int win_len;
POINT pt;
IUIAutomation *pAutomation = NULL;
IUIAutomationElement *element = NULL;
CoInitialize(NULL);
EXTERN_C const CLSID CLSID_CUIAutomation;
EXTERN_C const IID IID_IUIAutomation;
HRESULT hr = CoCreateInstance(&CLSID_CUIAutomation,NULL, CLSCTX_INPROC_SERVER,&IID_IUIAutomation,(void**)&pAutomation);
GetCursorPos(&pt);
hr = IUIAutomation_ElementFromPoint(pAutomation, pt, &element);
if(SUCCEEDED(hr) && element != NULL){
IUIAutomationElement_get_CurrentNativeWindowHandle(element,&hwnd);
win_len = GetWindowTextLengthW(hwnd);
if(win_len > 0) {
win_name = (PWSTR) malloc(sizeof(wchar_t) * win_len + 1);
GetWindowTextW(hwnd, win_name, win_len + 1);
}
}
I used also the function hwnd = GetForegroundWindow(); but I still get the same value 0. Could someone know what I am doing incorrectly?
I want to create a grid with buttons. When a button is clicked I want it to change color, and 0 or 1 get stored in an array depending on the current state of the button.
Now I do this by creating the buttons with two for loops (rows, and columns).
Inside the for loops;
/*Create an ID number for the button being created*/
btn_nr ++;
char btn_nr_str[3];
sprintf(btn_nr_str,"%d",btn_nr); //convert nr to string
/*Create button*/
button = gtk_button_new();
/* When the button is clicked, we call the "callback" function
* with a pointer to the ID */
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (callback)(gpointer) btn_nr_str);
/* Insert button into the table */
gtk_table_attach_defaults (GTK_TABLE(table), button, col, col+1, row, row+1);
gtk_widget_show (button);
The callback function;
void callback( GtkWidget *widget, gpointer nr)
{
GdkColor buttonColor;
gdk_color_parse ("black", &buttonColor);
gtk_widget_modify_bg ( GTK_WIDGET(widget), GTK_STATE_NORMAL, &buttonColor);
g_print ("Hello again - %s was pressed\n", (char *) nr);
}
The buttons are created like wanted, and when clicked they turn black.
However, all buttons print the last created button's ID.
How do I pass the right ID on?
You are accessing a local array (btn_nr_str) from outside (the callback) its scope (the for cycle). The idea is correct (using user_data) but the implementation is not.
For your specific case, you can use the type conversion macros provided by GLib. They are meant for exactly this purpose:
/* In the for cycle */
g_signal_connect(button, "clicked", G_CALLBACK(callback), GINT_TO_POINTER(btn_nr);
/* In the callback */
gint btn_nr = GPOINTER_TO_INT(user_data);
P.S.: gtk_signal_connect has been deprecated years ago.
As shown in the example below, this callback function is when the user clicks an OK button. I can get window (the top level widget) from button by using gtk_widget_get_toplevel, but I'm stuck trying to get a widget pointer for a GtkEntry widget with name ENTRY.
/* Called when OK button is clicked */
on_BT_OK_clicked(GtkButton *button, gpointer user_data)
{
//The line directly below is the one I get an error on
GtkWidget *entry = lookup_widget( GTK_WIDGET(button), "ENTRY" );
gchar *text1, *text2;
text1 = gtk_entry_get_text( GTK_ENTRY(entry));
text2 = g_strconcat("Hello, ", text1, NULL);
GtkWidget *window = gtk_widget_get_toplevel (GTK_WIDGET(button));
GtkWidget *dialog = gtk_message_dialog_new( window,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
text2);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
But I get the error "undefined reference to lookup_widget." I can find a billion examples of snippets of code using lookup_widget, but not a single one full source code example showing the headers that enable the use of it. I'm using Anjuta3.2.0 and the latest Glade plugin.
As Basile Starynkevitch says, lookup_widget() was a function generated by Glade 2. However, code generation by Glade has been deprecated for quite a long time now, in favor of (first) libglade and (later) GtkBuilder. In fact, Glade 3 won't even do it.
The preferred solution is to pass a pointer to your ENTRY as the user data pointer when you connect the signal, or, if you're using gtk_builder_connect_signals(), store a pointer to ENTRY in your class and pass the class as the user data pointer.
However, if you must use lookup_widget(), here's the source that Glade 2 generated as of about 6 years ago:
GtkWidget*
lookup_widget (GtkWidget *widget,
const gchar *widget_name)
{
GtkWidget *parent, *found_widget;
for (;;)
{
if (GTK_IS_MENU (widget))
parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
else
parent = widget->parent;
if (!parent)
parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey");
if (parent == NULL)
break;
widget = parent;
}
found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget),
widget_name);
if (!found_widget)
g_warning ("Widget not found: %s", widget_name);
return found_widget;
}
For this to work, you have to do the following for every widget contained within a toplevel window:
g_object_set_data_full (G_OBJECT (toplevel), "name-of-widget", gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref);
and then the following once for each toplevel window:
g_object_set_data (G_OBJECT (toplevel), "name-of-toplevel", toplevel);
Seems to me to be more trouble than it's worth.
Glade-2 implements lookup_widget() in support.c and the header is support.h
Once the GLADE GUI is converted to C codes these files are generated automatically.
Hopefully this is an easy question to answer! I am trying to use GtkEntryCompletion (a la the example here) but while this code works I can't seem to get the GtkEntry to present the autocomplete results when I set the text of the field programatically. What I am trying to accomplish is a semi pre-filled text entry that is already presenting the user with some autocomplete options.
To set the text I have tried using the functions gtk_entry_set_text(...), gtk_entry_buffer_insert_text(...) and even gtk_entry_buffer_emit_inserted_text(...) but to no avail. Is there a way to do this in such a way as to act like regular user input and display the suggestions?
I think you need to call gtk_entry_completion_complete after setting the text.
EDIT
Sorry #Tylter, but wow, this is way more difficult than I imagined. The only way I can figure out how to do it is to actually send the keypress event to the window.
gtk_widget_grab_focus(entry);
GdkEvent new_event;
new_event.key.type = GDK_KEY_PRESS;
new_event.key.window = gtk_widget_get_parent_window(entry);
new_event.key.send_event = TRUE;
new_event.key.time = GDK_CURRENT_TIME;
new_event.key.keyval = 0x053; // capital S
new_event.key.state = GDK_KEY_PRESS_MASK;
new_event.key.length = 0;
new_event.key.string = 0;
new_event.key.hardware_keycode = 0;
new_event.key.group = 0;
gdk_event_put((gpointer)&new_event);
EDIT 2
Are you using a GtkDialog for your pop-up? I coded this up really quick and it seems to work. Here you would be creating the dialog in a button click event:
static void click_event( GtkWidget *widget,
gpointer data )
{
GtkWidget* window = gtk_dialog_new ();
completion = create_completion();
entry = gtk_entry_new();
gtk_entry_set_completion(GTK_ENTRY(entry), completion);
// add entry to dialog
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
entry, TRUE, TRUE, 0);
gtk_widget_show(entry);
gtk_widget_show(window); // you must show the window before sending the keypress event
gtk_widget_grab_focus(entry);
GdkEvent new_event;
new_event.key.type = GDK_KEY_PRESS;
new_event.key.window = gtk_widget_get_parent_window(entry);
new_event.key.send_event = TRUE;
new_event.key.time = GDK_CURRENT_TIME;
new_event.key.keyval = 0x053; // capital S
new_event.key.state = GDK_KEY_PRESS_MASK;
new_event.key.length = 0;
new_event.key.string = 0;
new_event.key.hardware_keycode = 0;
new_event.key.group = 0;
gdk_event_put((gpointer)&new_event);
}
The only gotcha I saw with this is that your must show the dialog window before sending the keypress event.