Changeset 23

Show
Ignore:
Timestamp:
12/02/06 02:16:47 (2 years ago)
Author:
baxissimo
Message:

dxut theme's textfield works now.

Files:

Legend:

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

    r17 r23  
    8181        x = rx; y = ry; w = rw; h = rh; 
    8282    } 
     83    /** Value setter using point values */ 
     84    void  setLTRB(float leftx, float topy, float rightx, float bottomy) { 
     85        set(leftx,topy,rightx-leftx,bottomy-topy); 
     86    } 
    8387 
    8488    /** Point-inside-rect test */ 
     
    9599        if (2*v > h) { y += h/2; h = 0; } 
    96100        else {            y+=v; h-=2*v; } 
     101    } 
     102    void inflate(float v) { 
     103        inset(-v); 
    97104    } 
    98105 
  • trunk/luigi/example1.d

    r22 r23  
    140140            auto b16 =   g.add_widget(new Button("Help")); 
    141141 
    142             c15.value_changed.connect( (Widget w, bool onoff) 
    143             { 
     142            /*c15.value_changed.connect(  
     143                (Widget w, bool onoff) { 
     144                    writefln(onoff?"checked!":"unchecked!");  
     145                    });*/ 
     146            c15.value_changed ~= (Widget w, bool onoff) { 
    144147                writefln(onoff?"checked!":"unchecked!");  
    145             })
     148            }
    146149        } 
    147150 
     
    149152            alias southGroup g; // workaround for http://tinyurl.com/u5eal 
    150153            //Button b0 = add_widget(new Button("Hohoho!")); 
    151             auto l0 = g.add_widget(new Label( "FirstName:")); 
    152             auto t0 = g.add_widget(new TextField); 
    153             auto t1 = g.add_widget(new TextField("Last name:")); 
    154             t1.text = "Rumplestilskin"
     154            auto l0 = g.add_widget(new Label( "First Name:")); 
     155            auto t0 = g.add_widget(new TextField("Hello")); 
     156            auto l1 = g.add_widget(new Label( "Last Name:")); 
     157            auto t1 = g.add_widget(new TextField("Rumpelstiltskin"))
    155158            auto b4 = g.add_widget(new Button("Click me!")); 
    156             b4.clicked.connect((Widget w){ writefln("Ouch! Not so hard!"); }  ); 
     159            auto l2 = g.add_widget(new Label("Disabled label")); 
     160            l2.disable; 
     161            b4.clicked ~= (Widget w){ writefln("Ouch! Not so hard!"); }; 
    157162        } 
    158163 
  • trunk/luigi/gui.d

    r22 r23  
    15031503 
    15041504 
    1505     this(char[] label_="") 
    1506     { 
    1507         super(); 
    1508         label=label_; 
     1505    this(char[] text_="") 
     1506    { 
     1507        super(); 
    15091508        rect.width = 130; 
    15101509        text_accepted = new TextAcceptedSignal; 
    1511     } 
    1512  
    1513  
    1514     char [] label; 
     1510        m_text=text_; 
     1511    } 
    15151512 
    15161513    alias FlexSignal!(Widget, char[]) TextAcceptedSignal; 
  • trunk/luigi/signalobj.d

    r13 r23  
    149149        return f_key; 
    150150    } 
     151 
     152    /** Provides an alternate signal for connect() using the ~= operator. 
     153        This can allow for somewhat cleaner syntax when using delegate literals. 
     154        (One set of parentheses is eliminated) 
     155        For example: 
     156            theSignal ~= (Widget w, bool onoff) { 
     157                writefln(onoff?"checked!":"unchecked!");}; 
     158        Versus  
     159            theSignal.connect( (Widget w, bool onoff) { 
     160                writefln(onoff?"checked!":"unchecked!");}); 
     161        The downside is that it is not possible to specify template 
     162        arguments for ~= explicitly if needed. 
     163     */ 
     164    alias connect opCatAssign; 
     165 
    151166    /** Some simple wrappers for the most comment skipped argument  
    152      *  versions of connect.  These work around the implicit  
    153      *  instantiation problem. 
     167     *  versions of connect.  These work well with implicit instatiation. 
    154168     */ 
    155169    slot_key connect1st(DT)(DT f) { return connect!(DT,0)(f);  } 
     
    158172    slot_key connect4th(DT)(DT f) { return connect!(DT,3)(f);  } 
    159173    slot_key connect5th(DT)(DT f) { return connect!(DT,4)(f);  } 
     174 
    160175    // this doesn't quite work yet because of DMD bug #540 
    161176    // Name also has to be different from 'connect' for what also looks  
    162177    // to be a compiler bug.  They should be able to co-exist.  
     178    // If it did work you'd be able to do something like sig.connecti!(2)(dg). 
    163179    template connecti(int arg_offset) { 
    164180        slot_key connecti(DT)(DT f) 
  • trunk/luigi/theme.d

    r15 r23  
    544544        entry.y+=1; 
    545545        entry.h-=2; 
    546         if (w.label) { 
    547             Rect text_rect = get_font.string_rect(w.label); 
    548             entry.x += 6+text_rect.w; 
    549             entry.w -= 6+text_rect.w; 
    550         } 
    551  
    552546        txt = entry; 
    553547        txt.inset(1); txt.w-=1; txt.h-=1; 
     
    577571    Size textfield_min_size(Widget widget, Size bounds) { 
    578572        auto w = cast(TextField)widget; assert(w); 
    579         Size sz = get_font.string_rect(w.label).size; 
    580         sz.w += 20; 
    581         sz.h += 2; 
     573        Size sz = Size(20,2); 
    582574        return sz; 
    583575    } 
     
    600592            entry_rect.pos -= rect.pos; 
    601593            inside_rect.pos -= rect.pos; 
    602             if (label) { 
    603                 Rect text_rect = font.string_rect(label); 
    604                 draw_label_text( label, 2-text_rect.x, 2-text_rect.y+text_rect.h ); 
    605             } 
    606594 
    607595            set_color(hilite_color[2]); 
     
    716704    void textfield_mouse_button(Widget widget, MouseButtonEvent ev) 
    717705    { 
    718         if (ev.is_press && ev.is_left) { 
     706        if (ev.is_left)  
     707        { 
    719708            auto txtf = cast(TextField)widget; assert(txtf); 
    720             float fselpos = textfield_get_char_pos(txtf, ev.x); 
    721             int pos = lrint(fselpos); 
    722             if (ev.shift_down) { 
    723                 int[2] sel=txtf.sel_range[]; 
    724                 sel[txtf.sel_active] = pos; 
    725                 txtf.select_range(sel[0],sel[1]); 
    726             } 
    727             else { 
    728                 txtf.select_range(pos,pos);        
     709            if (ev.is_press) { 
     710                float fselpos = textfield_get_char_pos(txtf, ev.x); 
     711                int pos = lrint(fselpos); 
     712                if (ev.shift_down) { 
     713                    int[2] sel=txtf.sel_range[]; 
     714                    sel[txtf.sel_active] = pos; 
     715                    txtf.select_range(sel[0],sel[1]); 
     716                } 
     717                else { 
     718                    txtf.select_range(pos,pos);        
     719                } 
     720                txtf.grab_mouse(); 
     721            } 
     722            else if (ev.is_release) { 
     723                if (txtf.is_grabbing_mouse) txtf.release_mouse(); 
    729724            } 
    730725        } 
  • trunk/luigi/themes/dxut.d

    r22 r23  
    7878        radiogroup_register(); 
    7979        radiobutton_register(); 
     80 
     81        sel_text_color.set(255,255,255); 
     82        sel_text_bkg_color.set(10,36,106); 
     83        sel_text_unfocus_bkg_color.set(176,176,176); 
     84 
    8085    } 
    8186    ~this() { 
     
    8792    class ThemeData { 
    8893        // per-widget elements needed so we can blend objects independently 
     94        // a little wasteful, though, since most info does not change per-elem 
    8995        Element[] elements; 
    9096    } 
     
    151157    } 
    152158 
    153     /** Draw text centered in the rectangle */ 
    154     void draw_text_centered(Font font, char[] label, Rect rect) 
    155     { 
    156         Rect sr = font.string_rect(label); 
    157         float sx = rect.x+(rect.w-sr.w)/2; 
    158         float sy = rect.y+(rect.h-sr.h)/2; 
    159         Point trans = font.origin; trans.x+=sx; trans.y+=sy; 
    160         translate(trans); 
    161         font.draw_string(label); 
    162         untranslate(trans); 
     159    enum TextAlign { 
     160        Center = 0x0, 
     161        Top = 0x1, 
     162        Bottom = 0x2, 
     163        Left = 0x4, 
     164        Right = 0x8, 
     165        TopLeft = Top|Left, 
     166        TopRight = Top|Right, 
     167        BottomLeft = Bottom|Left, 
     168        BottomRight = Bottom|Right, 
     169        LRMask = Right | Left, 
     170        TBMask = Top | Bottom, 
    163171    } 
    164172    /** Draw text so the upper left corner is at (x,y) */ 
     
    170178        untranslate(trans); 
    171179    } 
    172  
    173     void draw_elem_sprite(inout Element elem, inout Rect rect) { 
     180    /** Draw text inside the rect with the indicated alignment */ 
     181    void draw_text_rect(Font font, char[] txt, Rect r, TextAlign ta) 
     182    { 
     183        Point trans = font.origin; trans.x+=r.x; trans.y+=r.y; 
     184        TextAlign tbflags = ta & TextAlign.TBMask; 
     185        TextAlign lrflags = ta & TextAlign.LRMask; 
     186        if (lrflags != TextAlign.Left) { 
     187            Rect sr = font.string_rect(txt); 
     188            if (lrflags == TextAlign.Right) { 
     189                trans.x += r.w - sr.w; 
     190            }  
     191            else if (lrflags == TextAlign.Center) { 
     192                trans.x += (r.w - sr.w)/2; 
     193            } 
     194        } 
     195        if (lrflags != TextAlign.Top) { 
     196            float txth = font.height; 
     197            if (lrflags == TextAlign.Bottom) { 
     198                trans.y += r.h - txth; 
     199            }  
     200            else if (lrflags == TextAlign.Center) { 
     201                trans.y += (r.h - txth)/2; 
     202            } 
     203        } 
     204        translate(trans); 
     205        font.draw_string(txt); 
     206        untranslate(trans); 
     207    } 
     208    /** Draw text centered in the rectangle */ 
     209    void draw_text_centered(Font font, char[] label, Rect rect) 
     210    { 
     211        draw_text_rect(font,label,rect,TextAlign.Center); 
     212    } 
     213 
     214    void draw_elem_texture(inout Element elem, inout Rect rect) { 
    174215        if (elem.texColor.alpha == 0)  
    175216            return; 
     
    178219        fill_rect(rect, elem.texRect); 
    179220    } 
    180     void draw_elem_sprite(inout Element elem, inout Rect rect, int[4] texRect) { 
     221    void draw_elem_texture(inout Element elem, inout Rect rect, int[4] texRect) { 
    181222        if (elem.texColor.alpha == 0)  
    182223            return; 
     
    185226        fill_rect(rect, texRect); 
    186227    } 
    187     void draw_elem_text(inout Element elem, char[] text, Rect rect, bool shadow=false) 
     228    void draw_elem_text(inout Element elem, char[] text, Rect rect,  
     229                        TextAlign al = TextAlign.Center, bool shadow=false) 
    188230    { 
    189231        if (elem.fontColor.alpha == 0) 
     
    193235            set_color(0); 
    194236            rect.x+=1; rect.y+=1; 
    195             draw_text_centered(elem.font, text, rect); 
     237            draw_text_rect(elem.font, text, rect, al); 
    196238            rect.x-=1; rect.y-=1; 
    197239        } 
    198240        set_color(elem.fontColor.current); 
    199         draw_text_centered(elem.font, text, rect); 
     241        draw_text_rect(elem.font, text, rect, al); 
    200242    } 
    201243    //----LABEL--------------------------------------------------------------- 
    202244    void label_register() { 
     245        addHandlers!(Label)(&label_draw, &label_best_size); 
     246 
     247        Element[] elems = new Element[1]; 
     248        Element e; 
     249        e.set_font( m_default_font ); 
     250        e.fontColor.states[ WidgetState.Disabled ] = Color( 200, 200, 200, 200 ); 
     251        elems[0] = e; 
     252        m_elements[Label.classinfo] = elems; 
     253    } 
     254    Size label_best_size(Widget widget, Size bounds) { 
     255        auto w = cast(Label)widget; assert(w); 
     256        Element[] elem = get_widget_elements(w); 
     257        Rect r = elem[0].font.string_rect(w.label); 
     258        return Size(r.width+2,r.height+2); 
     259    } 
     260    void label_draw(Widget widget) { 
     261        auto w = cast(Label)widget; assert(w); 
     262        WidgetState state = WidgetState.Normal; 
     263        if( !w.enabled) 
     264            state = WidgetState.Disabled; 
     265        Element[] elem = get_widget_elements(w); 
     266        elem[0].fontColor.blend( state, m_elapsedTime ); 
     267        draw_elem_text( elem[0], w.label, w.rect, TextAlign.Center, true ); 
    203268    } 
    204269 
     
    266331            } 
    267332 
    268             //float elapsedTime = 1.0/60.; 
    269  
    270333            Element[] elem = get_widget_elements(w); 
    271334 
     
    278341                e.texColor.blend( iState, m_elapsedTime, blendRate); 
    279342                e.fontColor.blend( iState, m_elapsedTime, blendRate); 
    280                 if (e.texColor.alpha != 0) { 
    281                     glEnable(GL_TEXTURE_2D); 
    282                     set_color(e.texColor.current); 
    283                     fill_rect(r, e.texRect); 
    284                 } 
    285                 if (e.fontColor.alpha != 0) { 
    286                     glDisable(GL_TEXTURE_2D); 
    287                     set_color(e.fontColor.current); 
    288                     draw_text_centered(e.font, label, r); 
    289                 } 
     343                draw_elem_texture(e, r); 
     344                draw_elem_text(e, label, r); 
    290345            } 
    291346        } 
     
    359414            txt_rect.w = elem[0].font.string_rect(label).w; 
    360415             
    361             draw_elem_sprite( elem[0], btn_rect ); 
    362             draw_elem_text( elem[0], label, txt_rect, true ); 
     416            draw_elem_texture( elem[0], btn_rect ); 
     417            draw_elem_text( elem[0], label, txt_rect, TextAlign.Center, true ); 
    363418 
    364419            if( !checked ) 
     
    367422            elem[1].texColor.blend( iState, m_elapsedTime, fBlendRate ); 
    368423            btn_rect.inset(1); 
    369             draw_elem_sprite( elem[1], btn_rect ); 
     424            draw_elem_texture( elem[1], btn_rect ); 
    370425        } 
    371426    } 
    372427    //----TEXTFIELD--------------------------------------------------------- 
     428    enum TextElem { 
     429        Text, 
     430        TL, // top left 
     431        TC, // top center 
     432        TR, // top right 
     433        L,  // left 
     434        R,  // right 
     435        BL, // bottom left 
     436        BC, // bottom center 
     437        BR  // bottom right 
     438    } 
    373439    void textfield_register() { 
    374     } 
     440        addHandlers!(TextField)(&textfield_draw, &textfield_best_size, &textfield_min_size); 
     441        addEventHandlers!(TextField)(&textfield_mouse_button, &textfield_mouse_move); 
     442 
     443        Element[] elems = new Element[TextElem.max+1]; 
     444        Element e; 
     445 
     446        e.fontColor.states[ WidgetState.Rollover ] = Color(0, 0, 0, 255); 
     447        e.fontColor.states[ WidgetState.Depressed ] = Color(0, 0, 0, 255); 
     448        e.fontColor.states[ WidgetState.Disabled ] = Color(200, 200, 200, 200); 
     449        e.set_font( m_default_font, Color(255, 255, 255, 255)); 
     450 
     451        e.set_texture( m_texid, [1, 290, 280, 331] ); 
     452        e.texColor.states[ WidgetState.Rollover ] = Color(255, 255, 255, 160); 
     453        e.texColor.states[ WidgetState.Depressed ] = Color(150, 150, 150, 255); 
     454        e.texColor.states[ WidgetState.Normal ]   = Color(255, 255, 255, 150); 
     455        e.texColor.states[ WidgetState.Focus ]    = Color(255, 255, 255, 200); 
     456        e.texColor.states[ WidgetState.Disabled ] = Color(200, 200, 200, 255); 
     457 
     458        e.set_font(m_default_font, Color( 0, 0, 0 )); 
     459        int[4][] rects = [ 
     460            [14, 90, 241, 113], 
     461            [8, 82, 14, 90], 
     462            [14, 82, 241, 90], 
     463            [241, 82, 246, 90], 
     464            [8, 90, 14, 113], 
     465            [241, 90, 246, 113], 
     466            [8, 113, 14, 121], 
     467            [14, 113, 241, 121], 
     468            [241, 113, 246, 121], 
     469            ]; 
     470        foreach(i,r; rects) { 
     471            e.set_texture( m_texid, r); 
     472            elems[i] = e; 
     473        } 
     474        m_elements[TextField.classinfo] = elems; 
     475    } 
     476    const int textfield_borderw = 5;  
     477    const int textfield_paddingw = 4; 
     478    float textfield_get_char_pos(TextField txtf, float clickx) 
     479    { 
     480        Element[] elem = get_widget_elements(txtf); 
     481        Rect entry_rect,inside_rect; 
     482        Rect r = txtf.rect; 
     483        r.inset(textfield_borderw + textfield_paddingw); 
     484        r.x += txtf.xscroll_offset; 
     485        r.w -= txtf.xscroll_offset; 
     486        Font font = elem[0].font; 
     487        float basex = r.x; 
     488        float x = r.x; 
     489        float lastx = x-10; 
     490        int imax = txtf.text.length; 
     491        // binary search would be better here theoretically 
     492        int i; 
     493        for(i=0; x<clickx && i<imax; x=basex+font.string_rect(txtf.text[0..++i]).w) 
     494        { 
     495            lastx = x; 
     496        } 
     497        if (i==0) return 0; 
     498        else if (i>=imax) return imax; 
     499         
     500        float frac = (clickx-lastx)/(x-lastx); 
     501        return i-1.0+frac; 
     502    } 
     503    void textfield_update_rects(TextField txtf, Element[] elem) 
     504    { 
     505        Rect rbase = txtf.rect; 
     506        Rect rtext = rbase; 
     507        rtext.inset( textfield_borderw ); 
     508        alias TextElem T; 
     509        elem[T.Text].elemRect = rtext; 
     510        elem[T.TL].elemRect.setLTRB( rbase.x,  rbase.y,  rtext.x,  rtext.y ); 
     511        elem[T.TC].elemRect.setLTRB( rtext.x,  rbase.y,  rtext.x2, rtext.y ); 
     512        elem[T.TR].elemRect.setLTRB( rtext.x2, rbase.y,  rbase.x2, rtext.y ); 
     513        elem[T.L ].elemRect.setLTRB( rbase.x,  rtext.y,  rtext.x,  rtext.y2 ); 
     514        elem[T.R ].elemRect.setLTRB( rtext.x2, rtext.y,  rbase.x2, rtext.y2 ); 
     515        elem[T.BL].elemRect.setLTRB( rbase.x,  rtext.y2, rtext.x,  rbase.y2 ); 
     516        elem[T.BC].elemRect.setLTRB( rtext.x,  rtext.y2, rtext.x2, rbase.y2 ); 
     517        elem[T.BR].elemRect.setLTRB( rtext.x2, rtext.y2, rbase.x2, rbase.y2 ); 
     518    } 
     519    Size textfield_min_size(Widget widget, Size bounds) { 
     520        Size sz = textfield_best_size(widget,bounds); 
     521        sz.w = min(100.0,sz.w); 
     522        return sz; 
     523    } 
     524    Size textfield_best_size(Widget widget, Size bounds) { 
     525        auto w = cast(TextField)widget; assert(w); 
     526        Element[] elem = get_widget_elements(w); 
     527        Size sz = elem[TextElem.Text].font.string_rect(w.text).size; 
     528        sz.w = max(100.0,sz.w); 
     529        float pad = 2*(textfield_borderw+textfield_paddingw); 
     530        sz.w += pad; 
     531        sz.h += pad; 
     532        return sz; 
     533    } 
     534    void textfield_draw(Widget widget) 
     535    { 
     536        auto w = cast(TextField)widget; assert(w); 
     537        with(w) { 
     538            Element[] elem = get_widget_elements(w); 
     539            textfield_update_rects(w, elem); 
     540 
     541            //foreach(i,e; elem) 
     542            for (int i=0; i<elem.length; i++) 
     543            { 
     544                Element *e = &elem[i]; 
     545                e.texColor.blend( WidgetState.Normal, m_elapsedTime ); 
     546                e.fontColor.blend( WidgetState.Normal, m_elapsedTime ); 
     547                draw_elem_texture( *e, e.elemRect ); 
     548            } 
     549 
     550            Rect inside_rect = elem[0].elemRect; 
     551            inside_rect.inset(textfield_paddingw); 
     552 
     553            // Clip to insides of entry rect 
     554            push_clip_rect( inside_rect ); scope(exit) pop_clip_rect(); 
     555 
     556            // Scrolled rect is the entire text rect, possibly scrolled out of view 
     557            // (--actually only x and y matter) 
     558            Rect scrolled_rect = inside_rect; 
     559            scrolled_rect.x += xscroll_offset; 
     560 
     561            float sel_offset = elem[0].font.string_rect(text[0..sel_begin]).width; 
     562            Size sel_size = elem[0].font.string_rect(text[sel_begin..sel_end]).size; 
     563 
     564            // make sure active end of selection is visible 
     565            { 
     566                float sel_x = scrolled_rect.x + sel_offset; 
     567                if (sel_active==1) sel_x += sel_size.width; 
     568                float dx; 
     569                if ((dx=sel_x-inside_rect.x)<0) { 
     570                    scrolled_rect.x-=dx-2; xscroll_offset-=dx-2; 
     571                } 
     572                else if ((dx=sel_x-inside_rect.x2)>0) { 
     573                    scrolled_rect.x-=dx+1; xscroll_offset-=dx+1; 
     574                } 
     575            } 
     576 
     577            if (selection_length) 
     578            { 
     579                // draw unselected first part of text 
     580                if (sel_begin!=0) { 
     581                    draw_elem_text(elem[0], text[0..sel_begin], scrolled_rect, 
     582                                   TextAlign.TopLeft); 
     583                } 
     584                 
     585                Rect rsel; 
     586                rsel.x = scrolled_rect.x+sel_offset; 
     587                rsel.y = scrolled_rect.y; 
     588                rsel.size = sel_size; 
     589 
     590                // Draw selection bkg 
     591                if (focused) { 
     592                    set_color(sel_text_bkg_color); 
     593                } else { 
     594                    set_color(sel_text_unfocus_bkg_color); 
     595                } 
     596                glDisable(GL_TEXTURE_2D); 
     597                fill_rect( rsel ); 
     598 
     599                // draw selected text 
     600                set_color(sel_text_color); 
     601                draw_text_rect(elem[0].font, text[sel_begin..sel_end], rsel,  
     602                               TextAlign.TopLeft); 
     603                rsel.x += rsel.width; 
     604 
     605                // draw rest of unselected text 
     606                if (sel_end!=text.length) { 
     607                    draw_elem_text(elem[0], text[sel_end..$], rsel, TextAlign.TopLeft); 
     608                } 
     609            } 
     610            else { 
     611                // Draw all the text in one go 
     612                draw_elem_text(elem[0], text, scrolled_rect, TextAlign.TopLeft); 
     613            } 
     614 
     615            // Caret 
     616            if ( enabled && selection_length == 0 ) { 
     617                if (focused && selection_length==0) 
     618                { 
     619                    float h = inside_rect.height; 
     620                    float x = scrolled_rect.x + sel_offset; 
     621                    set_color(elem[0].fontColor.current); 
     622                    glBegin( GL_LINE_LOOP ); 
     623                    glVertex2f( x, inside_rect.y  ); 
     624                    glVertex2f( x, inside_rect.y  ); 
     625                    glVertex2f( x, inside_rect.y2 ); 
     626                    glVertex2f( x, inside_rect.y2 ); 
     627                    glEnd(); 
     628                } 
     629            } 
     630 
     631        } 
     632    } 
     633    void textfield_mouse_button(Widget widget, MouseButtonEvent ev) 
     634    { 
     635        if (ev.is_left) { 
     636            auto txtf = cast(TextField)widget; assert(txtf); 
     637            if (ev.is_press) { 
     638                float fselpos = textfield_get_char_pos(txtf, ev.x); 
     639                int pos = lrint(fselpos); 
     640                if (ev.shift_down) { 
     641                    int[2] sel=txtf.sel_range[]; 
     642                    sel[txtf.sel_active] = pos; 
     643                    txtf.select_range(sel[0],sel[1]); 
     644                } 
     645                else { 
     646                    txtf.select_range(pos,pos);        
     647                } 
     648                txtf.grab_mouse(); 
     649            } 
     650            else if (ev.is_release) { 
     651                if (txtf.is_grabbing_mouse()) txtf.release_mouse();  
     652            } 
     653        } 
     654    } 
     655    void textfield_mouse_move(Widget widget, MouseMoveEvent ev)  
     656    { 
     657        if (ev.left_down) { 
     658            auto txtf = cast(TextField)widget; assert(txtf); 
     659            float fselpos = textfield_get_char_pos(txtf, ev.x); 
     660            int pos = lrint(fselpos); 
     661            int[2] sel=txtf.sel_range[]; 
     662            sel[txtf.sel_active] = pos; 
     663            txtf.select_range(sel[0],sel[1]); 
     664        } 
     665    } 
     666     
    375667    //----SLIDER------------------------------------------------------------ 
    376668    void slider_register() { 
     
    380672        Element[] elems = new Element[2]; 
    381673        Element e; 
    382  
    383674 
    384675        e.fontColor.states[ WidgetState.Rollover ] = Color(0, 0, 0, 255); 
     
    472763            elem[0].texColor.blend( iState, m_elapsedTime, fBlendRate ); 
    473764            if (horizontal) { 
    474                 draw_elem_sprite( elem[0], track_rect ); 
     765                draw_elem_texture( elem[0], track_rect ); 
    475766            } 
    476767            else { 
     
    482773                glTranslatef(rect.x+rect.w/2, rect.y+rect.h/2, 0); 
    483774                glRotatef(90,0,0,1); 
    484                 draw_elem_sprite( elem[0], r ); 
     775                draw_elem_texture( elem[0], r ); 
    485776                glPopMatrix(); 
    486777            } 
     
    506797                thumb_rect.x = v-thumb_rect.w/2; 
    507798                thumb_rect.y = track_rect.y + (track_rect.h-thumb_rect.h)/2; 
    508                 draw_elem_sprite( elem[1], thumb_rect ); 
     799                draw_elem_texture( elem[1], thumb_rect ); 
    509800            } else { 
    510801                float t = (value-value_min)/(value_max-value_min); 
     
    515806                glTranslatef(rect.x+rect.w/2, v, 0); 
    516807                glRotatef(90,0,0,1); 
    517                 draw_elem_sprite( elem[1], thumb_rect ); 
     808                draw_elem_texture( elem[1], thumb_rect ); 
    518809                glPopMatrix(); 
    519810            } 
     
    578869    int m_texh = 0; 
    579870    Element[][ClassInfo] m_elements; 
     871 
     872    Color sel_text_color; 
     873    Color sel_text_bkg_color; 
     874    Color sel_text_unfocus_bkg_color; 
    580875         
    581876    PerformanceCounter m_timer; 
     
    652947 
    653948    int[4] texRect;       // Bounding rect of this element on the composite texture 
     949    Rect elemRect;        // where this element will be drawn 
    654950     
    655951    BlendColor texColor;