Changeset 100:0ea4a3e651ae
- Timestamp:
- 11/15/08 12:39:14
(2 months ago)
- Author:
- Diggory Hardy <diggory.hardy@gmail.com>
- branch:
- default
- Message:
There is now a position marker for text editing.
Changed the way fonts are configured. Actually, not much of the new way exists yet.
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r99 |
r100 |
|
| 17 | 17 | <WidgetData|floating={0:[0x8200,13,6,14],1:["text","button","blank"]}> |
|---|
| 18 | 18 | <WidgetData|text={0:[0x4032]}> |
|---|
| 19 | | <WDims|content=[736,221,272,79]> |
|---|
| 20 | | <WDims|root=[6,736,50,6,580,6]> |
|---|
| 21 | | <WDims|floating=[25,0,103,27,572,26,74,74,242,128,168,93]> |
|---|
| 22 | 19 | {Basic} |
|---|
| 23 | 20 | <WidgetData|root={0:[0x21,0x90D970],1:["A string!"]}> |
|---|
| r98 |
r100 |
|
| 11 | 11 | <int|lcdFilter=2> |
|---|
| 12 | 12 | <int|renderMode=0x30000> |
|---|
| | 13 | <char[]|defaultFont="/usr/share/fonts/X11/Type1/n019003l.pfb"> |
|---|
| | 14 | !<char[]|defaultFont="/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"> |
|---|
| | 15 | <int|defaultSize=16> |
|---|
| 13 | 16 | |
|---|
| 14 | 17 | {VideoOptions} |
|---|
| r98 |
r100 |
|
| 61 | 61 | } |
|---|
| 62 | 62 | |
|---|
| 63 | | |
|---|
| 64 | 63 | /** Cache informatation for rendering a block of text. |
|---|
| 65 | 64 | * |
|---|
| … | … | |
| 74 | 73 | |
|---|
| 75 | 74 | cache.cacheVer = cacheVer; |
|---|
| | 75 | cache.w = cache.h = 0; // reset |
|---|
| 76 | 76 | |
|---|
| 77 | 77 | /* Convert the string to an array of character codes (which is equivalent to decoding UTF8 |
|---|
| … | … | |
| 151 | 151 | * x = Smaller x-coordinate of position |
|---|
| 152 | 152 | * y = Smaller y-coordinate of position |
|---|
| 153 | | * col = Text colour (note: currently limited to black or white) */ |
|---|
| 154 | | void drawCache (FT_Face face, char[] str, ref TextBlock cache, int x, int y, Colour col ) { |
|---|
| | 153 | * col = Text colour (note: currently limited to black or white) |
|---|
| | 154 | * index = Index of edit position, or size_t.max if no idet position. */ |
|---|
| | 155 | void drawCache (FT_Face face, char[] str, ref TextBlock cache, int x, int y, Colour col, size_t index) { |
|---|
| 155 | 156 | updateCache (face, str, cache); // update if necessary |
|---|
| 156 | 157 | debug scope (failure) |
|---|
| … | … | |
| 160 | 161 | glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); |
|---|
| 161 | 162 | |
|---|
| 162 | | drawCacheImpl (cache, x, y, col); |
|---|
| | 163 | drawCacheImpl (face, cache, x, y, col, index); |
|---|
| 163 | 164 | } |
|---|
| 164 | 165 | /** A variation of drawCache, for transparent text. |
|---|
| … | … | |
| 174 | 175 | * |
|---|
| 175 | 176 | * The overhead of the transparency is minimal. */ |
|---|
| 176 | | void drawCacheA (FT_Face face, char[] str, ref TextBlock cache, int x, int y, Colour col/+ = Colour.WHITE+/) { |
|---|
| | 177 | void drawCacheA (FT_Face face, char[] str, ref TextBlock cache, int x, int y, Colour col, size_t index) { |
|---|
| 177 | 178 | updateCache (face, str, cache); // update if necessary |
|---|
| 178 | 179 | debug scope (failure) |
|---|
| … | … | |
| 183 | 184 | glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
|---|
| 184 | 185 | |
|---|
| 185 | | drawCacheImpl (cache, x, y, col); |
|---|
| 186 | | } |
|---|
| 187 | | |
|---|
| 188 | | private void drawCacheImpl (ref TextBlock cache, int x, int y, Colour col) { |
|---|
| | 186 | drawCacheImpl (face, cache, x, y, col, index); |
|---|
| | 187 | } |
|---|
| | 188 | |
|---|
| | 189 | private void drawCacheImpl (FT_Face face, ref TextBlock cache, int x, int y, Colour col, size_t index) { |
|---|
| 189 | 190 | if (DerelictGL.availableVersion() >= GLVersion.Version14) { |
|---|
| 190 | 191 | glBlendFunc (GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR); |
|---|
| … | … | |
| 217 | 218 | glEnd (); |
|---|
| 218 | 219 | } |
|---|
| 219 | | |
|---|
| 220 | | glDisable(GL_TEXTURE_2D); |
|---|
| | 220 | glDisable(GL_TEXTURE_2D); |
|---|
| 221 | 221 | glDisable(GL_BLEND); |
|---|
| | 222 | |
|---|
| | 223 | if (index <= cache.chars.length) { // draw edit position |
|---|
| | 224 | int x1; |
|---|
| | 225 | if (index == 0) |
|---|
| | 226 | x1 = x + 1; |
|---|
| | 227 | else { |
|---|
| | 228 | auto c = cache.chars[index-1]; |
|---|
| | 229 | x1 = x + c.xPos + c.ga.advanceX; |
|---|
| | 230 | } |
|---|
| | 231 | glColor3f(col.r, col.g, col.b); |
|---|
| | 232 | glRecti(x1 - 1, y, x1, y + (face.size.metrics.height >> 6)); |
|---|
| | 233 | } |
|---|
| 222 | 234 | } |
|---|
| 223 | 235 | |
|---|
| … | … | |
| 447 | 459 | * lcdFilter should come from enum FT_LcdFilter: |
|---|
| 448 | 460 | * FT_LCD_FILTER_NONE (0), FT_LCD_FILTER_DEFAULT (1), FT_LCD_FILTER_LIGHT (2) */ |
|---|
| 449 | | mixin (impl!("int renderMode, lcdFilter;")); |
|---|
| | 461 | mixin (impl!("int renderMode, lcdFilter, defaultSize; char[] defaultFont;")); |
|---|
| | 462 | |
|---|
| | 463 | void validate() { |
|---|
| | 464 | } |
|---|
| 450 | 465 | |
|---|
| 451 | 466 | static this() { |
|---|
| … | … | |
| 470 | 485 | * Struct should be stored externally and updated via references. */ |
|---|
| 471 | 486 | struct TextBlock { |
|---|
| 472 | | CharCache[] chars; // All chars. They hold x & y pos. info, so don't need to know about lines. |
|---|
| 473 | | int cacheVer = -1; // this is checked on access, and must equal for cache to be valid. |
|---|
| 474 | | int w, h; /// Size of the block. Likely the only fields of use outside the library. |
|---|
| | 487 | CharCache[] chars; /// All chars. They hold x & y pos. info, so don't need to know about lines. |
|---|
| | 488 | int cacheVer = -1; /// Checked on access; must equalFontTexture.cacheVer or the cache is rebuilt. |
|---|
| | 489 | int w, h; /// Size of the block. |
|---|
| 475 | 490 | } |
|---|
| 476 | 491 | struct CharCache { |
|---|
| 477 | | GlyphAttribs* ga; // character |
|---|
| 478 | | int xPos, yPos; // x,y position |
|---|
| 479 | | } |
|---|
| | 492 | GlyphAttribs* ga; /// The character |
|---|
| | 493 | int xPos, yPos; /// Character's x,y position |
|---|
| | 494 | } |
|---|
| r98 |
r100 |
|
| 22 | 22 | import mde.font.exception; |
|---|
| 23 | 23 | |
|---|
| 24 | | import mde.file.mergetag.Reader; |
|---|
| 25 | | import mde.file.mergetag.DataSet; |
|---|
| 26 | | import mde.setup.paths; |
|---|
| 27 | 24 | import mde.setup.exception; // InitStage stuff |
|---|
| 28 | 25 | |
|---|
| 29 | 26 | import derelict.freetype.ft; |
|---|
| 30 | 27 | |
|---|
| 31 | | import mde.file.deserialize; |
|---|
| 32 | 28 | import tango.stdc.stringz; |
|---|
| 33 | 29 | import Util = tango.text.Util; |
|---|
| … | … | |
| 47 | 43 | * |
|---|
| 48 | 44 | * Note: it is not currently intended to be thread-safe. */ |
|---|
| 49 | | class FontStyle : IDataSection |
|---|
| | 45 | class FontStyle |
|---|
| 50 | 46 | { |
|---|
| 51 | 47 | //BEGIN Static: manager |
|---|
| … | … | |
| 56 | 52 | } |
|---|
| 57 | 53 | |
|---|
| 58 | | /** Load the freetype library with settings from the file fileName. */ |
|---|
| 59 | | private const fileName = "fonts"; |
|---|
| | 54 | /** Load the freetype library with settings from options. */ |
|---|
| 60 | 55 | StageState initialize () { |
|---|
| 61 | 56 | if (FT_Init_FreeType (&library)) |
|---|
| … | … | |
| 67 | 62 | if (maj != 2 || min != 3) { |
|---|
| 68 | 63 | logger.warn ("Using an untested FreeType version: {}.{}.{}", maj, min, patch); |
|---|
| 69 | | logger.info ("The only tested version of freetype is 2.3.5"); |
|---|
| | 64 | logger.info ("The only tested version of freetype is 2.3"); |
|---|
| 70 | 65 | } |
|---|
| 71 | 66 | |
|---|
| … | … | |
| 87 | 82 | } |
|---|
| 88 | 83 | |
|---|
| 89 | | /* Load font settings |
|---|
| 90 | | * |
|---|
| 91 | | * Each mergetag section corresponds to a font; each is loaded whether used or not |
|---|
| 92 | | * (however the actual font files are only loaded on use). A fallback id must be |
|---|
| 93 | | * provided in the header which must match a loaded font name; if a non-existant font |
|---|
| 94 | | * is requested a warning will be logged and this font returned. */ |
|---|
| 95 | | char[] fallbackName; |
|---|
| 96 | | try { |
|---|
| 97 | | IReader reader; |
|---|
| 98 | | reader = confDir.makeMTReader (fileName, PRIORITY.LOW_HIGH, null, true); |
|---|
| 99 | | reader.dataSecCreator = delegate IDataSection(ID id) { |
|---|
| 100 | | auto f = new FontStyle; |
|---|
| 101 | | fonts[id] = f; |
|---|
| 102 | | return f; |
|---|
| 103 | | }; |
|---|
| 104 | | reader.read; |
|---|
| 105 | | |
|---|
| 106 | | // get fallback name |
|---|
| 107 | | char[]* p = "fallback" in reader.dataset.header._charA; |
|---|
| 108 | | if (p is null) |
|---|
| 109 | | throw new fontException ("No fallback font style specified"); |
|---|
| 110 | | fallbackName = *p; |
|---|
| 111 | | } catch (NoFileException) { |
|---|
| 112 | | throw new fontException ("No font settings file (fonts.[mtt|mtb])"); |
|---|
| 113 | | } catch (Exception e) { |
|---|
| 114 | | throw new fontException ("Reading font settings failed: "~e.msg); |
|---|
| 115 | | } |
|---|
| 116 | | |
|---|
| 117 | | // Find the fallback |
|---|
| 118 | | FontStyle* p = fallbackName in fonts; |
|---|
| 119 | | if (p is null) |
|---|
| 120 | | throw new fontException ("Fallback font style specified is not found"); |
|---|
| 121 | | fallback = *p; |
|---|
| 122 | | // Load the fallback now, to ensure it's available. |
|---|
| 123 | | // Also note that get() doesn't make sure the fallback is loaded before returning it. |
|---|
| 124 | | fallback.load; |
|---|
| 125 | | |
|---|
| | 84 | // Load the fallback font; if it throws let exception abort program |
|---|
| | 85 | fallback = new FontStyle (fontOpts.defaultFont(), fontOpts.defaultSize()); |
|---|
| | 86 | |
|---|
| 126 | 87 | return StageState.ACTIVE; |
|---|
| 127 | 88 | } |
|---|
| … | … | |
| 130 | 91 | StageState cleanup () { |
|---|
| 131 | 92 | // Clear loaded fonts (each has an FT_Face object needing to be freed): |
|---|
| 132 | | foreach (fs; fonts) |
|---|
| | 93 | /* FIXME |
|---|
| | 94 | foreach (fs; fonts) |
|---|
| 133 | 95 | fs.freeFace; |
|---|
| | 96 | */ |
|---|
| 134 | 97 | |
|---|
| 135 | 98 | FT_Done_FreeType (library); // free the library |
|---|
| … | … | |
| 145 | 108 | * this function should never fail or throw, in theory (unless out of memory). The |
|---|
| 146 | 109 | * fallback should already be loaded. */ |
|---|
| 147 | | FontStyle get(char[] name) { |
|---|
| 148 | | FontStyle* p = name in fonts; |
|---|
| 149 | | if (p is null) { |
|---|
| 150 | | logger.warn ("Font style "~name~" requested but not found; reverting to the fallback style."); |
|---|
| 151 | | fonts[name] = fallback; // set to prevent another warning getting logged |
|---|
| 152 | | return fallback; |
|---|
| 153 | | } |
|---|
| 154 | | // Got it, but we need to make sure it's loaded: |
|---|
| 155 | | try { |
|---|
| 156 | | p.load; |
|---|
| 157 | | } catch (Exception e) { |
|---|
| 158 | | logger.warn ("Font style "~name~" failed to load; reverting to the fallback style."); |
|---|
| 159 | | return fallback; |
|---|
| 160 | | } |
|---|
| 161 | | return *p; |
|---|
| | 110 | FontStyle getDefault () { |
|---|
| | 111 | //FIXME: Ddoc, new purpose; rename |
|---|
| | 112 | return fallback; |
|---|
| 162 | 113 | } |
|---|
| 163 | 114 | |
|---|
| … | … | |
| 165 | 116 | FT_Library library; |
|---|
| 166 | 117 | FontTexture fontTex; |
|---|
| 167 | | FontStyle[ID] fonts; // all font styles known about; not necessarily loaded |
|---|
| 168 | | FontStyle fallback; // used when requested font isn't in fonts |
|---|
| | 118 | //FontStyle[char[]] fonts; // loaded fonts, by file name FIXME: use hash of struct { char[] path; int size; }? |
|---|
| | 119 | FontStyle fallback; // default & used when requested font can't be loaded |
|---|
| 169 | 120 | } |
|---|
| 170 | 121 | //END Static |
|---|
| 171 | | |
|---|
| 172 | | this() {} |
|---|
| 173 | | |
|---|
| 174 | | //BEGIN Mergetag code |
|---|
| 175 | | //NOTE: would it be better not to use a new mergetag file for this? |
|---|
| 176 | | //FIXME: revise when gui can set options |
|---|
| 177 | | void addTag (char[] tp, ID id, char[] dt) { |
|---|
| 178 | | if (tp == "char[]") { |
|---|
| 179 | | if (id == "path") |
|---|
| 180 | | path = parseTo!(char[]) (dt); |
|---|
| 181 | | } |
|---|
| 182 | | else if (tp == "int") { |
|---|
| 183 | | if (id == "size") |
|---|
| 184 | | size = parseTo!(int) (dt); |
|---|
| 185 | | } |
|---|
| 186 | | } |
|---|
| 187 | | void writeAll (ItemDelg) {} // no writing the config for now |
|---|
| 188 | | //END Mergetag code |
|---|
| 189 | 122 | |
|---|
| 190 | 123 | /** Load the font file. |
|---|
| … | … | |
| 193 | 126 | * Sharing an FT_Face would require calling FT_Set_Pixel_Sizes each time a glyph is rendered or |
|---|
| 194 | 127 | * swapping the size information (face.size)? */ |
|---|
| 195 | | void load () |
|---|
| | 128 | this (char[] path, int size) |
|---|
| 196 | 129 | in { |
|---|
| 197 | 130 | assert (library !is null, "font: library is null"); |
|---|
| … | … | |
| 207 | 140 | */ |
|---|
| 208 | 141 | |
|---|
| 209 | | if (FT_Set_Pixel_Sizes (face, 0,size)) |
|---|
| | 142 | if (FT_Set_Pixel_Sizes (face, 0, size)) |
|---|
| 210 | 143 | throw new fontLoadException ("Unable to set pixel size"); |
|---|
| 211 | 144 | |
|---|
| … | … | |
| 213 | 146 | if (fontTex is null) |
|---|
| 214 | 147 | fontTex = new FontTexture; |
|---|
| | 148 | |
|---|
| | 149 | return this; |
|---|
| | 150 | } |
|---|
| | 151 | |
|---|
| | 152 | this (FontStyle font, int size) { |
|---|
| | 153 | //FIXME: copy font's face and set new size? |
|---|
| 215 | 154 | } |
|---|
| 216 | 155 | |
|---|
| … | … | |
| 235 | 174 | /** Draw a block of text (may inlcude new-lines). |
|---|
| 236 | 175 | * |
|---|
| | 176 | * Params: |
|---|
| | 177 | * x = Top left x-coordinate of text block |
|---|
| | 178 | * y = Top left y-coordinate of text block |
|---|
| | 179 | * str = Text to render |
|---|
| | 180 | * cache = An (optional) TextBlock used for rendering this text, to save some CPU work. See updateBlock |
|---|
| | 181 | * col = Colour to render the text; see mde.types.Colour |
|---|
| | 182 | * index = Either the index of the character to draw with an edit cursor or size_t.max. Not |
|---|
| | 183 | * the index within str, but the number of characters, excluding new-lines. |
|---|
| 237 | 184 | * The text block is drawn with top-left corner at x,y. To put the text's baseline at a given |
|---|
| 238 | | * y coordinate would require some changes. Line height is fixed based on largest glyph. |
|---|
| | 185 | * y coordinate would require some changes. Line height is fixed (see getLineSeparation). |
|---|
| 239 | 186 | * Due to hinter, glyphs are not guaranteed to lie within the "bounding box" defined by cache. |
|---|
| 240 | 187 | * Can be changed to test size of each glyph if necessary. |
|---|
| … | … | |
| 248 | 195 | * char[] str; |
|---|
| 249 | 196 | * TextBlock strCache; |
|---|
| 250 | | * textBlock (x, y, str, strCache); |
|---|
| | 197 | * textBlock (x, y, str, strCache, Colour.WHITE); |
|---|
| 251 | 198 | * --------------------------------- |
|---|
| 252 | 199 | * The TextBlock cache will be updated as necessary. Besides the initial update, this will only |
|---|
| … | … | |
| 258 | 205 | * of a text block is to use a TextBlock cache and update it, either with this function or with |
|---|
| 259 | 206 | * the updateBlock function. */ |
|---|
| 260 | | void textBlock (int x, int y, char[] str, ref TextBlock cache, Colour col) |
|---|
| 261 | | in { |
|---|
| 262 | | assert (face, "FontStyle: face is null"); |
|---|
| 263 | | } body { |
|---|
| 264 | | try { |
|---|
| 265 | | fontTex.drawCache (face, str, cache, x, y, col); |
|---|
| | 207 | void textBlock (int x, int y, char[] str, ref TextBlock cache, Colour col, size_t index = size_t.max) |
|---|
| | 208 | in { |
|---|
| | 209 | assert (face, "FontStyle: face is null"); |
|---|
| | 210 | } body { |
|---|
| | 211 | try { |
|---|
| | 212 | fontTex.drawCache (face, str, cache, x, y, col, index); |
|---|
| 266 | 213 | } catch (Exception e) { |
|---|
| 267 | 214 | logger.warn ("Exception while drawing text: "~e.msg); |
|---|
| … | … | |
| 269 | 216 | } |
|---|
| 270 | 217 | /** ditto */ |
|---|
| 271 | | void textBlock (int x, int y, char[] str, Colour col) |
|---|
| | 218 | void textBlock (int x, int y, char[] str, Colour col, size_t index = size_t.max) |
|---|
| 272 | 219 | in { |
|---|
| 273 | 220 | assert (face, "FontStyle: face is null"); |
|---|
| … | … | |
| 278 | 225 | // would be horrible). |
|---|
| 279 | 226 | TextBlock cache; |
|---|
| 280 | | fontTex.drawCache (face, str, cache, x, y, col); |
|---|
| | 227 | fontTex.drawCache (face, str, cache, x, y, col, index); |
|---|
| 281 | 228 | } catch (Exception e) { |
|---|
| 282 | 229 | logger.warn ("Exception while drawing text: "~e.msg); |
|---|
| … | … | |
| 288 | 235 | * Set the alpha by calling glColor*() first. See FontTexture.drawCacheA()'s documentation for |
|---|
| 289 | 236 | * details. */ |
|---|
| 290 | | void textBlockA (int x, int y, char[] str, ref TextBlock cache, Colour col) |
|---|
| 291 | | in { |
|---|
| 292 | | assert (face, "FontStyle: face is null"); |
|---|
| 293 | | } body { |
|---|
| 294 | | try { |
|---|
| 295 | | fontTex.drawCacheA (face, str, cache, x, y, col); |
|---|
| | 237 | void textBlockA (int x, int y, char[] str, ref TextBlock cache, Colour col, size_t index = size_t.max) |
|---|
| | 238 | in { |
|---|
| | 239 | assert (face, "FontStyle: face is null"); |
|---|
| | 240 | } body { |
|---|
| | 241 | try { |
|---|
| | 242 | fontTex.drawCacheA (face, str, cache, x, y, col, index); |
|---|
| 296 | 243 | } catch (Exception e) { |
|---|
| 297 | 244 | logger.warn ("Exception while drawing text: "~e.msg); |
|---|
| … | … | |
| 313 | 260 | |
|---|
| 314 | 261 | private: |
|---|
| 315 | | char[] path; // path to font file |
|---|
| 316 | | int size; // font size |
|---|
| 317 | | |
|---|
| 318 | 262 | FT_Face face; |
|---|
| 319 | | |
|---|
| 320 | | debug(mdeUnitTest) unittest { |
|---|
| 321 | | // Don't do a unittest since font relies on loading the freetype library dynamically, |
|---|
| 322 | | // normally done by Init. Also font is mostly visual and many problems will be obvious. |
|---|
| 323 | | } |
|---|
| 324 | 263 | } |
|---|
| 325 | | |
|---|
| 326 | | /+class OptionsFont : Options { |
|---|
| 327 | | alias store!(+/ |
|---|
| r99 |
r100 |
|
| 226 | 226 | } |
|---|
| 227 | 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 | |
|---|
| 228 | 236 | /// Gives all callbacks the modified value |
|---|
| 229 | 237 | void endEdit () { |
|---|
| r99 |
r100 |
|
| 96 | 96 | colour = Colour (col); |
|---|
| 97 | 97 | } |
|---|
| | 98 | |
|---|
| | 99 | void setIndex (size_t index = size_t.max) { |
|---|
| | 100 | this.index = index; |
|---|
| | 101 | } |
|---|
| 98 | 102 | |
|---|
| 99 | 103 | void getDimensions (out wdsize w, out wdsize h) { |
|---|
| … | … | |
| 104 | 108 | |
|---|
| 105 | 109 | void draw (wdabs x, wdabs y) { |
|---|
| 106 | | font.textBlock (x,y, content, textCache, colour); |
|---|
| | 110 | font.textBlock (x,y, content, textCache, colour, index); |
|---|
| 107 | 111 | } |
|---|
| 108 | 112 | |
|---|
| 109 | 113 | char[] content; |
|---|
| 110 | 114 | TextBlock textCache; |
|---|
| | 115 | size_t index; |
|---|
| 111 | 116 | Colour colour; |
|---|
| 112 | 117 | FontStyle font; |
|---|
| r99 |
r100 |
|
| 32 | 32 | { |
|---|
| 33 | 33 | this () { |
|---|
| 34 | | defaultFont = FontStyle.get("default"); |
|---|
| | 34 | defaultFont = FontStyle.getDefault; |
|---|
| 35 | 35 | } |
|---|
| 36 | 36 | |
|---|
| … | … | |
| 136 | 136 | a.content = text; |
|---|
| 137 | 137 | a.colour = Colour (col); |
|---|
| 138 | | return a; |
|---|
| | 138 | a.index = size_t.max; |
|---|
| | 139 | return a; |
|---|
| 139 | 140 | } |
|---|
| 140 | 141 | |
|---|
| r99 |
r100 |
|
| 24 | 24 | import mde.gui.content.Content; |
|---|
| 25 | 25 | |
|---|
| | 26 | debug { |
|---|
| | 27 | import tango.util.log.Log : Log, Logger; |
|---|
| | 28 | private Logger logger; |
|---|
| | 29 | static this () { |
|---|
| | 30 | logger = Log.getLogger ("mde.gui.widget.textContent"); |
|---|
| | 31 | } |
|---|
| | 32 | } |
|---|
| | 33 | |
|---|
| 26 | 34 | |
|---|
| 27 | 35 | class TextContentWidget : ATextWidget |
|---|
| … | … | |
| 38 | 46 | /** On click, request keyboard input. */ |
|---|
| 39 | 47 | int clickEvent (wdabs, wdabs, ubyte, bool state) { |
|---|
| | 48 | adapter.setIndex = content.getEditIndex; |
|---|
| | 49 | mgr.requestRedraw; |
|---|
| 40 | 50 | return 1; // get keyboard input via keyEvent |
|---|
| 41 | 51 | } |
|---|
| 42 | 52 | |
|---|
| 43 | 53 | void keyEvent (ushort s, char[] i) { |
|---|
| 44 | | adapter.setText (content.keyStroke (s, i)); |
|---|
| 45 | | adapter.getDimensions (mw, mh); // FIXME: only passively change size: next resize will see new minimal size |
|---|
| | 54 | adapter.setText = content.keyStroke (s, i); |
|---|
| | 55 | adapter.setIndex = content.getEditIndex; |
|---|
| | 56 | adapter.getDimensions (mw, mh); // NOTE: only passively change size: next resize will see new minimal size |
|---|
| 46 | 57 | mgr.requestRedraw; |
|---|
| 47 | 58 | } |
|---|
| 48 | 59 | void keyFocusLost () { |
|---|
| | 60 | adapter.setIndex; |
|---|
| 49 | 61 | content.endEdit; // update other users of content relying on callbacks |
|---|
| | 62 | mgr.requestRedraw; |
|---|
| 50 | 63 | } |
|---|
| 51 | 64 | |
|---|