diff options
author | Christian Göttsche <cgzones@googlemail.com> | 2021-01-18 15:23:23 +0100 |
---|---|---|
committer | cgzones <cgzones@googlemail.com> | 2021-01-23 15:20:47 +0100 |
commit | 2ec44098f9ca6604f2e897bbc4e2ee164049107f (patch) | |
tree | 135d98bfa7f04523f734712871fc33dfa33e3ff8 | |
parent | 6f6e0ec571a05f612788fffa9dbf095ddd8a939c (diff) |
Allow meters in text mode to span empty neighbors to the right
Closes: #484
-rw-r--r-- | Header.c | 48 | ||||
-rw-r--r-- | Meter.h | 1 | ||||
-rw-r--r-- | Object.c | 4 | ||||
-rw-r--r-- | Object.h | 4 |
4 files changed, 43 insertions, 14 deletions
@@ -150,35 +150,71 @@ void Header_reinit(Header* this) { } void Header_draw(const Header* this) { - int height = this->height; - int pad = this->pad; + const int height = this->height; + const int pad = this->pad; attrset(CRT_colors[RESET_COLOR]); for (int y = 0; y < height; y++) { mvhline(y, 0, ' ', COLS); } - int width = COLS / this->nrColumns - (pad * this->nrColumns - 1) - 1; + const int width = COLS / this->nrColumns - (pad * this->nrColumns - 1) - 1; int x = pad; Header_forEachColumn(this, col) { Vector* meters = this->columns[col]; for (int y = (pad / 2), i = 0; i < Vector_size(meters); i++) { Meter* meter = (Meter*) Vector_get(meters, i); - meter->draw(meter, x, y, width); + + int actualWidth; + if (meter->mode == TEXT_METERMODE) + actualWidth = meter->columnWidthCount * width + (meter->columnWidthCount - 1) * (2 * pad + 1); + else + actualWidth = width; + + meter->draw(meter, x, y, actualWidth); y += meter->h; } x += width + pad; } } +/* + * Calculate how many columns the current meter is allowed to span, + * by counting how many columns to the right are empty or contain a BlankMeter. + * Returns the number of columns to span, i.e. if the direct neighbor is occupied 1. + */ +static int calcColumnWidthCount(const Header* this, const Meter* curMeter, const int pad, const int curColumn, const int curHeight) { + for (int i = curColumn + 1; i < this->nrColumns; i++) { + const Vector* meters = this->columns[i]; + + int height = pad; + for (int j = 0; j < Vector_size(meters); j++) { + const Meter* meter = (const Meter*) Vector_get(meters, j); + + if (height >= curHeight + curMeter->h) + break; + + height += meter->h; + if (height <= curHeight) + continue; + + if (!Object_isA((const Object*) meter, (const ObjectClass*) &BlankMeter_class)) + return i - curColumn; + } + } + + return this->nrColumns - curColumn; +} + int Header_calculateHeight(Header* this) { - int pad = this->settings->headerMargin ? 2 : 0; + const int pad = this->settings->headerMargin ? 2 : 0; int maxHeight = pad; Header_forEachColumn(this, col) { const Vector* meters = this->columns[col]; int height = pad; for (int i = 0; i < Vector_size(meters); i++) { - const Meter* meter = (const Meter*) Vector_get(meters, i); + Meter* meter = (Meter*) Vector_get(meters, i); + meter->columnWidthCount = calcColumnWidthCount(this, meter, pad, col, height); height += meter->h; } maxHeight = MAXIMUM(maxHeight, height); @@ -98,6 +98,7 @@ struct Meter_ { int param; GraphData* drawData; int h; + int columnWidthCount; /*<< only used internally by the Header */ const ProcessList* pl; uint8_t curItems; const int* curAttributes; @@ -15,8 +15,6 @@ const ObjectClass Object_class = { .extends = NULL }; -#ifndef NDEBUG - bool Object_isA(const Object* o, const ObjectClass* klass) { if (!o) return false; @@ -29,5 +27,3 @@ bool Object_isA(const Object* o, const ObjectClass* klass) { return false; } - -#endif /* NDEBUG */ @@ -57,10 +57,6 @@ typedef union { extern const ObjectClass Object_class; -#ifndef NDEBUG - bool Object_isA(const Object* o, const ObjectClass* klass); -#endif /* NDEBUG */ - #endif |