Changeset 101:71f0f1f83620

Show
Ignore:
Timestamp:
11/16/08 12:03:47 (2 months ago)
Author:
Diggory Hardy <diggory.hardy@gmail.com>
branch:
default
Message:

Some path adjustments for windows (untested) and fonts. All types of option can be edited.

paths: support for getting the full path for a font when just the file name is entered, in order to unify usage on windows and linux.
paths: Used getSpecialPath for some windows paths; needs testing.
Content: Moved line-editing code to abstract ValueContent? class and added some conversion functions, so that any type of ValueContent? can be edited as text.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • data/conf/gui.mtt

    r100 r101  
    1515<WidgetData|optVal={0:[0x6030]}> 
    1616<WidgetData|optSep={0:[0x21, 0xff],1:["="]}> 
    17 <WidgetData|floating={0:[0x8200,13,6,14],1:["text","button","blank"]}> 
    18 <WidgetData|text={0:[0x4032]}> 
     17<WidgetData|floating={0:[0x8200,6,14],1:["button","blank"]}> 
    1918{Basic} 
    2019<WidgetData|root={0:[0x21,0x90D970],1:["A string!"]}> 
  • data/conf/options.mtt

    r100 r101  
    1111<int|lcdFilter=2> 
    1212<int|renderMode=0x30000> 
    13 <char[]|defaultFont="/usr/share/fonts/X11/Type1/n019003l.pfb"> 
    14 !<char[]|defaultFont="/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"> 
     13!<char[]|defaultFont="n019003l.pfb"> 
     14<char[]|defaultFont="DejaVuSans.ttf"> 
    1515<int|defaultSize=16> 
    1616 
  • mde/font/font.d

    r100 r101  
    2323 
    2424import mde.setup.exception;     // InitStage stuff 
     25import mde.setup.paths; 
    2526 
    2627import derelict.freetype.ft; 
     
    126127     * Sharing an FT_Face would require calling FT_Set_Pixel_Sizes each time a glyph is rendered or 
    127128     * swapping the size information (face.size)? */ 
    128     this (char[] path, int size) 
     129    this (char[] file, int size) 
    129130    in { 
    130131        assert (library !is null, "font: library is null"); 
    131132    } body { 
    132         if (FT_New_Face (library, toStringz(path), 0, &face)) 
    133             throw new fontLoadException ("Unable to read font: "~path); 
     133   if (FT_New_Face (library, getFontPath (file).ptr, 0, &face)) 
     134            throw new fontLoadException ("Unable to read font: "~file[0..$-1]); 
    134135         
    135136        if (!FT_IS_SCALABLE (face)) 
    136137            throw new fontLoadException ("Currently no support for non-scalable fonts (which " ~ 
    137                     path ~ " is). Please report if you want to see support."); 
     138                    file[0..$-1] ~ " is). Please report if you want to see support."); 
    138139        /* The following will need to be addressed when adding support for non-scalables: 
    139140         *  Use of face.size.metrics.height property. 
  • mde/gui/content/Content.d

    r100 r101  
    9292        desc_ = d; 
    9393    } 
    94 protected: 
     94     
     95    /// Get the text. 
     96    char[] toString (uint i) { 
     97        return (i == 0) ? sv 
     98            : (i == 1) ? name_ 
     99            : (i == 2) ? desc_ 
     100            : null; 
     101    } 
     102     
     103    /** Acts on a keystroke and returns the new value. 
     104     * 
     105     * Supports one-line editing: left/right, home/end, backspace/delete. */ 
     106    char[] keyStroke (ushort sym, char[] i) { 
     107    debug assert (i.length, "TextContent.keyStroke: no value (??)");    // impossible? 
     108    char k = *i; 
     109    if (k > 0x20) { 
     110        if (k == 0x7f) {        // delete 
     111        size_t p = pos; 
     112        if (p < sv.length) ++p; 
     113        while (p < sv.length && (sv[p] & 0x80) && !(sv[p] & 0x40)) 
     114            ++p; 
     115        sv = sv[0..pos] ~ sv[p..$]; 
     116        } else {            // insert character 
     117        char[] tail = sv[pos..$]; 
     118        sv.length = sv.length + i.length; 
     119        size_t npos = pos+i.length; 
     120        if (tail) sv[npos..$] = tail.dup;   // cannot assign with overlapping ranges 
     121            sv[pos..npos] = i; 
     122        pos = npos; 
     123        } 
     124    } else {            // use sym; many keys output 0 
     125        if (sym == SDLK_BACKSPACE) {    // backspace; k == 0x8 
     126        char[] tail = sv[pos..$]; 
     127        if (pos) --pos; 
     128        while (pos && (sv[pos] & 0x80) && !(sv[pos] & 0x40)) 
     129            --pos; 
     130        sv = sv[0..pos] ~ tail; 
     131        } else if (sym == SDLK_LEFT) { 
     132        if (pos) --pos; 
     133        while (pos && (sv[pos] & 0x80) && !(sv[pos] & 0x40)) 
     134            --pos; 
     135        } else if (sym == SDLK_RIGHT) { 
     136        if (pos < sv.length) ++pos; 
     137        while (pos < sv.length && (sv[pos] & 0x80) && !(sv[pos] & 0x40)) 
     138            ++pos; 
     139        } else if (sym == SDLK_HOME || sym == SDLK_UP) { 
     140        pos = 0; 
     141        } else if (sym == SDLK_END || sym == SDLK_DOWN) { 
     142        pos = sv.length; 
     143        } else 
     144        debug logger.trace ("Symbol: {}", sym); 
     145    } 
     146    return sv; 
     147    } 
     148     
     149    size_t getEditIndex () { 
     150    size_t i = 0; 
     151    for (size_t p = 0; p < pos; ++p) 
     152        if (!(sv[p] & 0x80) || sv[p] & 0x40) 
     153        ++i; 
     154    return i; 
     155    } 
     156     
     157    /// Call at the end of an edit to convert sv to v and call callbacks 
     158    void endEdit (); 
     159protected: 
     160    char[] sv;      // string of value; updated on assignment for displaying and editing 
     161    size_t pos;     // editing position; used by keyStroke 
     162    char[] symb; 
    95163    char[] name_, desc_;// name and description, loaded by lookup.Translation 
    96164} 
     
    114182    this (char[] symbol, bool val = false) { 
    115183        symb = symbol; 
    116         v = val
     184   assignNoCB (val)
    117185    } 
    118186     
     
    123191    } 
    124192     
    125     /// Get the text. 
    126     char[] toString (uint i) { 
    127         return (i == 0) ? v ? "true" : "false" 
    128              : (i == 1) ? name_ 
    129              : (i == 2) ? desc_ 
    130              : null; 
    131     } 
    132      
     193    void assignNoCB (bool val) { 
     194    v = val; 
     195    sv = v ? "true" : "false"; 
     196    } 
    133197    void opAssign (bool val) { 
    134         v = val
    135         foreach (cb; cngCb) 
     198   assignNoCB (val)
     199   foreach (cb; cngCb) 
    136200            cb(symb, val); 
    137201    } 
     
    141205    alias opCall opCast; 
    142206     
    143     bool v;     //FIXME: should be protected but Options needs to set without calling callbacks 
    144 protected: 
    145     char[] symb; 
     207    void endEdit () { 
     208    v = sv && (sv[0] == 't' || sv[0] == 'T' || sv[0] == '1'); 
     209    foreach (cb; cngCb) 
     210        cb(symb, v); 
     211    } 
     212     
     213protected: 
     214    bool v; 
    146215    void delegate (char[],bool)[] cngCb;       // change callbacks 
    147216} 
     
    153222        symb = symbol; 
    154223        v = val; 
    155     pos = v.length; 
    156224    } 
    157225     
     
    162230    } 
    163231     
    164     /// Get the text. 
    165     char[] toString (uint i) { 
    166         return (i == 0) ? v 
    167             : (i == 1) ? name_ 
    168             : (i == 2) ? desc_ 
    169             : null; 
    170     } 
    171      
     232    void assignNoCB (char[] val) { 
     233    v = val; 
     234    } 
    172235    void opAssign (char[] val) { 
    173236        v = val; 
     
    180243    alias opCall opCast; 
    181244     
    182     /** Acts on a keystroke and returns the new value. 
    183      * 
    184      * Supports one-line editing: left/right, home/end, backspace/delete. */ 
    185     char[] keyStroke (ushort sym, char[] i) { 
    186     debug assert (i.length, "TextContent.keyStroke: no value (??)");    // impossible? 
    187     char k = *i; 
    188     if (k > 0x20) { 
    189         if (k == 0x7f) {        // delete 
    190         size_t p = pos; 
    191         if (p < v.length) ++p; 
    192         while (p < v.length && (v[p] & 0x80) && !(v[p] & 0x40)) 
    193             ++p; 
    194         v = v[0..pos] ~ v[p..$]; 
    195         } else {            // insert character 
    196         char[] tail = v[pos..$]; 
    197         v.length = v.length + i.length; 
    198         size_t npos = pos+i.length; 
    199         if (tail) v[npos..$] = tail.dup;    // cannot assign with overlapping ranges 
    200             v[pos..npos] = i; 
    201         pos = npos; 
    202         } 
    203     } else {            // use sym; many keys output 0 
    204         if (sym == SDLK_BACKSPACE) {    // backspace; k == 0x8 
    205         char[] tail = v[pos..$]; 
    206         if (pos) --pos; 
    207         while (pos && (v[pos] & 0x80) && !(v[pos] & 0x40)) 
    208             --pos; 
    209         v = v[0..pos] ~ tail; 
    210         } else if (sym == SDLK_LEFT) { 
    211         if (pos) --pos; 
    212         while (pos && (v[pos] & 0x80) && !(v[pos] & 0x40)) 
    213             --pos; 
    214         } else if (sym == SDLK_RIGHT) { 
    215         if (pos < v.length) ++pos; 
    216         while (pos < v.length && (v[pos] & 0x80) && !(v[pos] & 0x40)) 
    217             ++pos; 
    218         } else if (sym == SDLK_HOME || sym == SDLK_UP) { 
    219         pos = 0; 
    220         } else if (sym == SDLK_END || sym == SDLK_DOWN) { 
    221         pos = v.length; 
    222         } else 
    223         debug logger.trace ("Symbol: {}", sym); 
    224     } 
    225     return v; 
    226     } 
    227      
    228     size_t getEditIndex () { 
    229     size_t i = 0; 
    230     for (size_t p = 0; p < pos; ++p) 
    231         if (!(v[p] & 0x80) || v[p] & 0x40) 
    232         ++i; 
    233     return i; 
    234     } 
    235      
    236     /// Gives all callbacks the modified value 
    237245    void endEdit () { 
    238246    foreach (cb; cngCb) 
     
    240248    } 
    241249     
    242     char[] v; 
    243 protected: 
    244     char[] symb; 
    245     size_t pos;     // editing position; used by keyStroke 
     250protected: 
     251    alias sv v;     // don't need separate v and sv in this case 
    246252    void delegate (char[],char[])[] cngCb; 
    247253} 
     
    253259    this (char[] symbol, int val = 0) { 
    254260        symb = symbol; 
    255         v = val
     261   assignNoCB (val)
    256262    } 
    257263     
     
    262268    } 
    263269     
    264     /// Get the text. 
    265     char[] toString (uint i) { 
    266         return (i == 0) ? Int.toString (v) 
    267         : (i == 1) ? name_ 
    268         : (i == 2) ? desc_ 
    269         : null; 
    270     } 
    271      
     270    void assignNoCB (int val) { 
     271    v = val; 
     272    sv = Int.toString (v); 
     273    } 
    272274    void opAssign (int val) { 
    273         v = val
    274         foreach (cb; cngCb) 
     275   assignNoCB (val)
     276   foreach (cb; cngCb) 
    275277            cb(symb, val); 
    276278    } 
     
    280282    alias opCall opCast; 
    281283     
     284    void endEdit () { 
     285    v = Int.toInt (sv); 
     286    foreach (cb; cngCb) 
     287        cb(symb, v); 
     288    } 
     289     
     290protected: 
    282291    int v; 
    283 protected: 
    284     char[] symb; 
    285292    void delegate (char[],int)[] cngCb; 
    286293} 
     
    292299    this (char[] symbol, double val = 0) { 
    293300        symb = symbol; 
    294         v = val
     301   assignNoCB (val)
    295302    } 
    296303     
     
    301308    } 
    302309     
    303     /// Get the text. 
    304     char[] toString (uint i) { 
    305         return (i == 0) ? Float.toString (v) 
    306         : (i == 1) ? name_ 
    307         : (i == 2) ? desc_ 
    308         : null; 
    309     } 
    310      
     310    void assignNoCB (double val) { 
     311    v = val; 
     312    sv = Float.toString (v); 
     313    } 
    311314    void opAssign (double val) { 
    312         v = val
    313         foreach (cb; cngCb) 
     315   assignNoCB (val)
     316   foreach (cb; cngCb) 
    314317            cb(symb, val); 
    315318    } 
     
    319322    alias opCall opCast; 
    320323     
     324    void endEdit () { 
     325    v = Float.toFloat (sv); 
     326    foreach (cb; cngCb) 
     327        cb(symb, v); 
     328    } 
     329     
     330protected: 
    321331    double v; 
    322 protected: 
    323     char[] symb; 
    324332    void delegate (char[],double)[] cngCb; 
    325333} 
  • mde/gui/widget/createWidget.d

    r99 r101  
    107107    DisplayContent  = TAKES_CONTENT | 0x30, 
    108108    BoolContent     = TAKES_CONTENT | 0x31, 
    109     TextContent       = TAKES_CONTENT | 0x32, 
     109    ValueContent      = TAKES_CONTENT | 0x32, 
    110110     
    111111    GridLayout      = TAKES_CONTENT | PARENT | 0x100, 
     
    127127        "DisplayContent", 
    128128        "BoolContent", 
    129     "TextContent", 
     129    "ValueContent", 
    130130        "editContent", 
    131131        "TrialContentLayout", 
  • mde/gui/widget/miscContent.d

    r99 r101  
    2929    if (cast(BoolContent) c) 
    3030        return new BoolContentWidget(mgr,id,data,c); 
    31     else if (cast(TextContent) c) 
    32     return new TextContentWidget(mgr,id,data,c); 
     31    else if (cast(ValueContent) c) 
     32    return new ValueContentWidget(mgr,id,data,c); 
    3333    else        // generic uneditable option 
    3434        return new DisplayContentWidget(mgr,id,data,c); 
  • mde/gui/widget/textContent.d

    r100 r101  
    3232} 
    3333 
    34  
    35 class TextContentWidget : ATextWidget 
     34/// Capable of editing any ValueContent class 
     35class ValueContentWidget : ATextWidget 
    3636{ 
    3737    this (IWidgetManager mgr, widgetID id, WidgetData data, IContent c) { 
    3838        WDCheck(data, 1); 
    39         content = cast(TextContent) c; 
    40         if (!content) content = new TextContent (null, null); 
    41         //throw new ContentException (); 
     39        content = cast(ValueContent) c; 
     40        if (!content) //content = new TextContent (null, null); 
     41        throw new ContentException (); 
    4242        adapter = mgr.renderer.getAdapter (content.toString(0)); 
    4343        super (mgr, id, data); 
     
    6464     
    6565protected: 
    66     TextContent content; 
     66    ValueContent content; 
    6767} 
  • mde/lookup/Options.d

    r98 r101  
    125125    if (p) { 
    126126        auto q = cast(`~VContentN!(T)~`) (*p); 
    127         if (q) q.v = parseTo!(`~T.stringof~`) (dt); 
     127        if (q) q.assignNoCB = parseTo!(`~T.stringof~`) (dt); 
    128128    } 
    129129}`; 
  • mde/scheduler/Scheduler.d

    r95 r101  
    2626    import tango.util.log.Log : Log, Logger; 
    2727    private Logger logger; 
    28 
    29 static this() { 
    30     debug logger = Log.getLogger ("mde.scheduler.Scheduler"); 
     28    static this() { 
     29    logger = Log.getLogger ("mde.scheduler.Scheduler"); 
     30    } 
    3131} 
    3232 
  • mde/setup/Init.d

    r98 r101  
    120120            if (args.contains("conf-path")) 
    121121                paths.extraConfPath = args["conf-path"]; 
     122         
    122123            if (args.contains("base-path")) 
    123124                paths.resolvePaths (args["base-path"]); 
  • mde/setup/paths.d

    r91 r101  
    4040import tango.io.Console; 
    4141import tango.io.FilePath; 
    42 import tango.sys.Environment; 
    43 //import tango.scrapple.sys.win32.Registry;     // Trouble getting this to work 
     42version (linux) { 
     43    import tango.io.FileScan; 
     44    import tango.util.container.SortedMap; 
     45    import tango.sys.Environment; 
     46} else version (Windows) 
     47    import tango.sys.win32.SpecialPath; 
     48 
     49debug { 
     50    import tango.util.log.Log : Log, Logger; 
     51    private Logger logger; 
     52    static this() { 
     53    logger = Log.getLogger ("mde.setup.paths"); 
     54    } 
     55
    4456 
    4557/** Order to read files in. 
     
    112124        Cout ("\nConf paths found:"); 
    113125        confDir.coutPaths; 
    114         Cout ("\nLog file directory:\n\t")(logDir).newline; 
     126        Cout ("\nLog file directory:\n\t")(logDir); 
     127    version (Windows) { 
     128        Cout ("\nFont directory:\n\t")(fontDir).newline; 
     129    } else version (linux) { 
     130        Cout ("\nFont filse found:"); 
     131        foreach (f,p; fontFiles) 
     132        Cout ("\n\t")(f)("\t")(p[0..$-1]); 
     133        Cout.newline; 
     134    } 
    115135    } 
    116136     
     
    191211/** These are the actual instances, one for each of the data and conf "directories". */ 
    192212mdeDirectory dataDir, confDir; 
    193 char[] logDir; 
     213char[] logDir;     /// Directory for log files 
    194214 
    195215//BEGIN Path resolution 
     
    203223// FIXME: use tango/sys/Environment.d 
    204224version (linux) { 
     225    SortedMap!(char[],char[]) fontFiles;    // key is file name, value is CString path 
     226    /** Get the actual path of a font file, or throw NoFileException if not found. 
     227     * 
     228     * Returns a C string (null terminated). */ 
     229    char[] getFontPath (char[] file) { 
     230    char[] ret; 
     231    if (fontFiles.get (file, ret)) 
     232        return ret; 
     233    throw new NoFileException ("Unable to find font file: "~file); 
     234    } 
     235     
    205236    // base-path not used on posix 
    206     void resolvePaths (char[] = null) { 
     237    void resolvePaths (char[] base = "data") { 
    207238        // Home directory: 
    208239        char[] HOME = Environment.get("HOME", "."); 
     
    211242        // Static data (must exist): 
    212243        FilePath staticPath = 
    213                 findPath (false, "/usr/share/games/mde", "/usr/local/share/games/mde", "data"); 
     244                findPath (false, "/usr/share/games/mde", "/usr/local/share/games/mde", base); 
    214245        // Config (can just use defaults if necessary, so long as we can save afterwards): 
    215246        FilePath userPath = findPath (true, HOME~"/.config/mde", HOME~"/.mde"); 
     
    230261        // Logging path: 
    231262        logDir = userPath.toString; 
     263     
     264    // Font paths: 
     265    auto fs = new FileScan; 
     266    // Scan for directories containing truetype and type1 fonts: 
     267    fs.sweep ("/usr/share/fonts", (FilePath fp, bool isDir) 
     268        {   return isDir || fp.suffix == ".ttf" || fp.suffix == ".pfb"; }, 
     269           true); 
     270    fontFiles = new SortedMap!(char[],char[]); 
     271    foreach (fp; fs.files) 
     272        fontFiles.add (fp.file, fp.cString);    // both strings should be slices of same memory 
     273    logger.trace ("found {} font files, {} dirs", fs.files.length, fs.folders.length); 
    232274    } 
    233275} else version (Windows) { 
     276    char[] fontDir; 
     277    /** Get the actual path of a font file, or throw NoFileException if not found. 
     278     * 
     279     * Returns a C string (null terminated). */ 
     280    char[] getFontPath (char[] file) { 
     281    FilePath path = new FilePath (fontDir~file); 
     282    if (path.exists && !path.isFolder) 
     283        return path.CString; 
     284    throw new NoFileException ("Unable to find font file: "~file); 
     285    } 
     286     
    234287    void resolvePaths (char[] base = "./") { 
    235         //FIXME: Get path from registry 
    236         //FIXME: Get user path (Docs&Settings/USER/Local Settings/Application data/mde) 
    237         //http://www.dsource.org/projects/tango/forums/topic/187 
     288        //FIXME: Get base path from registry 
    238289         
    239290        // Base paths: 
    240291        FilePath installPath = findPath (false, base); 
    241         FilePath staticPath = findPath (false, installPath.append("data").toString); 
    242         FilePath userPath = findPath (true, installPath.append("user").toString);   // FIXME: see above 
     292        FilePath staticPath = findPath (false, installPath.toString); 
     293    FilePath userPath = findPath (true, getSpecialPath(CSIDL_LOCAL_APPDATA) ~ "/mde"); 
    243294         
    244295        // Static data paths: 
     
    257308        // Logging path: 
    258309        logDir = userPath.toString; 
     310     
     311    // Font path: 
     312    fontDir = getSpecialPath (CSIDL_FONTS) ~ "/";   // append separator 
    259313    } 
    260314} else {