@@ -185,40 +185,53 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
185185#ifdef HAVE_LIBNCURSESW
186186
187187#define PIXPERROW_UTF8 4
188- static const char * const GraphMeterMode_dotsUtf8 [] = {
188+ static const char * const GraphMeterMode_top_dotsUtf8 [] = {
189189 /*00*/ " " , /*01*/ "⢀" , /*02*/ "⢠" , /*03*/ "⢰" , /*04*/ "⢸" ,
190190 /*10*/ "⡀" , /*11*/ "⣀" , /*12*/ "⣠" , /*13*/ "⣰" , /*14*/ "⣸" ,
191191 /*20*/ "⡄" , /*21*/ "⣄" , /*22*/ "⣤" , /*23*/ "⣴" , /*24*/ "⣼" ,
192192 /*30*/ "⡆" , /*31*/ "⣆" , /*32*/ "⣦" , /*33*/ "⣶" , /*34*/ "⣾" ,
193193 /*40*/ "⡇" , /*41*/ "⣇" , /*42*/ "⣧" , /*43*/ "⣷" , /*44*/ "⣿"
194194};
195195
196+ static const char * const GraphMeterMode_bottom_dotsUtf8 [] = {
197+ /*00*/ " " , /*01*/ "⠈" , /*02*/ "⠘" , /*03*/ "⠸" , /*04*/ "⢸" ,
198+ /*10*/ "⠁" , /*11*/ "⠉" , /*12*/ "⠙" , /*13*/ "⠹" , /*14*/ "⢹" ,
199+ /*20*/ "⠃" , /*21*/ "⠋" , /*22*/ "⠛" , /*23*/ "⠻" , /*24*/ "⢻" ,
200+ /*30*/ "⠇" , /*31*/ "⠏" , /*32*/ "⠟" , /*33*/ "⠿" , /*34*/ "⢿" ,
201+ /*40*/ "⡇" , /*41*/ "⡏" , /*42*/ "⡟" , /*43*/ "⡿" , /*44*/ "⣿"
202+ };
203+
204+ static const char * const * const GraphMeterMode_dotsUtf8 [2 ] = {
205+ GraphMeterMode_top_dotsUtf8 ,
206+ GraphMeterMode_bottom_dotsUtf8
207+ };
196208#endif
197209
198210#define PIXPERROW_ASCII 2
199- static const char * const GraphMeterMode_dotsAscii [] = {
211+ static const char * const GraphMeterMode_top_dotsAscii [] = {
200212 /*00*/ " " , /*01*/ "." , /*02*/ ":" ,
201213 /*10*/ "." , /*11*/ "." , /*12*/ ":" ,
202214 /*20*/ ":" , /*21*/ ":" , /*22*/ ":"
203215};
204216
205- static void GraphMeterMode_draw (Meter * this , int x , int y , int w ) {
206- assert (x >= 0 );
207- assert (w <= INT_MAX - x );
217+ static const char * const GraphMeterMode_bottom_dotsAscii [] = {
218+ /*00*/ " " , /*01*/ "'" , /*02*/ ":" ,
219+ /*10*/ "'" , /*11*/ "'" , /*12*/ ":" ,
220+ /*20*/ ":" , /*21*/ ":" , /*22*/ ":"
221+ };
208222
209- // Draw the caption
210- const int captionLen = 3 ;
211- const char * caption = Meter_getCaption (this );
212- if (w >= captionLen ) {
213- attrset (CRT_colors [METER_TEXT ]);
214- mvaddnstr (y , x , caption , captionLen );
215- }
216- w -= captionLen ;
223+ static const char * const * const GraphMeterMode_dotsAscii [2 ] = {
224+ GraphMeterMode_top_dotsAscii ,
225+ GraphMeterMode_bottom_dotsAscii
226+ };
217227
218- assert (this -> h >= 1 );
219- int h = this -> h ;
228+ static void GraphMeterMode_drawGraph (Meter * this , int x , int y , int w , int h , int channel ) {
229+ assert (x >= 0 );
230+ assert (y >= 0 );
231+ assert (w > 0 && w <= INT_MAX - x );
232+ assert (h > 0 && h <= INT_MAX - y );
220233
221- GraphData * data = & this -> drawData ;
234+ GraphData * data = & this -> drawData [ channel + 1 ] ;
222235
223236 // Expand the graph data buffer if necessary
224237 assert (data -> nValues / 2 <= INT_MAX );
@@ -247,28 +260,35 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
247260 data -> values [nValues - 1 ] = 0.0 ;
248261 if (this -> curItems > 0 ) {
249262 assert (this -> values );
250- data -> values [nValues - 1 ] = sumPositiveValues (this -> values , this -> curItems );
263+ if (channel < 0 ) {
264+ data -> values [nValues - 1 ] = sumPositiveValues (this -> values , this -> curItems );
265+ } else {
266+ assert (this -> curItems > channel );
267+ data -> values [nValues - 1 ] = this -> values [channel ];
268+ }
251269 }
252270 }
253271
254272 if (w < 1 ) {
255273 goto end ;
256274 }
257- x += captionLen ;
258275
259276 // Graph drawing style (character set, etc.)
260- const char * const * GraphMeterMode_dots ;
261- int GraphMeterMode_pixPerRow ;
277+ const char * const * GraphMeterMode_dots = NULL ;
278+ int GraphMeterMode_pixPerRow = 0 ;
279+ int GraphMeterMode_dotSet = channel >= 0 ? channel : 0 ;
262280#ifdef HAVE_LIBNCURSESW
263281 if (CRT_utf8 ) {
264- GraphMeterMode_dots = GraphMeterMode_dotsUtf8 ;
282+ GraphMeterMode_dots = GraphMeterMode_dotsUtf8 [ GraphMeterMode_dotSet ] ;
265283 GraphMeterMode_pixPerRow = PIXPERROW_UTF8 ;
266284 } else
267285#endif
268286 {
269- GraphMeterMode_dots = GraphMeterMode_dotsAscii ;
287+ GraphMeterMode_dots = GraphMeterMode_dotsAscii [ GraphMeterMode_dotSet ] ;
270288 GraphMeterMode_pixPerRow = PIXPERROW_ASCII ;
271289 }
290+ assert (GraphMeterMode_dots );
291+ assert (GraphMeterMode_pixPerRow > 0 );
272292
273293 // Starting positions of graph data and terminal column
274294 if ((size_t )w > nValues / 2 ) {
@@ -290,7 +310,8 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
290310 int line2 = CLAMP (v2 - (GraphMeterMode_pixPerRow * (h - 1 - line )), 0 , GraphMeterMode_pixPerRow );
291311
292312 attrset (CRT_colors [colorIdx ]);
293- mvaddstr (y + line , x + col , GraphMeterMode_dots [line1 * (GraphMeterMode_pixPerRow + 1 ) + line2 ]);
313+ int screen_row = GraphMeterMode_dotSet == 0 ? y + line : y + h - line - 1 ;
314+ mvaddstr (screen_row , x + col , GraphMeterMode_dots [line1 * (GraphMeterMode_pixPerRow + 1 ) + line2 ]);
294315 colorIdx = GRAPH_2 ;
295316 }
296317 }
@@ -299,6 +320,23 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
299320 attrset (CRT_colors [RESET_COLOR ]);
300321}
301322
323+ static void GraphMeterMode_draw (Meter * this , int x , int y , int w ) {
324+ assert (x >= 0 );
325+ assert (w <= INT_MAX - x );
326+
327+ // Draw the caption
328+ const int captionLen = 3 ;
329+ const char * caption = Meter_getCaption (this );
330+ if (w >= captionLen ) {
331+ attrset (CRT_colors [METER_TEXT ]);
332+ mvaddnstr (y , x , caption , captionLen );
333+ }
334+ w -= captionLen ;
335+
336+ // Draw the graph
337+ GraphMeterMode_drawGraph (this , x + captionLen , y , w , this -> h , -1 );
338+ }
339+
302340/* ---------- LEDMeterMode ---------- */
303341
304342static const char * const LEDMeterMode_digitsAscii [] = {
@@ -483,7 +521,9 @@ void Meter_delete(Object* cast) {
483521 if (Meter_doneFn (this )) {
484522 Meter_done (this );
485523 }
486- free (this -> drawData .values );
524+ for (size_t i = 0 ; i < ARRAYSIZE (this -> drawData ); i ++ ) {
525+ free (this -> drawData [i ].values );
526+ }
487527 free (this -> caption );
488528 free (this -> values );
489529 free (this );
@@ -513,9 +553,10 @@ void Meter_setMode(Meter* this, MeterModeId modeIndex) {
513553 this -> draw = Meter_drawFn (this );
514554 Meter_updateMode (this , modeIndex );
515555 } else {
516- free (this -> drawData .values );
517- this -> drawData .values = NULL ;
518- this -> drawData .nValues = 0 ;
556+ for (size_t i = 0 ; i < ARRAYSIZE (this -> drawData ); i ++ ) {
557+ free (this -> drawData [i ].values );
558+ this -> drawData [i ] = (GraphData ) { .values = NULL };
559+ }
519560
520561 const MeterMode * mode = & Meter_modes [modeIndex ];
521562 this -> draw = mode -> draw ;
0 commit comments