Toggle Between wireframe mode - openscenegraph

I have 2 functions, one to enter and to exit the wireframe mode:
void enterWireFrame(const osgGA::GUIEventAdapter& ea, osgViewer::Viewer* viewer)
{
osg::Node* scene = viewer->getSceneData();
osg::Group* parent = scene->getParent(0);
osg::Node* node = parent->getChild(0);
auto scribe = new osgFX::Scribe();
scribe->addChild(node);
parent->replaceChild(node, scribe);
}
And to exit:
void exitWireFrame(const osgGA::GUIEventAdapter& ea, osgViewer::Viewer* viewer)
{
osg::Node* scene = viewer->getSceneData();
osg::Group* parent = scene->getParent(0);
osg::Node* node = (dynamic_cast<osg::Group*>(scene))->getChild(0);
parent->replaceChild(parent, node);
}
Basically I ran the program in this sequence:
enterWireFrame(...);
exitWireFrame(...);
The enterWireFrame() renders the wireframe okay, but I am unable to get back the original non-wireframe look, despite running exitWireFrame().

Entering and exiting wireframe mode can easily be achieved by adding a PolygonMode attribute to the stateset of your node. Check osgGA::StateSetManipulator::cyclePolygonMode for implementation details. Actually, the 'w' key, unless overridden already does this toggling for you.

Related

How to create a button with an icon iside?

as stated in the title question, I want to create a button that uses an icon as background.
I am using the wearable circle emulator with 360x360.
I tried a lot of code and examples but with no success.
Last code used:
static void
create_base_gui(appdata_s *ad)
{
/* Window */
ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
elm_win_autodel_set(ad->win, EINA_TRUE);
if (elm_win_wm_rotation_supported_get(ad->win))
{
int rots[4] = { 0, 90, 180, 270 };
elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
}
eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad);
/*Box*/
ad->box = elm_box_add(ad->win);
evas_object_size_hint_weight_set(ad->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_show(ad->box);
elm_win_resize_object_add(ad->win, ad->box);
ad->button2 = elm_button_add(ad->box);
elm_object_text_set(ad->button2, "Click me");
evas_object_size_hint_weight_set(ad->button2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(ad->button2, EVAS_HINT_FILL, EVAS_HINT_FILL);
ad->icon2 = elm_icon_add(ad->box);
elm_image_file_set(ad->icon2, "C/Tizen/testWorkspace/BasicUI/shared/res/basicui.png", NULL);
elm_image_resizable_set(ad->icon2, EINA_TRUE, EINA_TRUE);
elm_object_part_content_set(ad->button2, "icon", ad->icon2);
elm_object_content_set(ad->button2, ad->icon2);
elm_box_pack_end(ad->box, ad->button2);
evas_object_show(ad->button2);
/* Show window after base gui is set up */
evas_object_show(ad->win);
}
The button is created and it's clickable (no behaviour defined yet).
The icon is not displayed.
What am I doing wrong ?
Thanks
PS: based on https://developer.tizen.org/ko/development/ui-practices/native-application/efl/ui-components/wearable-ui-components/creating-wearable-buttons?langredirect=1
and on the default BasicUI example
You need to declare the path from the tizen system point of view.
The correct path is then
/opt/usr/apps/org.somepackage.yourapp/shared/res/youricon.png
needless to say that org.somepackage.yourapp is the package path to your app and youricon.png is your icon.
You can even check the location of your icon in the device manager.
On the following image it is
/opt/usr/apps/org.example.settingsui/shared/res/settingsui.png
This is not imho very good solution, but there is a better way of doing this:
You can use either function
app_get_shared_resource_path();
app_get_resource_path();
You can write method like this:
static void
app_get_shared_resource(const char *file_in, char *path_out, int path_max)
{
char *res_path = app_get_shared_resource_path();
if (res_path) {
snprintf(path_out, path_max, "%s%s", res_path, file_in);
free(res_path);
}
}
and then use it like this
char icon_path[128] = {0,};
app_get_shared_resource("youricon.png", icon_path, 128);
// create your button and stuff and then
elm_image_file_set(ic, icon_path, NULL);
All these are more valuable for tizen 2.3.X and lower. Since Tizen 2.4 you can use Resource Manager
My guess is that the icon should be added on button control instead of box control.
So this:
ad->icon2 = elm_icon_add(ad->box);
should be:
ad->icon2 = elm_icon_add(ad->button);
Hope that helps!

In Linux, Which component decides to open a new window in gedit?

Let's consider that I open a file with the command gedit toto1.txt, a new window shows up with the content of toto1.txt. This sound familiar and usual, however the two following cases are not that straight to undertand: (1) a new command (let's says gedit toto2.txt) open a new tab in the previous window and (2) a new command (let's says gedit toto3.txt) will open a new tab in a new window.
My question is : which component decide to open the new window in case (2) and what are the condition to do so ? Why It did not opened a new window in case (1) ?
Any idea ?
It's gedit itself that makes that decision. Let's take a look at the source code. The function open_files will open a new window when it cannot find an active window (or when the flag --new-window was explicitly specified).
static void
open_files (GApplication *application,
gboolean new_window,
...)
{
GeditWindow *window = NULL;
if (!new_window)
{
window = get_active_window (GTK_APPLICATION (application));
}
if (window == NULL)
{
gedit_debug_message (DEBUG_APP, "Create main window");
window = gedit_app_create_window (GEDIT_APP (application), NULL);
gedit_debug_message (DEBUG_APP, "Show window");
gtk_widget_show (GTK_WIDGET (window));
}
...
}
So what's an "active window"? Let's look at get_active_window:
static GeditWindow *
get_active_window (GtkApplication *app)
{
GdkScreen *screen;
guint workspace;
gint viewport_x, viewport_y;
GList *windows, *l;
screen = gdk_screen_get_default ();
workspace = gedit_utils_get_current_workspace (screen);
gedit_utils_get_current_viewport (screen, &viewport_x, &viewport_y);
/* Gtk documentation says the window list is always in MRU order */
windows = gtk_application_get_windows (app);
for (l = windows; l != NULL; l = l->next)
{
GtkWindow *window = l->data;
if (GEDIT_IS_WINDOW (window) && is_in_viewport (window, screen, workspace, viewport_x, viewport_y))
{
return GEDIT_WINDOW (window);
}
}
return NULL;
}
So, the answer is: gedit will open a new window if there's not already a gedit window on screen.
(Well, there could of course be bugs here. I haven't looked very closely. That viewport_x/y stuff looks a bit suspect, as a viewport should have four coordinates: top/bottom/left/right. The code might be confused by multi-monitor setups).
Looks like this is done by gedit itself :)
But, if you want to open document in new window you can use --new-window switch. Try to call gedit with --help from command line.
If you need an straight answer on question "How gedit determine is it can use existing window or must open a new one?" i think you must see the gedit source code at https://github.com/GNOME/gedit

Avoid MessageBox while closing child window

I am having a child window derived from CFormView. On certain condition in OnCreate() function, I want to close this window.
I tried 2 options:
int CFilterWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFormView::OnCreate(lpCreateStruct) == -1)
return -1;
//Trial-1
if (!IsInitialized())
{
DestroyWindow();
return 0;
}
//Trial-2
if (!IsInitialized())
{
return -1;
}
return 0;
}
In both scenarios, the window is closed but my system returns "Failed to create empty document."
How do I avoid this message?
This is a completely normal behavior.
Document, Frame and View are created in one turn. First the document is created, than the frame and than the inner view. If one of the operations failed all other are also rolled back and fail.
So in the case of the MDI OnFileNew calls OpenDocumentFile from you template.
This function creates the new CDocument, followed by a new frame window. The frame window creates the view. This fails due to your code.
Your error message comes from CMultiDocTemplate::OpenDocumentFile because CreateNewFrame fails.
Let the MFC create your window and destroy the view it in OnInitialUpdate. This should work without this message.

wxWidgets wxFrame resize in wxNotebook

I am using wxWidget to design GUI. My GUI has multiple tabs. If user resizes the Frame, if he has selected some tab, when he is switching between tabs same modified size should be maintained. i am using sizers to put all child windows.But currently this is not happening. My current code is like this
void XTab::OnPageChanged(wxNotebookEvent & event)
{
if(isActive())
{
int page = event.GetOldSelection();
if(page!=-1)
{
XPanel * panel = (XPanel*)GetPage(page);
xdmlASSERT(panel->isActive());
panel->onUIDeactivate();
}
page = event.GetSelection();
if(page!=-1)
{
XPanel * panel = (XPanel*)GetPage(page);
xdmlASSERT(!panel->isActive());
panel->onUIActivate();
}
RecalcSize();
DFrame::UpdateLayout(this);
}
}
where DFrame is derived from wxFrame and XPanel is derived from wxPanel.The size is recalculated and best size is queried in GetSizer->CalcMin() method. This happens in ReCalcSize(). I don't know the reason why size of frame set by user is not persisting. Is there any way to store modified size of all children dynamically so? can u send some code for this?

Shrink window in GTK+ dynamically when content shrinks?

I have a window in a Vala application and an image inside it.
This image is changed sometimes by img.set_from_pixbuf(imgdata); and so it's size changes as well. It's embedded in a Gtk.Box.
box = new Gtk.Box(Orientation.VERTICAL,5);
...
box.pack_end(img,false,false);
So if there was a big image before and I replace it with a smaller one, the window remains ridiculously big and I have not found a method to dynamically shrink it to the space required.
I have tried with window.set_default_size(box.width_request,box.height_request) but it always returns -1.
So any ideas how to resize the window?
Thanks!
I have fought with this issue myself and while the accepted answer is correct, I though I could give a more "complete" answer, with working code.
Reproducing the problem
The following code (In C++, sorry) reproduces your issue:
#include <array>
#include <gtkmm.h>
class ResizableWindow : public Gtk::Window
{
public:
ResizableWindow()
: m_toggle{"Toggle"}
, m_currentImageIndex{0}
{
m_files[0] = "small.png";
m_files[1] = "large.png";
// Setup window layout:
m_layout.attach(*Gtk::manage(new Gtk::Image(m_files[m_currentImageIndex])), 0, 0, 1, 1);
m_layout.attach(m_toggle, 0, 1, 1, 1);
add(m_layout);
// Set up signal handlers:
m_toggle.signal_clicked().connect([this](){OnToggle();});
}
private:
void OnToggle()
{
// Switch image file:
if(m_currentImageIndex == 0)
{
m_currentImageIndex = 1;
}
else
{
m_currentImageIndex = 0;
}
// Load new image.
Gtk::Widget* child = m_layout.get_child_at(0, 0);
Gtk::Image* currentImage = dynamic_cast<Gtk::Image*>(child);
currentImage->set(m_files[m_currentImageIndex]);
}
Gtk::Grid m_layout;
Gtk::Button m_toggle;
std::array<std::string, 2> m_files;
size_t m_currentImageIndex;
};
int main (int argc, char* argv[])
{
auto app = Gtk::Application::create(argc, argv, "so.question.q8903140");
ResizableWindow w;
w.show_all();
return app->run(w);
}
The Toggle button changes the underlying images. Both are the same image, but with different sizes. Notice that, As you already mentionned, when toggling for the first time (small --> large), the window resizes appropriately. However, when toggling a second time (large --> small), the image is resized, but not the window, leaving extra space around the image:
Weird, I know...
Solution
To solve the issue, one needs to call the resize method. So the Toggle handler would become:
void OnToggle()
{
if(m_currentImageIndex == 0)
{
m_currentImageIndex = 1;
}
else
{
m_currentImageIndex = 0;
}
Gtk::Widget* child = m_layout.get_child_at(0, 0);
Gtk::Image* currentImage = dynamic_cast<Gtk::Image*>(child);
currentImage->set(m_files[m_currentImageIndex]);
// Resize window:
resize(1, 1);
}
Note that resize was called with dimensions 1x1 (smallest possible dimensions). Gtkmm will resize the window following geometry constraints automatically from there.
If I am not mistaken the automatic resizing of windows only only happens when elements are too large to be drawn. Additionally the set_default_size method only matters when first drawing the window and unless I am wrong is never used again. I would suggest using the resize method to set the window size. (link)
window.resize(box.width_request, box.height_request);
One thing you need to remember when using resize if you can't resize it smaller than the request_size if you run into that issue use the set_request_size method.

Resources