Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix:gui/internal:Handling resize/rotation #682

Merged
merged 28 commits into from
Jan 30, 2019
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
60804d6
Handling resize for boxes
lains Oct 5, 2018
2b49f03
Fixing indentation to comply to guidelines
lains Oct 7, 2018
884a915
Handling resize differently on menus (reloading the whole menu instea…
lains Oct 13, 2018
76de75b
Merge branch 'trunk' into fixing_resize
lains Oct 13, 2018
29a4b09
Fixing previous merge
lains Oct 13, 2018
4886c93
Fixing compilation warning and indentation according to style
lains Oct 14, 2018
59948f0
Cleanup and doxygen doc
lains Oct 15, 2018
91a8f7a
Adding virtual keyboard resize handler, improving resize for menu topbox
lains Oct 29, 2018
b8ae292
Adding virtual keyboard resize handler, improving resize for menu topbox
lains Oct 29, 2018
9b01401
Fixing indentation for sanity check
lains Oct 29, 2018
73a54c3
Merge branch 'trunk' into fixing_resize
lains Oct 29, 2018
23e8434
Adding declaration of gui_internal_box_resize() in headers
lains Oct 29, 2018
91e6a05
Repacking virtual keyboard box on resize events
lains Nov 5, 2018
7562c5a
Creating gui_internal_menu_needs_resizing() function from existing code
lains Nov 16, 2018
081fa13
Forcing resize when display is resized then the user goes back in sub…
lains Nov 16, 2018
c255e9c
Fixing indentation
lains Nov 17, 2018
69d43fc
Fixing indentation
lains Nov 17, 2018
534c50e
Fixing indentation
lains Nov 17, 2018
0adf12a
Fixing bug that has been inserted during re-indentation
lains Nov 17, 2018
b51f7a9
Removing debug logs, adding doxygen comments
lains Nov 19, 2018
2ed7bc8
Reverting unrelated changes committed by mistake
lains Nov 19, 2018
3e781f1
Merge branch 'trunk' into fixing_resize
lains Nov 19, 2018
8b81d29
Moving debugging logs to lvl_debug
lains Nov 19, 2018
93d74f9
Fixing redraw of menus when going back from a submenu (if no window r…
lains Nov 20, 2018
e5bd1d5
Removing unused code
lains Nov 26, 2018
9a71d6d
Moving widget-related swap and move functions to gui_internal_widget.c
lains Nov 26, 2018
f6a1102
Fixing indentation
lains Nov 26, 2018
caab250
Cleanup
lains Nov 26, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 37 additions & 13 deletions navit/gui/internal/gui_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ gui_internal_time_help(struct gui_priv *this) {
/**
* Applies the configuration values to this based on the settings
* specified in the configuration file (this->config) and
* the most approriate default profile based on screen resolution.
* the most appropriate default profile based on screen resolution.
*
* This function should be run after this->root is setup and could
* be rerun after the window is resized.
Expand Down Expand Up @@ -2679,20 +2679,28 @@ static void gui_internal_setup(struct gui_priv *this) {
g_free(gui_file);
}

//##############################################################################################################
//# Description:
//# Comment:
//# Authors: Martin Schaller (04/2008)
//##############################################################################################################
static void gui_internal_resize(void *data, int w, int h) {
/**
* @brief Callback function invoked when display area is resized
*
* @param data A generic argument structure pointer, here we use it to store the the internal GUI context (this)
* @param wnew The new width of the display area
* @param hnew The new height of the display area
*
* @author Martin Schaller
* @date 2008/04
*/
static void gui_internal_resize(void *data, int wnew, int hnew) {
GList *l;
struct widget *w;

struct gui_priv *this=data;
int changed=0;

gui_internal_setup(this);

if (this->root.w != w || this->root.h != h) {
this->root.w=w;
this->root.h=h;
if (this->root.w != wnew || this->root.h != hnew) {
this->root.w=wnew;
this->root.h=hnew;
changed=1;
}
/*
Expand All @@ -2701,11 +2709,27 @@ static void gui_internal_resize(void *data, int w, int h) {
*/
if (!changed && this->gra && graphics_get_data(this->gra, "padding"))
changed = 1;
dbg(lvl_debug,"w=%d h=%d children=%p", w, h, this->root.children);
navit_handle_resize(this->nav, w, h);
dbg(lvl_debug,"w=%d h=%d children=%p", wnew, hnew, this->root.children);
navit_handle_resize(this->nav, wnew, hnew);
if (this->root.children) {
if (changed) {
gui_internal_html_main_menu(this);
l = g_list_last(this->root.children);
if (l) {
w=l->data;
void (*redisplay)(struct gui_priv *priv, struct widget *widget, void *data);
redisplay=w->menu_data->redisplay;
dbg(lvl_error, "redisplay%c=NULL", redisplay?'!':'=');
if (!gui_internal_widget_reload_href(this,
w)) { /* If the foremost widget is a HTML menu, reload & redraw it from its href */
/* If not, resize the foremost widget */
dbg(lvl_error, "Current GUI displayed is not a menu");
dbg(lvl_error, "Will call resize with w=%d, h=%d", wnew, hnew)
gui_internal_menu_resize(this, wnew, hnew);
gui_internal_menu_render(this);
}
} else {
dbg(lvl_error,"Current GUI displayed is a menu");
}
} else {
gui_internal_menu_render(this);
}
Expand Down
14 changes: 14 additions & 0 deletions navit/gui/internal/gui_internal_keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,17 @@ struct gui_internal_keyb_mode {
-> datai = (mode & VKBD_MASK_7) | ((x) & VKBD_LAYOUT_MASK)
#define SWCASE() MODE(gui_internal_keyb_modes[mode/8].case_mode)
#define UMLAUT() MODE(gui_internal_keyb_modes[mode/8].umlaut_mode)

static void gui_internal_keyboard_topbox_resize(struct gui_priv *this, struct widget *w, void *data,
int neww, int newh) {
struct menu_data *md=gui_internal_menu_data(this);
struct widget *old_wkbdb = md->keyboard;

dbg(lvl_error, "gui_internal_keyboard_topbox_resize called on %p with w=%d, h=%d", w, neww, newh);
dbg(lvl_error, "old keyboard widget was at %p", old_wkbdb);
gui_internal_keyboard_do(this, old_wkbdb, md->keyboard_mode);
}

/**
* @brief Creates a new keyboard widget or switches the layout of an existing widget
*
Expand Down Expand Up @@ -167,6 +178,8 @@ gui_internal_keyboard_do(struct gui_priv *this, struct widget *wkbdb, int mode)
else
render=1;
gui_internal_widget_children_destroy(this, wkbdb);
gui_internal_widget_reset_pack(this, wkbdb);
gui_internal_widget_pack(this, wkbdb);
} else
wkbdb=gui_internal_box_new(this, gravity_center|orientation_horizontal_vertical|flags_fill);
md->keyboard=wkbdb;
Expand All @@ -176,6 +189,7 @@ gui_internal_keyboard_do(struct gui_priv *this, struct widget *wkbdb, int mode)
wkbd->cols=8;
wkbd->spx=0;
wkbd->spy=0;
wkbd->on_resize=gui_internal_keyboard_topbox_resize;
max_w=max_w/8;
max_h=max_h/8; // Allows 3 results in the list when searching for Towns
wkbd->p.y=max_h*2;
Expand Down
155 changes: 105 additions & 50 deletions navit/gui/internal/gui_internal_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

extern char *version;

static void gui_internal_menu_destroy(struct gui_priv *this, struct widget *w) {
void gui_internal_menu_destroy(struct gui_priv *this, struct widget *w) {
struct menu_data *menu_data=w->menu_data;
if (menu_data) {
if (menu_data->refresh_callback_obj.type) {
Expand All @@ -36,10 +36,53 @@ static void gui_internal_menu_destroy(struct gui_priv *this, struct widget *w) {
this->root.children=g_list_remove(this->root.children, w);
}

/**
* @brief Retrieve then html anchor (href) from a menu widger
*
* @param w A widget corresponding to a menu (this widget should be an html menu)
*
* @return the string for the href, or NULL if this menu has no href (or the widget is not a menu)
*/
static char *gui_internal_widget_get_href(struct widget *w) {
if (w && w->menu_data)
return w->menu_data->href;
else
return NULL;
}

/**
* @brief Reload a menu from its anchor (href)
*
* @param this The internal GUI context
* @param w A widget corresponding to the menu to redraw (this widget should be an html menu, thus it should have a href)
*
* @return 1 in case of success, 0 if no menu could be reloaded
* @note If the widget provided in @p w has no href, we will return 0
*/
int gui_internal_widget_reload_href(struct gui_priv *this, struct widget *w) {
char *ohref = gui_internal_widget_get_href(w);
if (ohref) {
char *href=g_strdup(ohref);
gui_internal_menu_destroy(this, w);
gui_internal_html_load_href(this, href, 0);
g_free(href);
return 1;
}
return 0;
}

/**
* @brief Destroy (discard) all menu screens that have been placed after widget @p w
*
* @param this The internal GUI context
* @param w A widget corresponding to the last menu to keep (all subsequent menus in the list will be destroyed). NULL if all menus should be destroyed.
* @param render whether we should render the menu indicated by widget w (render!=0) or not (render==0)
*/
static void gui_internal_prune_menu_do(struct gui_priv *this, struct widget *w, int render) {
GList *l;
struct widget *wr,*wd;
gui_internal_search_idle_end(this);
/* Destroy all menus, backwards, starting from the end until we reach widget w, and redraw widget w */
while ((l = g_list_last(this->root.children))) {
wd=l->data;
if (wd == w) {
Expand All @@ -49,18 +92,15 @@ static void gui_internal_prune_menu_do(struct gui_priv *this, struct widget *w,
gui_internal_say(this, w, 0);
redisplay=w->menu_data->redisplay;
wr=w->menu_data->redisplay_widget;
if (!w->menu_data->redisplay && !w->menu_data->href) {
if (!redisplay && !gui_internal_widget_get_href(w)) {
gui_internal_widget_render(this, w);
return;
}
if (redisplay) {
gui_internal_menu_destroy(this, w);
redisplay(this, wr, wr->data);
} else {
char *href=g_strdup(w->menu_data->href);
gui_internal_menu_destroy(this, w);
gui_internal_html_load_href(this, href, 0);
g_free(href);
gui_internal_widget_reload_href(this, w);
}
return;
}
Expand All @@ -83,6 +123,34 @@ void gui_internal_prune_menu_count(struct gui_priv *this, int count, int render)
}
}

void gui_internal_menu_topbox_resize(struct gui_priv *this, struct widget *w, void *data, int neww, int newh) {
w->w=neww;
w->h=newh;
gui_internal_box_resize(this, w, data, w->w, w->h);
/* Note: this widget and its children have been resized, a call to gui_internal_box_render() needs to be done by the caller */
}

void gui_internal_menu_menu_resize(struct gui_priv *this, struct widget *w, void *data, int neww, int newh) {
struct padding *padding = NULL;

if (this->gra) {
padding = graphics_get_data(this->gra, "padding");
} else
dbg(lvl_warning, "cannot get padding: this->gra is NULL");
if (padding) {
w->p.x = padding->left;
w->p.y = padding->top;
w->w = neww - padding->left - padding->right;
w->h = newh - padding->top - padding->bottom;
} else {
w->p.x = 0;
w->p.y = 0;
w->w = neww;
w->h = newh;
}
gui_internal_box_resize(this, w, data, w->w, w->h);
/* Note: this widget and its children have been resized, a call to gui_internal_box_render() needs to be done by the caller */
}

/**
* @brief Initializes a GUI screen
Expand All @@ -101,31 +169,15 @@ void gui_internal_prune_menu_count(struct gui_priv *this, int count, int render)
struct widget *
gui_internal_menu(struct gui_priv *this, const char *label) {
struct widget *menu,*w,*w1,*topbox;
struct padding *padding = NULL;

if (this->gra) {
padding = graphics_get_data(this->gra, "padding");
} else
dbg(lvl_warning, "cannot get padding: this->gra is NULL");

gui_internal_search_idle_end(this);
topbox=gui_internal_box_new_with_label(this, 0, label);
topbox->w=this->root.w;
topbox->h=this->root.h;
topbox->on_resize=gui_internal_menu_topbox_resize;
gui_internal_widget_append(&this->root, topbox);
menu=gui_internal_box_new(this, gravity_left_center|orientation_vertical);

if (padding) {
menu->p.x = padding->left;
menu->p.y = padding->top;
menu->w = topbox->w - padding->left - padding->right;
menu->h = topbox->h - padding->top - padding->bottom;
} else {
menu->p.x = 0;
menu->p.y = 0;
menu->w = topbox->w;
menu->h = topbox->h;
}
menu->on_resize=gui_internal_menu_menu_resize;
topbox->on_resize(this, topbox, NULL, this->root.w, this->root.h);
menu->on_resize(this, menu, NULL, topbox->w, topbox->h);
menu->background=this->background;
gui_internal_apply_config(this);
topbox->menu_data=g_new0(struct menu_data, 1);
Expand Down Expand Up @@ -156,17 +208,8 @@ gui_internal_menu(struct gui_priv *this, const char *label) {
}
if (this->flags & 192) {
menu=gui_internal_box_new(this, gravity_left_center|orientation_vertical);
if (padding) {
menu->p.x = padding->left;
menu->p.y = padding->top;
menu->w = topbox->w - padding->left - padding->right;
menu->h = topbox->h - padding->top - padding->bottom;
} else {
menu->p.x = 0;
menu->p.y = 0;
menu->w = topbox->w;
menu->h = topbox->h;
}
menu->on_resize=gui_internal_menu_menu_resize;
menu->on_resize(this, menu, NULL, topbox->w, topbox->h);
w1=gui_internal_time_help(this);
gui_internal_widget_append(menu, w1);
w1=gui_internal_box_new(this, gravity_center|orientation_horizontal_vertical|flags_expand|flags_fill);
Expand All @@ -176,19 +219,10 @@ gui_internal_menu(struct gui_priv *this, const char *label) {
}
gui_internal_widget_pack(this, topbox);
gui_internal_widget_reset_pack(this, topbox);
topbox->w=this->root.w;
topbox->h=this->root.h;
if (padding) {
menu->p.x = padding->left;
menu->p.y = padding->top;
menu->w = topbox->w - padding->left - padding->right;
menu->h = topbox->h - padding->top - padding->bottom;
} else {
menu->p.x = 0;
menu->p.y = 0;
menu->w = topbox->w;
menu->h = topbox->h;
}
if (topbox->on_resize)
topbox->on_resize(this, topbox, NULL, this->root.w, this->root.h);
if (menu->on_resize)
menu->on_resize(this, menu, NULL, topbox->w, topbox->h);
return w;
}

Expand All @@ -211,6 +245,14 @@ void gui_internal_menu_reset_pack(struct gui_priv *this) {
gui_internal_widget_reset_pack(this, top_box);
}

/**
* @brief Renders a menu GUI on the display
*
* @note The whole sequence of menus is kept in this->root.children (when going back one page, we just move to the previous child in the list)
* Thus, only the last child of this->root.children is actually displayed
*
* @param this The internal GUI context
*/
void gui_internal_menu_render(struct gui_priv *this) {
GList *l;
struct widget *menu;
Expand All @@ -222,6 +264,19 @@ void gui_internal_menu_render(struct gui_priv *this) {
gui_internal_widget_render(this, menu);
}

void gui_internal_menu_resize(struct gui_priv *this, int w, int h) {
GList *l;
struct widget *menu_topwidget;

gui_internal_apply_config(this);
l=g_list_last(this->root.children);
menu_topwidget=l->data;
if (menu_topwidget->on_resize) {
dbg(lvl_error, "Invoking resize handler for menu_topwidget at %p", menu_topwidget);
menu_topwidget->on_resize(this, menu_topwidget, NULL, this->root.w, this->root.h);
}
}

struct widget *
gui_internal_top_bar(struct gui_priv *this) {
struct widget *w,*wm,*wh,*wc,*wcn;
Expand Down
5 changes: 5 additions & 0 deletions navit/gui/internal/gui_internal_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@
struct gui_priv;
struct menu_data;
struct widget;
void gui_internal_menu_destroy(struct gui_priv *this, struct widget *w);
int gui_internal_widget_reload_href(struct gui_priv *this, struct widget *w);
void gui_internal_prune_menu(struct gui_priv *this, struct widget *w);
void gui_internal_prune_menu_count(struct gui_priv *this, int count, int render);
void gui_internal_menu_topbox_resize(struct gui_priv *this, struct widget *w, void *data, int neww, int newh);
void gui_internal_menu_menu_resize(struct gui_priv *this, struct widget *w, void *data, int neww, int newh);
struct widget *gui_internal_menu(struct gui_priv *this, const char *label);
struct menu_data *gui_internal_menu_data(struct gui_priv *this);
void gui_internal_menu_reset_pack(struct gui_priv *this);
void gui_internal_menu_render(struct gui_priv *this);
void gui_internal_menu_resize(struct gui_priv *this, int w, int h);
struct widget *gui_internal_top_bar(struct gui_priv *this);
/* end of prototypes */
Loading