1 /++ 2 Contains functions that might be useful in making new widgets, 3 like for formatting text. 4 +/ 5 module qui.utils; 6 7 import qui.qui; 8 9 import utils.baseconv; 10 import utils.misc; 11 import std.conv : to; 12 13 /// To scroll a line, by an xOffset 14 /// 15 /// Can be used to scroll to right, or to left (by making xOffset negative). 16 /// Can also be used to fill an empty line with empty space (`' '`) to make it fill width, if `line.length < width` 17 /// 18 /// Arguments: 19 /// * `line` is the full line 20 /// * `xOffset` is the number of characters scrolled right 21 /// * `width` is the number of characters that are to be displayed 22 /// 23 /// Returns: the text that should be displayed 24 dstring scrollHorizontal(dstring line, integer xOffset, uinteger width){ 25 dchar[] r; 26 if (xOffset == 0){ 27 // in case it has to do nothing, 28 r = cast(dchar[])line[0 .. width > line.length ? line.length : width].dup; 29 }else if (xOffset > 0){ 30 // only do something if it's not scrolled too far for the line to be even displayed 31 if (xOffset < line.length){ 32 r = cast(dchar[])line[xOffset .. line.length].dup; 33 } 34 }else if (xOffset < 0){ 35 // only do something if it's not scrolled too far for the line to be even displayed 36 if (cast(integer)(line.length) + xOffset > 0){ 37 r.length = xOffset * -1; 38 r[] = ' '; 39 r = r ~ cast(dchar[])line.dup; 40 } 41 } 42 if (r.length < width){ 43 uinteger filledLength = r.length; 44 r.length = width; 45 r[filledLength .. r.length] = ' '; 46 }else if (r.length > width){ 47 r.length = width; 48 } 49 return cast(dstring)r; 50 } 51 /// 52 unittest{ 53 assert("0123456789".scrollHorizontal(5, 2) == "56"); 54 assert("0123456789".scrollHorizontal(0,10) == "0123456789"); 55 assert("0123456789".scrollHorizontal(10,4) == " "); 56 assert("0123456789".scrollHorizontal(-5,4) == " "); 57 assert("0123456789".scrollHorizontal(-5,6) == " 0"); 58 assert("0123456789".scrollHorizontal(-1,11) == " 0123456789"); 59 assert("0123456789".scrollHorizontal(-5,10) == " 01234"); 60 } 61 62 /// ditto 63 dchar[] scrollHorizontal(dchar[] line, integer xOffset, uinteger width){ 64 return cast(dchar[])(cast(dstring)line).scrollHorizontal(xOffset, width); 65 } 66 /// ditto 67 char[] scrollHorizontal(char[] line, integer xOffset, uinteger width){ 68 return cast(char[])(cast(dstring)line).scrollHorizontal(xOffset, width); 69 } 70 71 /// Adjusts offset (aka _scrollX or _scrollY) in scrolling so the selected character is visible TODO: FIX THIS 72 /// 73 /// Arguemnts: 74 /// * `selected` is the character on which the cursor is. If it's >lineWidth, `selected=lineWidth` 75 /// * `size` is the width/height (depending on if it's horizontal or vertical scrolling) of the space where the line is to be displayed 76 /// * `offset` is the variable storing the offset (_xOffset or _yOffset) 77 void adjustScrollingOffset(ref uinteger selected, uinteger size, uinteger lineWidth, ref uinteger offset){ 78 // if selected is outside size, it shouldn't be 79 if (selected > lineWidth){ 80 selected = lineWidth; 81 } 82 // range of characters' index that's visible (1 is inclusive, 2 is not) 83 uinteger visible1, visible2; 84 visible1 = offset; 85 visible2 = offset + size; 86 if (selected < visible1 || selected >= visible2){ 87 if (selected < visible1){ 88 // scroll back 89 offset = selected; 90 }else if (selected >= visible2){ 91 // scroll ahead 92 offset = selected+1 - (size); 93 } 94 } 95 } 96 97 /// Center-aligns text 98 /// 99 /// If `text.length > width`, the exceeding characters are removed 100 /// 101 /// Returns: the text center aligned in a string 102 dstring centerAlignText(dstring text, uinteger width, dchar fill = ' '){ 103 dchar[] r; 104 if (text.length < width){ 105 r.length = width; 106 uinteger offset = (width - text.length)/2; 107 r[0 .. offset] = fill; 108 r[offset .. offset+text.length][] = text; 109 r[offset+text.length .. r.length] = fill; 110 }else{ 111 r = cast(dchar[])text[0 .. width].dup; 112 } 113 return cast(dstring)r; 114 } 115 /// 116 unittest{ 117 assert("qwr".centerAlignText(7) == " qwr "); 118 } 119 120 /// To calculate size of widgets using their sizeRatio 121 deprecated uinteger ratioToRaw(uinteger selectedRatio, uinteger ratioTotal, uinteger total){ 122 uinteger r; 123 r = cast(uinteger)((cast(float)selectedRatio/cast(float)ratioTotal)*total); 124 return r; 125 }