Ticket #619: POI-101020.diff

File POI-101020.diff, 13.7 KB (added by tryagain, 11 years ago)

Minor fix-up of my previous post.

  • 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,
     2195                type_poi_shop_grocery+1,type_poi_peak-1,
     2196                type_poi_peak+1, type_poi_motel-1,
    21942197                type_poi_hostel+1,type_selected_point,
    21952198                type_none}},
    21962199        {"unknown","Unknown",(enum item_type []){
     
    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);
     2258
    22422259        wt->datai=dist;
    22432260        gui_internal_widget_append(wl, wt);
    22442261        g_free(text);
     
    22842301
    22852302static void gui_internal_cmd_position(struct gui_priv *this, struct widget *wm, void *data);
    22862303
     2304struct item_data {
     2305        int dist;
     2306        char label[32];
     2307        struct item item;
     2308        struct coord c;
     2309};
     2310
     2311/**
     2312 * @brief Event handler for POIs list "more" element.
     2313 *
     2314 * @param this The graphics context.
     2315 * @param wm called widget.
     2316 * @param data event data.
     2317 */
     2318static void
     2319gui_internal_cmd_pois_more(struct gui_priv *this, struct widget *wm, void *data)
     2320{
     2321        struct widget *w=g_new0(struct widget,1);
     2322        w->data=wm->data;
     2323        w->c=wm->c;
     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        int rowstoskip=0;
     2347        const int pagesize = 50; // Starting value and increment of count of items to be extracted
     2348        int maxitem = pagesize*(pagenb+1), it = 0, i;
     2349        struct item_data *items= g_new0( struct item_data, maxitem);
     2350        struct fibheap* fh = fh_makekeyheap();
     2351        int cnt = 0;
     2352        struct table_data *td;
     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                                        } else {
     2383                                                data = &items[it++];
     2384                                        }
     2385                                        data->item = *item;
     2386                                        data->c = c;
     2387                                        data->dist = idist;
     2388                                        if (item_attr_get(item, attr_label, &attr)) {
     2389                                                strncpy(data->label, attr.u.str, sizeof(data->label));
     2390                                        } else {
     2391                                                data->label[0] = 0;
     2392                                        }
     2393                                        // Key expression is a workaround to fight
     2394                                        // probable heap collisions when two objects
     2395                                        // are at the same distance. But it destroys
     2396                                        // right order of POIs 2048 km away from cener
     2397                                        // and if table grows more than 1024 rows.
     2398                                        fh_insertkey(fh, -((idist<<10) + cnt++), data);
     2399                                        if (it == maxitem)
     2400                                                dist = (-fh_minkey(fh))>>10;
    23312401                                }
    23322402                        }
    23332403                        map_rect_destroy(mr);
     
    23362406        }
    23372407        map_selection_destroy(sel);
    23382408        mapset_close(h);
    2339         w2->children=g_list_sort_with_data(w2->children,  gui_internal_cmd_pois_sort_num, (void *)1);
     2409       
     2410        wtable = gui_internal_widget_table_new(this,gravity_left_top | flags_fill | flags_expand |orientation_vertical,1);
     2411        td=wtable->data;
     2412
     2413        gui_internal_widget_append(w2,wtable);
     2414        wtable->w=w2->w;
     2415
     2416        // Move items from heap to the table
     2417        for(i=0;;i++)
     2418        {
     2419                int key = fh_minkey(fh);
     2420                struct item_data *data = fh_extractmin(fh);
     2421                if (data == NULL)
     2422                {
     2423                        dbg(2, "Empty heap: maxitem = %i, it = %i, dist = %i\n", maxitem, it, dist);
     2424                        break;
     2425                }
     2426                dbg(2, "dist1: %i, dist2: %i\n", data->dist, (-key)>>10);
     2427                if(i==(it-pagesize*pagenb) && data->dist>prevdist)
     2428                        prevdist=data->dist;
     2429                wi=gui_internal_cmd_pois_item(this, &center, &data->item, &data->c, data->dist, data->label);
     2430                wi->func=gui_internal_cmd_position;
     2431                wi->data=(void *)2;
     2432                wi->item=data->item;
     2433                wi->state |= STATE_SENSITIVE;
     2434                wi->c.x=data->c.x;
     2435                wi->c.y=data->c.y;
     2436                wi->c.pro=pro;
     2437                row = gui_internal_widget_table_row_new(this,
     2438                                                          gravity_left
     2439                                                          | flags_fill
     2440                                                          | orientation_horizontal);
     2441                row->children=g_list_append(row->children,wi);
     2442                row->datai=data->dist;
     2443                gui_internal_widget_prepend(wtable,row);
     2444        }
     2445
     2446        fh_deleteheap(fh);
     2447        free(items);
     2448
     2449        // Add an entry for more POI
     2450        struct widget *wl,*wt;
     2451        char buffer[32];
     2452        wl=gui_internal_box_new(this, gravity_left_center|orientation_horizontal|flags_fill);
     2453        if (it == maxitem) {
     2454                param.p.pagenb++;
     2455                snprintf(buffer, sizeof(buffer), "Get more (up to %d items)...", (param.p.pagenb+1)*pagesize);
     2456        } else {
     2457                param.p.dist++;
     2458                snprintf(buffer, sizeof(buffer), "Set search distance to %i km", 10*(param.p.dist+1));
     2459        }
     2460        wt=gui_internal_label_new(this, buffer);
     2461        gui_internal_widget_append(wl, wt);
     2462        wl->func=gui_internal_cmd_pois_more;
     2463        wl->data=GUINT_TO_POINTER(param.i);
     2464        wl->state |= STATE_SENSITIVE;
     2465        wl->c = wm->c;
     2466        row = gui_internal_widget_table_row_new(this,
     2467                                                  gravity_left
     2468                                                  | flags_fill
     2469                                                  | orientation_horizontal);
     2470        row->children=g_list_append(row->children,wl);
     2471        row->datai=100000; // Really far away for Earth, but won't work for bigger planets.
     2472        gui_internal_widget_append(wtable,row);
     2473
     2474        // Rendering now is needed to have table_data->bottomrow filled in.
    23402475        gui_internal_menu_render(this);
     2476        td=wtable->data;
     2477        if(td->bottom_row!=NULL)
     2478        {
     2479                while(((struct widget*)td->bottom_row->data)->datai<=prevdist
     2480                                && (td->next_button->state & STATE_SENSITIVE))
     2481                {
     2482                        gui_internal_table_button_next(this, td->next_button, NULL);
     2483                }
     2484        }
     2485        gui_internal_menu_render(this);
     2486
    23412487}
    23422488
    23432489static void
     
    27002846                flags=8|16|32|64|256;
    27012847                break;
    27022848        case 2:
    2703                 flags=4|8|16|32|64;
     2849                flags=4|8|16|32|64|128;
    27042850                break;
    27052851        case 3:
    27062852                flags=1|8|16|32|64|128;
     
    51565302        widget->data_free=gui_internal_table_data_free;
    51575303        data = (struct table_data*)widget->data;
    51585304
    5159 
    51605305        if (buttons) {
    51615306        data->next_button = gui_internal_button_new_with_callback
    51625307                (this,"Next",image_new_xs(this, "gui_active") ,
     
    54105555
    54115556}
    54125557
    5413 
     5558/**
     5559 * @brief Invalidates coordinates for previosly rendered table widget rows.
     5560 *
     5561 * @param table_data Data from the table object.
     5562 */
     5563void gui_internal_table_hide_rows(struct table_data * table_data)
     5564{
     5565        GList*cur_row;
     5566        for(cur_row=table_data->top_row; cur_row ; cur_row = g_list_next(cur_row))
     5567        {
     5568                struct widget * cur_row_widget = (struct widget*)cur_row->data;
     5569                if (cur_row_widget->type!=widget_table_row)
     5570                        continue;
     5571                cur_row_widget->p.x=0;
     5572                cur_row_widget->p.y=0;
     5573                cur_row_widget->w=0;
     5574                cur_row_widget->h=0;
     5575                if(cur_row==table_data->bottom_row)
     5576                        break;
     5577        }
     5578}
    54145579
    54155580/**
    54165581 * @brief Renders a table widget.
     
    54345599        dbg_assert(table_data);
    54355600        column_desc = gui_internal_compute_table_dimensions(this,w);
    54365601        y=w->p.y;
    5437 
     5602        gui_internal_table_hide_rows(table_data);
    54385603        /**
    54395604         * Skip rows that are on previous pages.
    54405605         */
     
    54445609                cur_row = table_data->top_row;
    54455610                is_first_page=0;
    54465611        }
    5447 
    5448 
    54495612        /**
    54505613         * Loop through each row.  Drawing each cell with the proper sizes,
    54515614         * at the proper positions.
     
    54705633                         */
    54715634                        is_skipped=1;
    54725635                        break;
    5473 
    54745636                }
    54755637                for(cur_column = cur_row_widget->children; cur_column;
    54765638                    cur_column=g_list_next(cur_column))
     
    54955657                                max_height = dim->height;
    54965658                        }
    54975659                }
     5660               
     5661                /* Row object should have its coordinates in actual
     5662                 * state to be able to pass mouse clicks to Column objects
     5663                 */
     5664                cur_row_widget->p.x=w->p.x;
     5665                cur_row_widget->w=w->w;
     5666                cur_row_widget->p.y=y;
     5667                cur_row_widget->h=max_height;
    54985668                y = y + max_height;
    54995669                table_data->bottom_row=cur_row;
    55005670                current_desc = g_list_next(current_desc);
     
    55145684                //    table_data->prev_button->h=table_data->button_box->h;
    55155685                //    table_data->next_button->c.y=table_data->button_box->c.y;
    55165686                //    table_data->prev_button->c.y=table_data->button_box->c.y;
    5517 
    55185687                gui_internal_widget_pack(this,table_data->button_box);
    55195688                if(table_data->next_button->p.y > w->p.y + w->h + table_data->next_button->h)
    55205689                {
    5521 
    55225690                        table_data->button_box->p.y = w->p.y + w->h -
    55235691                                table_data->button_box->h;
    55245692                }
     
    59956163                        table_data->page_headers=g_list_append(table_data->page_headers,
    59966164                                                               table_data->top_row);
    59976165                }
    5998 
    5999                 table_data->top_row = g_list_next(table_data->bottom_row);
     6166                /**
     6167                 * Invalidate row coordinates for all rows which were previously rendered
     6168                 
     6169                for(iterator=table_data->top_row; iterator && table_data->rows_on_page; iterator = g_list_next(iterator))
     6170                {
     6171                        struct widget * cur_row_widget = (struct widget*)iterator->data;
     6172                        cur_row_widget->p.x=-1;
     6173                        cur_row_widget->p.y=-1;
     6174                        cur_row_widget->w=0;
     6175                        cur_row_widget->h=0;
     6176                        table_data->rows_on_page--;
     6177                }
     6178                */
     6179                gui_internal_table_hide_rows(table_data);
     6180                table_data->top_row=g_list_next(table_data->bottom_row);
    60006181        }
    60016182        wm->state&= ~STATE_HIGHLIGHTED;
    60026183        gui_internal_menu_render(this);
     
    60246205                table_data = (struct table_data*) table_widget->data;
    60256206                if(table_data)
    60266207                {
     6208                        gui_internal_table_hide_rows(table_data);
    60276209                        current_page_top = table_data->top_row;
    60286210                        for(iterator = table_data->page_headers; iterator != NULL;
    60296211                            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