]> granicus.if.org Git - nethack/commitdiff
more Qt status
authorPatR <rankin@nethack.org>
Wed, 18 Nov 2020 02:55:16 +0000 (18:55 -0800)
committerPatR <rankin@nethack.org>
Wed, 18 Nov 2020 02:55:16 +0000 (18:55 -0800)
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.

win/Qt/qt_icon.cpp
win/Qt/qt_icon.h
win/Qt/qt_stat.cpp

index 2e027b3f558450a85e31f18d31ccf6af54249627..388a1e500a38f770e56e9f90cb2151926b12d79f 100644 (file)
@@ -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 }";
 }
index eda5c56892aaf6a504c0ccc1a344c71636d25d9d..56a24f0e1155bc7ecc4abaa76d1439207819f867 100644 (file)
@@ -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_
index 6c6bf9ce92a51d996ec566f88bb01f2cd8a38872..a3bed62c693fa5739b6b76a670610f79afb89b4d 100644 (file)
@@ -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
     {