From: PatR Date: Wed, 18 Nov 2020 02:55:16 +0000 (-0800) Subject: more Qt status X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=87a6616998d4a4345bd9a7920b07eac1cc42f476;p=nethack more Qt status The slightly condensed (statuslines:2) status layout puts additional width pressure on "Level:NN/nnnnnnnn" and "Score:nnnnnnnn" so add some code to conditionally shorten the field prefix if the value of the field is wider than the widget it's displayed in. --- diff --git a/win/Qt/qt_icon.cpp b/win/Qt/qt_icon.cpp index 2e027b3f5..388a1e500 100644 --- a/win/Qt/qt_icon.cpp +++ b/win/Qt/qt_icon.cpp @@ -2,7 +2,24 @@ // Qt4 conversion copyright (c) Ray Chason, 2012-2014. // NetHack may be freely redistributed. See license for details. -// qt_icon.cpp -- a labelled icon +// qt_icon.cpp -- a labelled icon for display in the status window +// +// TODO? +// When the label specifies two values separated by a slash (curHP/maxHP, +// curEn/maxEn, XpLevel/ExpPoints when 'showexp' is On), highlighting +// for changes is all or nothing. curHP and curEn go up and down +// without any change to the corresponding maximum all the time. Much +// rarer, but when maxHP and maxEn go up with level gain, the hero +// could be injured by a passive counterattack or collateral damage +// from an area effect--or much simpler, the casting cost of a spell +// that killed a monster and produced the level gain--so the current +// value could stay the same or even go down at same time max goes up. +// Likewise, Exp goes up a lot but Xp relatively rarely. (On the very +// rare occasions where either goes down, they'll both do so.) +// Highlighting two slash-separated values independently would be +// worthwhile but with the 'single label using a style sheet for color' +// approach it isn't going to happen. +// extern "C" { #include "hack.h" @@ -18,24 +35,25 @@ extern "C" { namespace nethack_qt_ { -NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget* parent, const char* l) : +NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget *parent, const char *l) : QWidget(parent), + label(new QLabel(l,this)), + icon(NULL), low_is_good(false), prev_value(-123), - turn_count(-1), - label(new QLabel(l,this)), - icon(0) + turn_count(-1) { initHighlight(); } -NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget* parent, const char* l, const QPixmap& i) : +NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget *parent, const char *l, + const QPixmap &i) : QWidget(parent), + label(new QLabel(l,this)), + icon(new QLabel(this)), low_is_good(false), prev_value(-123), - turn_count(-1), - label(new QLabel(l,this)), - icon(new QLabel(this)) + turn_count(-1) { setIcon(i); initHighlight(); @@ -43,6 +61,7 @@ NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget* parent, const char* l, con void NetHackQtLabelledIcon::initHighlight() { + // note: named 'green' is much darker than Qt::green hl_good = "QLabel { background-color : green; color : white }"; hl_bad = "QLabel { background-color : red ; color : white }"; } diff --git a/win/Qt/qt_icon.h b/win/Qt/qt_icon.h index eda5c5689..56a24f0e1 100644 --- a/win/Qt/qt_icon.h +++ b/win/Qt/qt_icon.h @@ -11,15 +11,18 @@ namespace nethack_qt_ { class NetHackQtLabelledIcon : public QWidget { public: - NetHackQtLabelledIcon(QWidget* parent, const char* label); - NetHackQtLabelledIcon(QWidget* parent, const char* label, const QPixmap& icon); + NetHackQtLabelledIcon(QWidget *parent, const char *label); + NetHackQtLabelledIcon(QWidget *parent, const char *label, + const QPixmap &icon); enum { NoNum=-99999 }; - void setLabel(const QString&, bool lower=true); // a string - void setLabel(const QString&, long, const QString& tail=""); // a number - void setLabel(const QString&, long show_value, long comparative_value, const QString& tail=""); - void setIcon(const QPixmap&); - virtual void setFont(const QFont&); + void setLabel(const QString &, bool lower=true); // string + void setLabel(const QString &, long, const QString &tail=""); // number + void setLabel(const QString &, long show_value, + long comparative_value, const QString &tail=""); + void setIcon(const QPixmap &); + virtual void setFont(const QFont &); + //QString labelText() { return QString(this->label->text()); } void highlightWhenChanging(); void lowIsGood(); @@ -30,6 +33,9 @@ public: virtual QSize sizeHint() const; virtual QSize minimumSizeHint() const; + QLabel *label; + QLabel *icon; + protected: void resizeEvent(QResizeEvent*); @@ -44,9 +50,6 @@ private: int turn_count; /* last time the value changed */ QString hl_good; QString hl_bad; - - QLabel* label; - QLabel* icon; }; } // namespace nethack_qt_ diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 6c6bf9ce9..a3bed62c6 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -757,17 +757,27 @@ void NetHackQtStatusWindow::updateStats() buf.sprintf("/%d", u.uhpmax); hp.setLabel("HP:", std::max((long) u.uhp, 0L), buf); // if Exp points are to be displayed, append them to Xp level; - // up/down highlighting becomes tricky--don't try very hard - if (::flags.showexp) { - buf.sprintf("%ld/%ld", (long) u.ulevel, (long) u.uexp); - // at levels above 20, "Level:NN/nnnnnnnn" doesn't fit so - // shorten "Level" to "Lvl" at that stage; - // at level 30, a few pixels are truncated from the start - // and end of "Lvl:30/nnnnnnnnn" but the result is ledgible - level.setLabel(((u.ulevel <= 20) ? "Level:" : "Lvl:") + buf, - NetHackQtLabelledIcon::NoNum, (long) u.uexp); - } else { - level.setLabel("Level:", (long) u.ulevel); + // up/down highlighting becomes tricky--don't try very hard; + // depending upon font size and status layout, "Level:NN/nnnnnnnn" + // might be too wide to fit + static const char *const lvllbl[3] = { "Level:", "Lvl:", "L:" }; + QFontMetrics fm(level.label->font()); + int startingpass = ::flags.showexp ? 0 : 3; + for (int i = startingpass; i < 6; ++i) { + // passes 0,1,2 are with Exp, 3,4,5 without (3 should always fit) + if (i < 3) { + buf.sprintf("%s%ld/%ld", lvllbl[i], + (long) u.ulevel, (long) u.uexp); + level.setLabel(buf, NetHackQtLabelledIcon::NoNum, + (long) u.uexp); + } else { + buf.sprintf("%s%ld", lvllbl[i - 3], (long) u.ulevel); + level.setLabel(buf, NetHackQtLabelledIcon::NoNum, + (long) u.ulevel); + } + // 2: allow a couple of pixels at either end to be clipped off + if (fm.size(0, buf).width() <= (2 + level.width() + 2)) + break; } } buf.sprintf("/%d", u.uenmax); @@ -803,13 +813,37 @@ void NetHackQtStatusWindow::updateStats() } else blank2.hide(); - if (::flags.time) + if (::flags.time) { + // hypothetically Time could grow to enough digits to have trouble + // fitting, but it's not worth worrying about time.setLabel("Time:", (long) g.moves); - else + } else { time.setLabel(""); + } #ifdef SCORE_ON_BOTL if (::flags.showscore) { - score.setLabel("Score:", (long) botl_score()); + long pts = botl_score(); + if (spreadout) { + // plenty of room; Time and Score both have the width of 3 fields + score.setLabel("Score:", pts); + } else { + // depending upon font size and status layout, "Score:nnnnnnnn" + // might be too wide to fit (simpler version of Level:NN/nnnnnnnn) + static const char *const scrlbl[3] = { "Score:", "Scr:", "S:" }; + QFontMetrics fm(score.label->font()); + for (int i = 0; i < 3; ++i) { + buf.sprintf("%s%ld", scrlbl[i], pts); + score.setLabel(buf, NetHackQtLabelledIcon::NoNum, pts); + // 2: allow a couple of pixels at either end to be clipped off + if (fm.size(0, buf).width() <= (2 + score.width() + 2)) + break; + } + // with Xp/Exp, we fallback to Xp if the shortest label prefix + // is still too long; here we just show a clipped value and + // let user either live with it or turn 'showscore' off (or + // set statuslines:3 to take advantage of the extra room that + // the spread out status layout provides) + } } else #endif {