Ticket #619: POI-101022.diff

File POI-101022.diff, 13.8 KB (added by tryagain, 11 years ago)

Yet another revision of POI.diff. New changes are small in size but significant for usability.

  • navit/gui/internal/gui_internal.c

     
    7171#include "util.h"
    7272#include "bookmarks.h"
    7373#include "debug.h"
     74#include "fib.h"
    7475
    7576
    7677extern char *version;
     
    21772178        {"peak","Land Features",(enum item_type []){
    21782179                type_poi_land_feature,type_poi_rock,
    21792180                type_poi_dam,type_poi_dam,
     2181                type_poi_peak,type_poi_peak,
    21802182                type_none}},
    21812183        {"unknown","Other",(enum item_type []){
    21822184                type_point_unspecified,type_point_unkn-1,
     
    21902192                type_poi_mall+1,type_poi_personal_service-1,
    21912193                type_poi_restaurant+1,type_poi_restroom-1,
    21922194                type_poi_restroom+1,type_poi_shop_grocery-1,
    2193                 type_poi_shop_grocery+1,type_poi_motel-1,
    2194                 type_poi_hostel+1,type_selected_point,
     2195                type_poi_shop_grocery+1,type_poi_peak-1,
     2196                type_poi_peak+1, type_poi_motel-1,
     2197                type_poi_hostel+1,type_line-1,
    21952198                type_none}},
    21962199        {"unknown","Unknown",(enum item_type []){
    21972200                type_point_unkn,type_point_unkn,
    21982201                type_none}},
    21992202};
    22002203
     2204union poi_param {
     2205        guint i;
     2206        struct {
     2207                unsigned char sel, selnb, pagenb, dist;
     2208        } p;
     2209};
     2210
    22012211static void gui_internal_cmd_pois(struct gui_priv *this, struct widget *wm, void *data);
    22022212
    22032213static struct widget *
    2204 gui_internal_cmd_pois_selector(struct gui_priv *this, struct pcoord *c)
     2214gui_internal_cmd_pois_selector(struct gui_priv *this, struct pcoord *c, int pagenb)
    22052215{
    22062216        struct widget *wl,*wb;
    22072217        int i;
    22082218        wl=gui_internal_box_new(this, gravity_left_center|orientation_horizontal|flags_fill);
    22092219        for (i = 0 ; i < sizeof(selectors)/sizeof(struct selector) ; i++) {
    2210         gui_internal_widget_append(wl, wb=gui_internal_button_new_with_callback(this, NULL,
    2211                 image_new_xs(this, selectors[i].icon), gravity_left_center|orientation_vertical,
    2212                 gui_internal_cmd_pois, &selectors[i]));
     2220                union poi_param p;
     2221                p.p.sel = 1;
     2222                p.p.selnb = i;
     2223                p.p.pagenb = pagenb;
     2224                p.p.dist = 0;
     2225                gui_internal_widget_append(wl, wb=gui_internal_button_new_with_callback(this, NULL,
     2226                        image_new_xs(this, selectors[i].icon), gravity_left_center|orientation_vertical,
     2227                        gui_internal_cmd_pois, GUINT_TO_POINTER(p.i)));
    22132228                wb->c=*c;
    22142229                wb->bt=10;
    22152230        }
     
    22172232}
    22182233
    22192234static struct widget *
    2220 gui_internal_cmd_pois_item(struct gui_priv *this, struct coord *center, struct item *item, struct coord *c, int dist)
     2235gui_internal_cmd_pois_item(struct gui_priv *this, struct coord *center, struct item *item, struct coord *c, int dist, char* name)
    22212236{
    22222237        char distbuf[32];
    22232238        char dirbuf[32];
    22242239        char *type;
    2225         struct attr attr;
    22262240        struct widget *wl,*wt;
    22272241        char *text;
    22282242
    22292243        wl=gui_internal_box_new(this, gravity_left_center|orientation_horizontal|flags_fill);
    22302244
    2231         sprintf(distbuf,"%d", dist/1000);
     2245        if (dist > 10000)
     2246                sprintf(distbuf,"%d", dist/1000);
     2247        else
     2248                sprintf(distbuf,"%d.%d", dist/1000, (dist%1000)/100);
    22322249        get_direction(dirbuf, transform_get_angle_delta(center, c, 0), 1);
    22332250        type=item_to_name(item->type);
    2234         if (item_attr_get(item, attr_label, &attr)) {
    2235                 wl->name=g_strdup_printf("%s %s",type,attr.u.str);
     2251        if (name[0]) {
     2252                wl->name=g_strdup_printf("%s %s",type,name);
    22362253        } else {
    2237                 attr.u.str="";
    22382254                wl->name=g_strdup(type);
    22392255        }
    2240         text=g_strdup_printf("%s %s %s %s", distbuf, dirbuf, type, attr.u.str);
     2256        text=g_strdup_printf("%s %s %s %s", distbuf, dirbuf, type, name);
    22412257        wt=gui_internal_label_new(this, text);
    22422258        wt->datai=dist;
    22432259        gui_internal_widget_append(wl, wt);
     
    22842300
    22852301static void gui_internal_cmd_position(struct gui_priv *this, struct widget *wm, void *data);
    22862302
     2303struct item_data {
     2304        int dist;
     2305        char *label;
     2306        struct item item;
     2307        struct coord c;
     2308};
     2309
     2310/**
     2311 * @brief Event handler for POIs list "more" element.
     2312 *
     2313 * @param this The graphics context.
     2314 * @param wm called widget.
     2315 * @param data event data.
     2316 */
     2317static void
     2318gui_internal_cmd_pois_more(struct gui_priv *this, struct widget *wm, void *data)
     2319{
     2320        struct widget *w=g_new0(struct widget,1);
     2321        w->data=wm->data;
     2322        w->c=wm->c;
     2323        w->w=wm->w;
     2324        gui_internal_back(this, NULL, NULL);
     2325        gui_internal_cmd_pois(this, w, NULL);
     2326        free(w);
     2327}
     2328
     2329
    22872330static void
    22882331gui_internal_cmd_pois(struct gui_priv *this, struct widget *wm, void *data)
    22892332{
     
    22932336        struct map *m;
    22942337        struct map_rect *mr;
    22952338        struct item *item;
    2296         int idist,dist=20000;
    2297         struct widget *wi,*w,*w2,*wb;
     2339        struct widget *wi,*w,*w2,*wb, *wtable, *row;
    22982340        enum projection pro=wm->c.pro;
    2299         struct selector *isel=wm->data;
     2341        union poi_param param = {.i = GPOINTER_TO_UINT(wm->data)};
     2342        int idist,dist=10000*(param.p.dist+1);
     2343        struct selector *isel = param.p.sel? &selectors[param.p.selnb]: NULL;
     2344        int pagenb = param.p.pagenb;
     2345        int prevdist=param.p.dist*10000;
     2346        const int pagesize = 50; // Starting value and increment of count of items to be extracted
     2347        int maxitem = pagesize*(pagenb+1), it = 0, i;
     2348        struct item_data *items= g_new0( struct item_data, maxitem);
     2349        struct fibheap* fh = fh_makekeyheap();
     2350        int cnt = 0;
     2351        struct table_data *td;
     2352        int width=wm->w;
     2353        dbg(2, "Params: sel = %i, selnb = %i, pagenb = %i, dist = %i\n",
     2354                param.p.sel, param.p.selnb, param.p.pagenb, param.p.dist);
    23002355
    23012356        wb=gui_internal_menu(this, isel ? isel->name : _("POIs"));
    23022357        w=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill);
    23032358        gui_internal_widget_append(wb, w);
    2304         if (! isel)
    2305                 gui_internal_widget_append(w, gui_internal_cmd_pois_selector(this,&wm->c));
     2359        if (!isel)
     2360                gui_internal_widget_append(w, gui_internal_cmd_pois_selector(this,&wm->c,pagenb));
    23062361        w2=gui_internal_box_new(this, gravity_top_center|orientation_vertical|flags_expand|flags_fill);
    23072362        gui_internal_widget_append(w, w2);
    23082363
    2309         sel=map_selection_rect_new(&wm->c, dist, 18);
     2364        sel=map_selection_rect_new(&wm->c,dist*transform_scale(wm->c.y),18);
    23102365        center.x=wm->c.x;
    23112366        center.y=wm->c.y;
    23122367        h=mapset_open(navit_get_mapset(this->nav));
     
    23182373                        while ((item=map_rect_get_item(mr))) {
    23192374                                if (gui_internal_cmd_pois_item_selected(isel, item->type) &&
    23202375                                    item_coord_get_pro(item, &c, 1, pro) &&
    2321                                     coord_rect_contains(&sel->u.c_rect, &c) &&
     2376                                    coord_rect_contains(&sel->u.c_rect, &c)  &&
    23222377                                    (idist=transform_distance(pro, &center, &c)) < dist) {
    2323                                         gui_internal_widget_append(w2, wi=gui_internal_cmd_pois_item(this, &center, item, &c, idist));
    2324                                         wi->func=gui_internal_cmd_position;
    2325                                         wi->data=(void *)2;
    2326                                         wi->item=*item;
    2327                                         wi->state |= STATE_SENSITIVE;
    2328                                         wi->c.x=c.x;
    2329                                         wi->c.y=c.y;
    2330                                         wi->c.pro=pro;
     2378                                        struct item_data *data;
     2379                                        struct attr attr;
     2380                                        if(it>=maxitem) {
     2381                                                data = fh_extractmin(fh);
     2382                                                free(data->label);
     2383                                                data->label=NULL;
     2384                                        } else {
     2385                                                data = &items[it++];
     2386                                        }
     2387                                        data->item = *item;
     2388                                        data->c = c;
     2389                                        data->dist = idist;
     2390                                        if (item_attr_get(item, attr_label, &attr)) {
     2391                                                //strncpy(data->label, attr.u.str, sizeof(data->label));
     2392                                                data->label=g_strdup(attr.u.str);
     2393                                        } else {
     2394                                                //data->label[0] = 0;
     2395                                                data->label=g_strdup("");
     2396                                        }
     2397                                        // Key expression is a workaround to fight
     2398                                        // probable heap collisions when two objects
     2399                                        // are at the same distance. But it destroys
     2400                                        // right order of POIs 2048 km away from cener
     2401                                        // and if table grows more than 1024 rows.
     2402                                        fh_insertkey(fh, -((idist<<10) + cnt++), data);
     2403                                        if (it == maxitem)
     2404                                                dist = (-fh_minkey(fh))>>10;
    23312405                                }
    23322406                        }
    23332407                        map_rect_destroy(mr);
     
    23362410        }
    23372411        map_selection_destroy(sel);
    23382412        mapset_close(h);
    2339         w2->children=g_list_sort_with_data(w2->children,  gui_internal_cmd_pois_sort_num, (void *)1);
     2413       
     2414        wtable = gui_internal_widget_table_new(this,gravity_left_top | flags_fill | flags_expand |orientation_vertical,1);
     2415        td=wtable->data;
     2416
     2417        gui_internal_widget_append(w2,wtable);
     2418
     2419        // Move items from heap to the table
     2420        for(i=0;;i++)
     2421        {
     2422                int key = fh_minkey(fh);
     2423                struct item_data *data = fh_extractmin(fh);
     2424                if (data == NULL)
     2425                {
     2426                        dbg(2, "Empty heap: maxitem = %i, it = %i, dist = %i\n", maxitem, it, dist);
     2427                        break;
     2428                }
     2429                dbg(2, "dist1: %i, dist2: %i\n", data->dist, (-key)>>10);
     2430                if(i==(it-pagesize*pagenb) && data->dist>prevdist)
     2431                        prevdist=data->dist;
     2432                wi=gui_internal_cmd_pois_item(this, &center, &data->item, &data->c, data->dist, data->label);
     2433                wi->func=gui_internal_cmd_position;
     2434                wi->data=(void *)2;
     2435                wi->item=data->item;
     2436                wi->state |= STATE_SENSITIVE;
     2437                wi->c.x=data->c.x;
     2438                wi->c.y=data->c.y;
     2439                wi->c.pro=pro;
     2440                wi->w=width;
     2441                row = gui_internal_widget_table_row_new(this,
     2442                                                          gravity_left
     2443                                                          | flags_fill
     2444                                                          | orientation_horizontal);
     2445                row->children=g_list_append(row->children,wi);
     2446                row->datai=data->dist;
     2447                gui_internal_widget_prepend(wtable,row);
     2448                free(data->label);
     2449        }
     2450
     2451        fh_deleteheap(fh);
     2452        free(items);
     2453
     2454        // Add an entry for more POI
     2455        struct widget *wl,*wt;
     2456        char buffer[32];
     2457        wl=gui_internal_box_new(this, gravity_left_center|orientation_horizontal|flags_fill);
     2458        if (it == maxitem) {
     2459                param.p.pagenb++;
     2460                snprintf(buffer, sizeof(buffer), "Get more (up to %d items)...", (param.p.pagenb+1)*pagesize);
     2461        } else {
     2462                param.p.dist++;
     2463                snprintf(buffer, sizeof(buffer), "Set search distance to %i km", 10*(param.p.dist+1));
     2464        }
     2465        wt=gui_internal_label_new(this, buffer);
     2466        gui_internal_widget_append(wl, wt);
     2467        wl->func=gui_internal_cmd_pois_more;
     2468        wl->data=GUINT_TO_POINTER(param.i);
     2469        wl->state |= STATE_SENSITIVE;
     2470        wl->c = wm->c;
     2471        row = gui_internal_widget_table_row_new(this,
     2472                                                  gravity_left
     2473                                                  | flags_fill
     2474                                                  | orientation_horizontal);
     2475        row->children=g_list_append(row->children,wl);
     2476        row->datai=100000000; // Really far away for Earth, but won't work for bigger planets.
     2477        gui_internal_widget_append(wtable,row);
     2478
     2479        // Rendering now is needed to have table_data->bottomrow filled in.
    23402480        gui_internal_menu_render(this);
     2481        td=wtable->data;
     2482        if(td->bottom_row!=NULL)
     2483        {
     2484                while(((struct widget*)td->bottom_row->data)->datai<=prevdist
     2485                                && (td->next_button->state & STATE_SENSITIVE))
     2486                {
     2487                        gui_internal_table_button_next(this, td->next_button, NULL);
     2488                }
     2489        }
     2490        gui_internal_menu_render(this);
     2491
    23412492}
    23422493
    23432494static void
     
    27002851                flags=8|16|32|64|256;
    27012852                break;
    27022853        case 2:
    2703                 flags=4|8|16|32|64;
     2854                flags=4|8|16|32|64|128;
    27042855                break;
    27052856        case 3:
    27062857                flags=1|8|16|32|64|128;
     
    51565307        widget->data_free=gui_internal_table_data_free;
    51575308        data = (struct table_data*)widget->data;
    51585309
    5159 
    51605310        if (buttons) {
    51615311        data->next_button = gui_internal_button_new_with_callback
    51625312                (this,"Next",image_new_xs(this, "gui_active") ,
     
    54105560
    54115561}
    54125562
    5413 
     5563/**
     5564 * @brief Invalidates coordinates for previosly rendered table widget rows.
     5565 *
     5566 * @param table_data Data from the table object.
     5567 */
     5568void gui_internal_table_hide_rows(struct table_data * table_data)
     5569{
     5570        GList*cur_row;
     5571        for(cur_row=table_data->top_row; cur_row ; cur_row = g_list_next(cur_row))
     5572        {
     5573                struct widget * cur_row_widget = (struct widget*)cur_row->data;
     5574                if (cur_row_widget->type!=widget_table_row)
     5575                        continue;
     5576                cur_row_widget->p.x=0;
     5577                cur_row_widget->p.y=0;
     5578                cur_row_widget->w=0;
     5579                cur_row_widget->h=0;
     5580                if(cur_row==table_data->bottom_row)
     5581                        break;
     5582        }
     5583}
    54145584
    54155585/**
    54165586 * @brief Renders a table widget.
     
    54345604        dbg_assert(table_data);
    54355605        column_desc = gui_internal_compute_table_dimensions(this,w);
    54365606        y=w->p.y;
    5437 
     5607        gui_internal_table_hide_rows(table_data);
    54385608        /**
    54395609         * Skip rows that are on previous pages.
    54405610         */
     
    54445614                cur_row = table_data->top_row;
    54455615                is_first_page=0;
    54465616        }
    5447 
    5448 
    54495617        /**
    54505618         * Loop through each row.  Drawing each cell with the proper sizes,
    54515619         * at the proper positions.
     
    54705638                         */
    54715639                        is_skipped=1;
    54725640                        break;
    5473 
    54745641                }
    54755642                for(cur_column = cur_row_widget->children; cur_column;
    54765643                    cur_column=g_list_next(cur_column))
     
    54955662                                max_height = dim->height;
    54965663                        }
    54975664                }
     5665               
     5666                /* Row object should have its coordinates in actual
     5667                 * state to be able to pass mouse clicks to Column objects
     5668                 */
     5669                cur_row_widget->p.x=w->p.x;
     5670                cur_row_widget->w=w->w;
     5671                cur_row_widget->p.y=y;
     5672                cur_row_widget->h=max_height;
    54985673                y = y + max_height;
    54995674                table_data->bottom_row=cur_row;
    55005675                current_desc = g_list_next(current_desc);
     
    55145689                //    table_data->prev_button->h=table_data->button_box->h;
    55155690                //    table_data->next_button->c.y=table_data->button_box->c.y;
    55165691                //    table_data->prev_button->c.y=table_data->button_box->c.y;
    5517 
    55185692                gui_internal_widget_pack(this,table_data->button_box);
    55195693                if(table_data->next_button->p.y > w->p.y + w->h + table_data->next_button->h)
    55205694                {
    5521 
    55225695                        table_data->button_box->p.y = w->p.y + w->h -
    55235696                                table_data->button_box->h;
    55245697                }
     
    59956168                        table_data->page_headers=g_list_append(table_data->page_headers,
    59966169                                                               table_data->top_row);
    59976170                }
    5998 
    5999                 table_data->top_row = g_list_next(table_data->bottom_row);
     6171                /**
     6172                 * Invalidate row coordinates for all rows which were previously rendered
     6173                 
     6174                for(iterator=table_data->top_row; iterator && table_data->rows_on_page; iterator = g_list_next(iterator))
     6175                {
     6176                        struct widget * cur_row_widget = (struct widget*)iterator->data;
     6177                        cur_row_widget->p.x=-1;
     6178                        cur_row_widget->p.y=-1;
     6179                        cur_row_widget->w=0;
     6180                        cur_row_widget->h=0;
     6181                        table_data->rows_on_page--;
     6182                }
     6183                */
     6184                gui_internal_table_hide_rows(table_data);
     6185                table_data->top_row=g_list_next(table_data->bottom_row);
    60006186        }
    60016187        wm->state&= ~STATE_HIGHLIGHTED;
    60026188        gui_internal_menu_render(this);
     
    60246210                table_data = (struct table_data*) table_widget->data;
    60256211                if(table_data)
    60266212                {
     6213                        gui_internal_table_hide_rows(table_data);
    60276214                        current_page_top = table_data->top_row;
    60286215                        for(iterator = table_data->page_headers; iterator != NULL;
    60296216                            iterator = g_list_next(iterator))
  • navit/gui/internal/Makefile.am

    old new  
    11include $(top_srcdir)/Makefile.inc
    2 AM_CPPFLAGS = -I$(top_srcdir)/navit @NAVIT_CFLAGS@ -DMODULE=gui_internal
     2AM_CPPFLAGS = -I$(top_srcdir)/navit -I$(top_srcdir)/navit/fib-1.1 @NAVIT_CFLAGS@ -DMODULE=gui_internal
    33if PLUGINS
    44modulegui_LTLIBRARIES = libgui_internal.la
    55else