diff --git a/Header.c b/Header.c index 292f9b1e..08e3548a 100644 --- a/Header.c +++ b/Header.c @@ -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); diff --git a/Meter.h b/Meter.h index 98fed575..2a3cb7af 100644 --- a/Meter.h +++ b/Meter.h @@ -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; diff --git a/Object.c b/Object.c index 0a29d015..f3613949 100644 --- a/Object.c +++ b/Object.c @@ -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 */ diff --git a/Object.h b/Object.h index 89933fa6..36e17b3b 100644 --- a/Object.h +++ b/Object.h @@ -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