sources/interface.cpp

changeset 23
f7221183a994
parent 20
5f8cdc8febbb
child 24
e651d02802c0
equal deleted inserted replaced
22:77d02446edf0 23:f7221183a994
43 static bool g_needOutputRender = false; 43 static bool g_needOutputRender = false;
44 static String g_statusBarText; 44 static String g_statusBarText;
45 static struct { char ch; int x; } g_cursorChar; 45 static struct { char ch; int x; } g_cursorChar;
46 static Vector<String> g_output = {""}; 46 static Vector<String> g_output = {""};
47 static int g_outputScroll = 0; 47 static int g_outputScroll = 0;
48 static String g_title;
48 49
49 // ------------------------------------------------------------------------------------------------- 50 // -------------------------------------------------------------------------------------------------
50 // 51 //
51 static FUNCTION 52 static FUNCTION
52 interface_color_pair (Color fg, Color bg) -> int 53 interface_color_pair (Color fg, Color bg) -> int
64 ::raw(); 65 ::raw();
65 ::keypad (stdscr, true); 66 ::keypad (stdscr, true);
66 ::noecho(); 67 ::noecho();
67 ::refresh(); 68 ::refresh();
68 ::timeout (0); 69 ::timeout (0);
70 g_title = format (APPNAME " %1 (%2)", full_version_string(), changeset_date_string());
69 71
70 for (int i = 0; i < NUM_COLORS; ++i) 72 for (int i = 0; i < NUM_COLORS; ++i)
71 for (int j = 0; j < NUM_COLORS; ++j) 73 for (int j = 0; j < NUM_COLORS; ++j)
72 { 74 {
73 init_pair ((i * NUM_COLORS + j), 75 init_pair ((i * NUM_COLORS + j),
89 } 91 }
90 92
91 // ------------------------------------------------------------------------------------------------- 93 // -------------------------------------------------------------------------------------------------
92 // 94 //
93 static FUNCTION 95 static FUNCTION
94 interface_clear_titlebar() -> void
95 {
96 int pair = interface_color_pair (WHITE, BLUE);
97 attron (pair);
98 mvhline (0, 0, ' ', COLS);
99 attroff (pair);
100 }
101
102 // -------------------------------------------------------------------------------------------------
103 //
104 static FUNCTION
105 interface_render_titlebar() -> void 96 interface_render_titlebar() -> void
106 { 97 {
107 String versionText = format (APPNAME " %1 (%2)", 98 if (g_title.length() <= COLS)
108 full_version_string(), changeset_date_string());
109
110 if (versionText.length() <= COLS)
111 { 99 {
112 int pair = interface_color_pair (WHITE, BLUE); 100 int pair = interface_color_pair (WHITE, BLUE);
101 int startx = (COLS - g_title.length()) / 2;
102 int endx = startx + g_title.length();
103 print ("startx: %1, endx: %2\n", startx, endx);
104
113 attron (pair); 105 attron (pair);
114 mvprintw (0, (COLS - versionText.length()) / 2, "%s", versionText.chars()); 106 mvprintw (0, startx, "%s", g_title.chars());
107 mvhline (0, 0, ' ', startx);
108 mvhline (0, endx, ' ', COLS - endx);
115 attroff (pair); 109 attroff (pair);
116 } 110 }
111
112 g_needRefresh = true;
113 }
114
115 // -------------------------------------------------------------------------------------------------
116 //
117 FUNCTION
118 Interface::set_title (const String& title) -> void
119 {
120 g_title = title;
121 interface_render_titlebar();
117 } 122 }
118 123
119 // ------------------------------------------------------------------------------------------------- 124 // -------------------------------------------------------------------------------------------------
120 // 125 //
121 static FUNCTION 126 static FUNCTION
146 // ------------------------------------------------------------------------------------------------- 151 // -------------------------------------------------------------------------------------------------
147 // 152 //
148 static FUNCTION 153 static FUNCTION
149 interface_render_input() -> void 154 interface_render_input() -> void
150 { 155 {
151 static char prompt[] = "> "; 156 static char prompt[] = ">";
152 int displaylength = COLS - strlen (prompt) - 1; 157 int displaylength = COLS - strlen (prompt) - 2;
153 int y = LINES - 2; 158 int y = LINES - 2;
154 159
155 // Ensure the cursor is within bounds 160 // Ensure the cursor is within bounds
156 g_cursor = clamp (g_cursor, 0, g_input.length()); 161 g_cursor = clamp (g_cursor, 0, g_input.length());
157 162
162 g_pan = g_cursor; // cursor went past the pan value to the left 167 g_pan = g_cursor; // cursor went past the pan value to the left
163 168
164 int start = g_pan; 169 int start = g_pan;
165 int end = min<int> (g_input.length(), start + displaylength); 170 int end = min<int> (g_input.length(), start + displaylength);
166 assert (g_cursor >= start and g_cursor <= end); 171 assert (g_cursor >= start and g_cursor <= end);
167 String displayTextBegin = g_input.mid (start, g_cursor);
168 String displayTextEnd = g_input.mid (g_cursor, end);
169 172
170 // Clear, but only as much as is necessary. I want to avoid clearing the entire line to save 173 // Clear, but only as much as is necessary. I want to avoid clearing the entire line to save
171 // bandwidth over SSH connections. Perhaps needlessly? I'm paranoid. 174 // bandwidth over SSH connections. Perhaps needlessly? I'm paranoid.
172 int renderLength = strlen (prompt) + displayTextBegin.length() + displayTextEnd.length(); 175 int renderLength = strlen (prompt) + 1 + g_input.length();
173 static int lastRenderLength = 0; 176 static int lastRenderLength = 0;
174 177
175 if (lastRenderLength > renderLength) 178 if (lastRenderLength > renderLength)
176 mvhline (y, renderLength, ' ', lastRenderLength - renderLength); 179 mvhline (y, renderLength, ' ', lastRenderLength - renderLength);
177 180
178 lastRenderLength = renderLength; 181 lastRenderLength = renderLength;
179 182
180 // Render the input line, with the part of the input string that's before the cursor written 183 // Render the input line, with the part of the input string that's before the cursor written
181 // AFTER the part that comes afterwards. This is to ensure that the cursor is placed at the 184 // AFTER the part that comes afterwards. This is to ensure that the cursor is placed at the
182 // position where our cursor is. It looks nice like that. :) 185 // position where our cursor is. It looks nice like that. :)
186
187 int pair = interface_color_pair (WHITE, BLUE);
188 attron (pair);
183 mvprintw (y, 0, "%s", prompt); 189 mvprintw (y, 0, "%s", prompt);
184 mvprintw (y, strlen (prompt) + displayTextBegin.length(), "%s", displayTextEnd.chars()); 190 attroff (pair);
185 mvprintw (y, strlen (prompt), "%s", displayTextBegin.chars()); 191 mvprintw (y, strlen (prompt) + 1, "%s", g_input.chars());
186 g_cursorChar.ch = g_cursor != 0 ? g_input[g_cursor - 1] : '\0'; 192 g_cursorChar.ch = g_cursor != 0 ? g_input[g_cursor - 1] : '\0';
187 g_cursorChar.x = strlen (prompt) + displayTextBegin.length() - 1; 193 g_cursorChar.x = strlen (prompt) + (g_cursor - g_pan);
188 g_needRefresh = true; 194 g_needRefresh = true;
189 g_needInputRender = false; 195 g_needInputRender = false;
190 } 196 }
191 197
192 // ------------------------------------------------------------------------------------------------- 198 // -------------------------------------------------------------------------------------------------
213 // ------------------------------------------------------------------------------------------------- 219 // -------------------------------------------------------------------------------------------------
214 // 220 //
215 FUNCTION 221 FUNCTION
216 Interface::render_full() -> void 222 Interface::render_full() -> void
217 { 223 {
218 interface_clear_titlebar();
219 interface_render_titlebar(); 224 interface_render_titlebar();
220 interface_render_output(); 225 interface_render_output();
221 interface_render_statusbar(); 226 interface_render_statusbar();
222 interface_render_input(); 227 interface_render_input();
223 } 228 }

mercurial