Changeset 12

Show
Ignore:
Timestamp:
11/25/06 19:55:41 (2 years ago)
Author:
baxissimo
Message:

Text selection via mouse works now.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/luigi/base.d

    r11 r12  
    3535// Until std.math actually implements it 
    3636long lrint(float v) { 
    37     return cast(long)math.floor(v); 
     37    return cast(long)math.floor(v+0.5); 
    3838} 
    3939 
  • trunk/luigi/gui.d

    r11 r12  
    15121512    // mixin Signal!(Widget) text_accepted; 
    15131513 
     1514    // This is for use by the theme 
     1515    int xscroll_offset = 0; 
     1516 
    15141517    //int substring_start  = 0; 
    15151518    //int substring_end  = 0; 
     
    15221525    } 
    15231526    int sel_active = 0; // 0 or 1 
    1524  
    1525     // This is for use by the theme 
    1526     int xscroll_offset = 0; 
    15271527 
    15281528    invariant { 
  • trunk/luigi/theme.d

    r11 r12  
    488488    void textfield_register() { 
    489489        _addFuncs!(TextField)(&textfield_draw, &textfield_best_size, &textfield_min_size); 
     490        _addEvFuncs!(TextField)(&textfield_mouse_button, &textfield_mouse_move); 
     491    } 
     492    const int textfield_base_scroll = 3; 
     493 
     494    /** Returns a double indicating the position of the x value. 
     495        If exactly on a char boundary then the return value will be 
     496        integral, if right in the middle of a character it will be  
     497        0.5 offset from an integer.  
     498    */ 
     499    void textfield_get_rects(TextField w, inout Rect entry, inout Rect txt) 
     500    { 
     501        entry = w.rect; 
     502        entry.y+=1; 
     503        entry.h-=2; 
     504        if (w.label) { 
     505            Rect text_rect = get_font.string_rect(w.label); 
     506            entry.x += 6+text_rect.w; 
     507            entry.w -= 6+text_rect.w; 
     508        } 
     509 
     510        txt = entry; 
     511        txt.inset(1); txt.w-=1; txt.h-=1; 
     512    } 
     513    float textfield_get_char_pos(TextField txtf, float clickx) 
     514    { 
     515        Rect entry_rect,inside_rect; 
     516        textfield_get_rects(txtf, entry_rect, inside_rect); 
     517        alias m_default_font font; 
     518        float offset = inside_rect.x + textfield_base_scroll + txtf.xscroll_offset; 
     519        float x = offset; 
     520        float lastx = x-10; 
     521        int imax = txtf.text.length; 
     522        // binary search would of course be better here 
     523        int i; 
     524        for(i=0; x<clickx && i<imax; x=offset+font.string_rect(txtf.text[0..++i]).w) 
     525        { 
     526            lastx = x; 
     527        } 
     528        if (i==0) return 0; 
     529        else if (i>=imax) return imax; 
     530         
     531        float frac = (clickx-lastx)/(x-lastx); 
     532        return i-1.0+frac; 
     533 
    490534    } 
    491535    Size textfield_min_size(Widget widget, Size bounds) { 
     
    510554        alias m_default_font font; 
    511555        with (txtf) { 
    512             Rect entry_rect = Rect(0,0,rect.w,rect.h); 
    513             entry_rect.y+=1; 
    514             entry_rect.h-=2; 
     556            Rect entry_rect,inside_rect; 
     557            textfield_get_rects(txtf, entry_rect, inside_rect); 
     558            entry_rect.pos -= rect.pos; 
     559            inside_rect.pos -= rect.pos; 
    515560            if (label) { 
    516561                Rect text_rect = font.string_rect(label); 
    517562                draw_label_text( label, 2-text_rect.x, 2-text_rect.y+text_rect.h ); 
    518                 entry_rect.x += 6+text_rect.w; 
    519                 entry_rect.w -= 6+text_rect.w; 
    520563            } 
    521564 
     
    524567 
    525568            // Find where to draw the text 
    526             const float base_scroll = 3; 
    527  
    528             Rect inside_rect = entry_rect; 
    529             inside_rect.inset(1); inside_rect.w-=1;inside_rect.h-=1; 
    530569 
    531570            // Clip to insides of entry rect 
    532571            push_clip_rect( inside_rect ); 
    533572 
    534             float offset = inside_rect.x + base_scroll + xscroll_offset; 
     573            float offset = inside_rect.x + textfield_base_scroll + xscroll_offset; 
    535574            float sel_offset = font.string_rect(text[0..sel_begin]).width; 
    536575            Size sel_size = font.string_rect(text[sel_begin..sel_end]).size; 
     
    541580                if (sel_active==1) sel_x += sel_size.width; 
    542581                float dx; 
    543                 if ((dx=sel_x-inside_rect.x)<0) { offset-=dx-2; xscroll_offset-=dx-2; } 
    544                 else if ((dx=sel_x-inside_rect.x2)>0) { offset-=dx+1; xscroll_offset-=dx+1; } 
     582                if ((dx=sel_x-inside_rect.x)<0) { 
     583                    offset-=dx-2; xscroll_offset-=dx-2; 
     584                } 
     585                else if ((dx=sel_x-inside_rect.x2)>0) { 
     586                    offset-=dx+1; xscroll_offset-=dx+1; 
     587                } 
    545588            } 
    546589 
     
    626669            glEnd(); 
    627670            translate(-0.5,-0.5); 
    628  
    629  
    630671        } 
    631672        translate(-widget.rect.x, -widget.rect.y); 
    632673    } 
     674    void textfield_mouse_button(Widget widget, MouseButtonEvent ev) 
     675    { 
     676        if (ev.is_press && ev.is_left) { 
     677            auto txtf = cast(TextField)widget; assert(txtf); 
     678            float fselpos = textfield_get_char_pos(txtf, ev.x); 
     679            int pos = lrint(fselpos); 
     680            if (ev.shift_down) { 
     681                int[2] sel=txtf.sel_range[]; 
     682                sel[txtf.sel_active] = pos; 
     683                txtf.select_range(sel[0],sel[1]); 
     684            } 
     685            else { 
     686                txtf.select_range(pos,pos);        
     687            } 
     688        } 
     689    } 
     690    void textfield_mouse_move(Widget widget, MouseMoveEvent ev)  
     691    { 
     692        if (ev.left_down) { 
     693            auto txtf = cast(TextField)widget; assert(txtf); 
     694            float fselpos = textfield_get_char_pos(txtf, ev.x); 
     695            int pos = lrint(fselpos); 
     696            int[2] sel=txtf.sel_range[]; 
     697            sel[txtf.sel_active] = pos; 
     698            txtf.select_range(sel[0],sel[1]); 
     699        } 
     700    } 
     701 
    633702 
    634703    //----SLIDER----------------------------------------------------------------