font debug env var, drag fixes, cposer hide scrollbar, plugin tool tip
[goodguy/history.git] / cinelerra-5.1 / guicast / bclistbox.C
index 88d4b09470a8337a470f11f664f26b9e7edbf945..0c3057d1d99ed47838741a38fa648cee5b71f7ea 100644 (file)
 
 // ====================================================== scrollbars
 
-
-BC_ListBoxYScroll::BC_ListBoxYScroll(BC_ListBox *listbox,
-                         int total_height,
-                                         int view_height,
-                         int position)
- : BC_ScrollBar(listbox->get_yscroll_x(),
-       listbox->get_yscroll_y(),
-       SCROLL_VERT,
-       listbox->get_yscroll_height(),
-       total_height,
-       position,
-       view_height)
+BC_ListBoxYScroll::BC_ListBoxYScroll(BC_ListBox *listbox)
+ : BC_ScrollBar(listbox->get_yscroll_x(), listbox->get_yscroll_y(),
+       listbox->yscroll_orientation, listbox->get_yscroll_height(),
+       listbox->items_h, listbox->yposition, listbox->view_h)
 {
        this->listbox = listbox;
 }
@@ -64,23 +56,10 @@ int BC_ListBoxYScroll::handle_event()
        return 1;
 }
 
-
-
-
-
-
-
-BC_ListBoxXScroll::BC_ListBoxXScroll(BC_ListBox *listbox,
-                         int total_width,
-                                         int view_width,
-                         int position)
- : BC_ScrollBar(listbox->get_xscroll_x(),
-       listbox->get_xscroll_y(),
-       SCROLL_HORIZ,
-       listbox->get_xscroll_width(),
-       total_width,
-       position,
-       view_width)
+BC_ListBoxXScroll::BC_ListBoxXScroll(BC_ListBox *listbox)
+ : BC_ScrollBar(listbox->get_xscroll_x(), listbox->get_xscroll_y(),
+       listbox->xscroll_orientation, listbox->get_xscroll_width(),
+       listbox->items_w, listbox->xposition, listbox->view_w)
 {
        this->listbox = listbox;
 }
@@ -96,12 +75,6 @@ int BC_ListBoxXScroll::handle_event()
 }
 
 
-
-
-
-
-
-
 BC_ListBoxToggle::BC_ListBoxToggle(BC_ListBox *listbox,
        BC_ListBoxItem *item,
        int x,
@@ -361,6 +334,8 @@ BC_ListBox::BC_ListBox(int x,
        new_value = 0;
        need_xscroll = 0;
        need_yscroll = 0;
+       xscroll_orientation = SCROLL_HORIZ;
+       yscroll_orientation = SCROLL_VERT;
        bg_tile = 0;
        bg_draw = 1;
        drag_popup = 0;
@@ -1061,7 +1036,7 @@ int BC_ListBox::get_text_w(BC_ListBoxItem *item)
 int BC_ListBox::get_text_h(BC_ListBoxItem *item)
 {
        int h = item->get_text_h();
-       if( h < 0 ) item->set_text_h(h = get_text_height(MEDIUMFONT));
+       if( h < 0 ) item->set_text_h(h = get_text_height(MEDIUMFONT, item->get_text()));
        return h;
 }
 
@@ -1234,6 +1209,13 @@ void BC_ListBox::set_autoplacement(ArrayList<BC_ListBoxItem*> *data,
 }
 
 
+void BC_ListBox::set_scroll_stretch(int xv, int yv)
+{
+       if( xv >= 0 ) xscroll_orientation =
+               !xv ? SCROLL_HORIZ : SCROLL_HORIZ + SCROLL_STRETCH;
+       if( yv >= 0 ) yscroll_orientation =
+               !yv ? SCROLL_VERT  : SCROLL_VERT  + SCROLL_STRETCH;
+}
 
 int BC_ListBox::get_yscroll_x()
 {
@@ -1362,6 +1344,8 @@ int BC_ListBox::get_text_mask(BC_ListBoxItem *item,
        {
                w = get_text_width(MEDIUMFONT, item->text) + LISTBOX_MARGIN * 2;
                h = row_height;
+               int ih = get_icon_h(item);
+               if( h < ih ) h = ih;
        }
        return 0;
 }
@@ -1807,7 +1791,11 @@ int BC_ListBox::select_next(int skip,
 void BC_ListBox::clamp_positions()
 {
        items_w = get_items_width();
+       if( xscroll_orientation & SCROLL_STRETCH )
+               items_w += view_w / 4;
        items_h = get_items_height(data, columns);
+       if( yscroll_orientation & SCROLL_STRETCH )
+               items_h += view_h / 4;
 
        if(yposition < 0) yposition = 0;
        else
@@ -1968,11 +1956,8 @@ int BC_ListBox::get_scrollbars()
        {
                if(!xscrollbar)
                {
-                       destination->add_subwindow(xscrollbar =
-                               new BC_ListBoxXScroll(this,
-                                       w_needed,
-                                       view_w,
-                                       xposition));
+                       xscrollbar = new BC_ListBoxXScroll(this);
+                       destination->add_subwindow(xscrollbar);
                        xscrollbar->show_window(0);
                        xscrollbar->bound_to = this;
                }
@@ -1995,11 +1980,8 @@ int BC_ListBox::get_scrollbars()
        {
                if(!yscrollbar)
                {
-                       destination->add_subwindow(yscrollbar =
-                               new BC_ListBoxYScroll(this,
-                                       h_needed,
-                                       view_h,
-                                       yposition));
+                       yscrollbar = new BC_ListBoxYScroll(this);
+                       destination->add_subwindow(yscrollbar);
                        yscrollbar->show_window(0);
                        yscrollbar->bound_to = this;
                }
@@ -2252,7 +2234,7 @@ int BC_ListBox::reposition_item(ArrayList<BC_ListBoxItem*> *data,
 void BC_ListBox::move_selection(ArrayList<BC_ListBoxItem*> *dst,
        ArrayList<BC_ListBoxItem*> *src)
 {
-       for(int i = 0; i < src[master_column].total; i++)
+       for(int i = 0; i < src[master_column].total; )
        {
                BC_ListBoxItem *item = src[master_column].values[i];
 
@@ -2264,14 +2246,15 @@ void BC_ListBox::move_selection(ArrayList<BC_ListBoxItem*> *dst,
                                dst[j].append(src[j].values[i]);
                                src[j].remove_number(i);
                        }
+                       continue;
                }
-               else
 // Descend into sublist
                if(item->get_sublist())
                {
                        move_selection(dst,
                                item->get_sublist());
                }
+               ++i;
        }
 }
 
@@ -2283,7 +2266,7 @@ int BC_ListBox::put_selection(ArrayList<BC_ListBoxItem*> *data,
        int temp = -1;
        if(!counter) counter = &temp;
 
-       if(destination < 0)
+       if(destination < 0 || destination >= data[master_column].total)
        {
                for(int j = 0; j < columns; j++)
                {
@@ -2473,6 +2456,7 @@ int BC_ListBox::repeat_event(int64_t duration)
                                return rectangle_scroll_event();
                        break;
 
+               case DRAG_ITEM:
                case SELECT:
                        if(duration == get_resources()->scroll_repeat)
                                return select_scroll_event();
@@ -3692,9 +3676,7 @@ int BC_ListBox::drag_start_event()
        switch(current_operation)
        {
                case SELECT:
-                       if(gui &&
-                               gui->is_event_win() &&
-                               allow_drag)
+                       if( gui && gui->is_event_win() && allow_drag )
                        {
                                BC_ListBoxItem *item_return = 0;
                                selection_number = get_cursor_item(data,
@@ -3704,32 +3686,25 @@ int BC_ListBox::drag_start_event()
 
                                if(selection_number >= 0)
                                {
-
-                                       if (item_return->icon_vframe)
-                                       {
+                                       int cx, cy;
+                                       get_abs_cursor_xy(cx, cy);
+                                       cx -= item_return->icon_vframe->get_w() / 2,
+                                       cy -= item_return->icon_vframe->get_h() / 2;
+                                       if( item_return->icon_vframe )
                                                drag_popup = new BC_DragWindow(this,
-                                                       item_return->icon_vframe /*,
-                                                       get_abs_cursor_x(0) - item_return->icon_vframe->get_w() / 2,
-                                                       get_abs_cursor_y(0) - item_return->icon_vframe->get_h() / 2 */);
-                                       }
+                                                       item_return->icon_vframe, cx, cy);
                                        else
 // this probably works not!
-                                       if (item_return->icon)
-                                       {
+                                       if( item_return->icon )
                                                drag_popup = new BC_DragWindow(this,
-                                                       item_return->icon /*,
-                                                       get_abs_cursor_x(0) - item_return->icon->get_w() / 2,
-                                                       get_abs_cursor_y(0) - item_return->icon->get_h() / 2 */);
-                                       }
+                                                       item_return->icon, cx, cy);
                                        else
-                                       {
                                                drag_popup = new BC_DragWindow(this,
-                                                       drag_icon_vframe /*,
-                                                       get_abs_cursor_x(0) - drag_icon_vframe->get_w() / 2,
-                                                       get_abs_cursor_y(0) - drag_icon_vframe->get_h() / 2 */);
-                                       }
-
+                                                       drag_icon_vframe, cx, cy);
                                        current_operation = DRAG_ITEM;
+// require shift down for scrolling
+                                       if( allow_drag < 0 && shift_down() )
+                                               set_repeat(get_resources()->scroll_repeat);
                                        return 1;
                                }
                        }
@@ -3738,10 +3713,12 @@ int BC_ListBox::drag_start_event()
                case COLUMN_DN:
                        if(gui && gui->is_event_win() && allow_drag_column)
                        {
+                               int cx, cy;
+                               get_abs_cursor_xy(cx, cy);
+                               cx -= drag_column_icon_vframe->get_w() / 2,
+                               cy -= drag_column_icon_vframe->get_h() / 2;
                                drag_popup = new BC_DragWindow(this,
-                                       drag_column_icon_vframe /*,
-                                       get_abs_cursor_x(0) - drag_column_icon_vframe->get_w() / 2,
-                                       get_abs_cursor_y(0) - drag_column_icon_vframe->get_h() / 2 */);
+                                       drag_column_icon_vframe, cx, cy);
                                dragged_title = highlighted_title;
                                current_operation = COLUMN_DRAG;
                                draw_titles(1);
@@ -3784,7 +3761,6 @@ int BC_ListBox::drag_motion_event()
                        }
 
                        return drag_popup->cursor_motion_event();
-                       break;
                }
 
                case COLUMN_DRAG:
@@ -3796,7 +3772,6 @@ int BC_ListBox::drag_motion_event()
                                draw_titles(1);
                        }
                        return drag_popup->cursor_motion_event();
-                       break;
                }
        }
        return 0;
@@ -3807,6 +3782,7 @@ int BC_ListBox::drag_stop_event()
        switch(current_operation)
        {
                case DRAG_ITEM:
+                       unset_repeat(get_resources()->scroll_repeat);
 // Inside window boundary
                        if(top_level->cursor_x > 0 &&
                                top_level->cursor_x < gui->get_w() - drag_popup->get_w() / 2 &&
@@ -3820,37 +3796,24 @@ int BC_ListBox::drag_stop_event()
                                {
                                        reposition_item(data,
                                                selection_number,
-                                               top_level->cursor_x +
-                                                       drag_popup->get_offset_x() -
-                                                       LISTBOX_MARGIN -
-                                                       2 +
-                                                       xposition,
-                                               top_level->cursor_y +
-                                                       drag_popup->get_offset_y() -
-                                                       LISTBOX_MARGIN -
-                                                       2 +
-                                                       yposition);
+                                               top_level->cursor_x + drag_popup->get_offset_x() -
+                                                       LISTBOX_MARGIN - 2 + xposition,
+                                               top_level->cursor_y + drag_popup->get_offset_y() -
+                                                       LISTBOX_MARGIN - 2 + yposition);
                                }
                                else
 // Move rows
                                if(process_drag)
                                {
-// Get destination
-                                       int destination = highlighted_item = item_to_index(data,
-                                               highlighted_ptr);
-//printf("BC_ListBox::drag_stop_event 1 %p %d\n", highlighted_ptr, destination);
-
 // Move selected items from data to temporary
                                        ArrayList<BC_ListBoxItem*> *src_items =
                                                new ArrayList<BC_ListBoxItem*>[columns];
-
                                        move_selection(src_items, data);
-
+// Get destination
+                                       int destination = highlighted_item = item_to_index(data,
+                                               highlighted_ptr);
 // Insert items from temporary to data
-                                       put_selection(data,
-                                               src_items,
-                                               destination);
-
+                                       put_selection(data, src_items, destination);
 
                                        delete [] src_items;
                                        set_autoplacement(data, 0, 1);
@@ -4192,6 +4155,7 @@ void BC_ListBox::clear_listbox(int x, int y, int w, int h)
 void BC_ListBox::update_format(int display_format, int redraw)
 {
        this->display_format = display_format;
+       xposition = 0;  yposition = 0;
        if( redraw && gui ) draw_items(1, 1);
 }
 
@@ -4404,9 +4368,14 @@ void BC_ListBox::draw_text_recursive(ArrayList<BC_ListBoxItem*> *data,
                                gui->set_color(row_color);
                                gui->draw_box(x, y, column_width, h);
                                gui->set_color(BLACK);
-                               int yy = y, xx = x + column_width-1;
-                               gui->draw_line(x, yy, xx, yy);
-                               yy = y + row_height;
+                               int xx = x + column_width-1;
+                               gui->draw_line(x, y, xx, y);
+                               int hh = h;
+                               if( display_format == LISTBOX_ICON_LIST ) {
+                                       int ih = get_icon_h(item);
+                                       if( ih > hh ) hh = ih;
+                               }
+                               int yy = y + hh-1;
                                gui->draw_line(x, yy, xx, yy);
                        }
 
@@ -4520,43 +4489,39 @@ void BC_ListBox::draw_title(int number)
                        image_number = 2;
        }
 
-       int column_offset = get_column_offset(number) - xposition + LISTBOX_BORDER;
-       int column_width = get_column_width(number, 1);
        gui->draw_3segmenth(get_column_offset(number) - xposition + LISTBOX_BORDER,
                LISTBOX_BORDER,
                get_column_width(number, 1) + get_resources()->listbox_title_overlap,
                column_bg[image_number]);
 
-// Column title sort order
-       if(number == sort_column)
-       {
-               BC_Pixmap *src;
-               if(sort_order == SORT_ASCENDING)
-                       src = column_sort_dn;
-               else
-                       src = column_sort_up;
+       int title_x = -xposition + get_column_offset(number) + 
+               LISTBOX_MARGIN + LISTBOX_BORDER;
+       title_x += get_resources()->listbox_title_margin;
 
-               int x = column_offset +
-                       column_width -
-                       LISTBOX_BORDER;
-               if(x > items_w) x = items_w;
-               x -= 5 + src->get_w();
+       gui->set_color(get_resources()->listbox_title_color);
+       gui->draw_text(title_x, 
+               LISTBOX_MARGIN + LISTBOX_BORDER + get_text_ascent(MEDIUMFONT), 
+               column_titles[number]);
+
+// Column sort order
+       if(number == sort_column) {
+               BC_Pixmap *src = sort_order == SORT_ASCENDING ?
+                       column_sort_dn : column_sort_up;
+
+//             int column_offset = get_column_offset(number) - xposition + LISTBOX_BORDER;
+//             int column_width = get_column_width(number, 1);
+//             int toggle_x = column_offset + column_width - LISTBOX_BORDER;
+//             if( toggle_x > items_w ) toggle_x = items_w;
+//             toggle_x -= 5 + src->get_w();
+
+               int x = title_x + 
+                       get_text_width(MEDIUMFONT, column_titles[number]) +
+                       LISTBOX_MARGIN;
+               
                gui->draw_pixmap(src,
                        x,
                        title_h / 2 - src->get_h() / 2 + LISTBOX_BORDER);
        }
-
-
-       int x = -xposition +
-               get_column_offset(number) +
-               LISTBOX_MARGIN +
-               LISTBOX_BORDER;
-       x += get_resources()->listbox_title_margin;
-
-       gui->set_color(get_resources()->listbox_title_color);
-       gui->draw_text(x,
-               LISTBOX_MARGIN + LISTBOX_BORDER + get_text_ascent(MEDIUMFONT),
-               _(column_titles[number]));
 }
 
 int BC_ListBox::draw_titles(int flash)