Qt: Clean up the byte view hover highlight.
authorGerald Combs <gerald@wireshark.org>
Fri, 25 Nov 2016 17:42:26 +0000 (11:42 -0600)
committerGerald Combs <gerald@wireshark.org>
Sat, 26 Nov 2016 14:41:40 +0000 (14:41 +0000)
Rename the text highlight enum "HighlightMode" to make its use and
intent more clear. Add a mode for the offset highlight instead of using
a separate variable. Use our palette to draw the hover highlight colors.
Add a note about colors to the Developer's Guide.

Change-Id: I488b2512a5058e17eb5b49c8ac55616100f32fbc
Reviewed-on: https://code.wireshark.org/review/18953
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Gerald Combs <gerald@wireshark.org>
docbook/wsdg_src/WSDG_chapter_userinterface.asciidoc
ui/qt/byte_view_text.cpp
ui/qt/byte_view_text.h
ui/qt/color_utils.cpp
ui/qt/color_utils.h

index 3b213ea4b4757113c340715ae4f03f1f57c3245a..ac1d225fee1a67970b4df01bcd526b1e39c59447 100644 (file)
@@ -230,6 +230,18 @@ code through the following steps:
 - push and commit on Gerrit
 - push ts on Transifex
 
+===== Colors
+
+Qt provides a number of colors via the http://doc.qt.io/qt-5/qpalette.html[QPalette]
+class. Use this class when you need a standard color provided by the
+underlying operating system.
+
+Wireshark uses an extended version of the
+http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines[Tango Color Palette]
+for many interface elements that require custom colors. This includes the
+I/O graphs, sequence diagrams, and RTP streams. Please use this palette
+(defined in `tango_colors.h` and the *ColorUtils* class) if *QPalette*
+doesn't meet your needs.
 
 ==== Other Issues and Information
 
index 3d8f47db757bc8ba4286950feb18bc860106cbf2..e812a1c046a0d3edefecba7e61b9016621acc8c4 100644 (file)
@@ -352,34 +352,34 @@ void ByteViewText::drawOffsetLine(QPainter &painter, const guint offset, const i
         '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
 
     QString text;
-    highlight_state state = StateNormal, offset_state = StateOffsetNormal;
+    HighlightMode hl_mode = ModeNormal, offset_mode = ModeOffsetNormal;
     qreal hex_x = offsetPixels() + margin_;
     qreal ascii_x = offsetPixels() + hexPixels() + margin_;
 
     // Hex
     if (show_hex_) {
         for (guint tvb_pos = offset; tvb_pos < max_pos; tvb_pos++) {
-            highlight_state hex_state = StateNormal;
+            HighlightMode hex_state = ModeNormal;
             bool add_space = tvb_pos != offset;
-            bool highlight_text = tvb_pos == hovered_byte_offset_;
+            bool draw_hover = tvb_pos == hovered_byte_offset_;
 
             if ((tvb_pos >= f_bound_.first && tvb_pos < f_bound_.second) || (tvb_pos >= fa_bound_.first && tvb_pos < fa_bound_.second)) {
-                hex_state = StateField;
-                offset_state = StateOffsetField;
+                hex_state = ModeField;
+                offset_mode = ModeOffsetField;
             } else if (tvb_pos >= p_bound_.first && tvb_pos < p_bound_.second) {
-                hex_state = StateProtocol;
+                hex_state = ModeProtocol;
             }
 
-            if (hex_state != state || highlight_text) {
-                if ((state == StateNormal || (state == StateProtocol && hex_state == StateField) || highlight_text) && add_space) {
+            if (hex_state != hl_mode || draw_hover) {
+                if ((hl_mode == ModeNormal || (hl_mode == ModeProtocol && hex_state == ModeField) || draw_hover) && add_space) {
                     add_space = false;
                     text += ' ';
                     /* insert a space every separator_interval_ bytes */
                     if ((tvb_pos % separator_interval_) == 0)
                         text += ' ';
                 }
-                hex_x += flushOffsetFragment(painter, hex_x, row_y, state, false, text);
-                state = hex_state;
+                hex_x += flushOffsetFragment(painter, hex_x, row_y, hl_mode, text);
+                hl_mode = hex_state;
             }
 
             if (add_space) {
@@ -400,39 +400,39 @@ void ByteViewText::drawOffsetLine(QPainter &painter, const guint offset, const i
                     text += (pd[tvb_pos] & (1 << j)) ? '1' : '0';
                 break;
             }
-            if (highlight_text) {
-                hex_x += flushOffsetFragment(painter, hex_x, row_y, state, true, text);
+            if (draw_hover) {
+                hex_x += flushOffsetFragment(painter, hex_x, row_y, ModeHover, text);
             }
         }
     }
     if (text.length() > 0) {
-        flushOffsetFragment(painter, hex_x, row_y, state, false, text);
+        flushOffsetFragment(painter, hex_x, row_y, hl_mode, text);
     }
-    state = StateNormal;
+    hl_mode = ModeNormal;
 
     // ASCII
     if (show_ascii_) {
         for (guint tvb_pos = offset; tvb_pos < max_pos; tvb_pos++) {
-            highlight_state ascii_state = StateNormal;
+            HighlightMode ascii_state = ModeNormal;
             bool add_space = tvb_pos != offset;
             bool highlight_text = tvb_pos == hovered_byte_offset_;
 
             if ((tvb_pos >= f_bound_.first && tvb_pos < f_bound_.second) || (tvb_pos >= fa_bound_.first && tvb_pos < fa_bound_.second)) {
-                ascii_state = StateField;
-                offset_state = StateOffsetField;
+                ascii_state = ModeField;
+                offset_mode = ModeOffsetField;
             } else if (tvb_pos >= p_bound_.first && tvb_pos < p_bound_.second) {
-                ascii_state = StateProtocol;
+                ascii_state = ModeProtocol;
             }
 
-            if (ascii_state != state || highlight_text) {
-                if ((state == StateNormal || (state == StateProtocol && ascii_state == StateField) || highlight_text) && add_space) {
+            if (ascii_state != hl_mode || highlight_text) {
+                if ((hl_mode == ModeNormal || (hl_mode == ModeProtocol && ascii_state == ModeField) || highlight_text) && add_space) {
                     add_space = false;
                     /* insert a space every separator_interval_ bytes */
                     if ((tvb_pos % separator_interval_) == 0)
                         text += ' ';
                 }
-                ascii_x += flushOffsetFragment(painter, ascii_x, row_y, state, false, text);
-                state = ascii_state;
+                ascii_x += flushOffsetFragment(painter, ascii_x, row_y, hl_mode, text);
+                hl_mode = ascii_state;
             }
 
             if (add_space) {
@@ -447,25 +447,25 @@ void ByteViewText::drawOffsetLine(QPainter &painter, const guint offset, const i
 
             text += g_ascii_isprint(c) ? c : '.';
             if (highlight_text) {
-                ascii_x += flushOffsetFragment(painter, ascii_x, row_y, state, true, text);
+                ascii_x += flushOffsetFragment(painter, ascii_x, row_y, ModeHover, text);
             }
         }
     }
     if (text.length() > 0) {
-        flushOffsetFragment(painter, ascii_x, row_y, state, false, text);
+        flushOffsetFragment(painter, ascii_x, row_y, hl_mode, text);
     }
 
     // Offset. Must be drawn last in order for offset_state to be set.
     if (show_offset_) {
         text = QString("%1").arg(offset, offsetChars(), 16, QChar('0'));
-        flushOffsetFragment(painter, margin_, row_y, offset_state, false, text);
+        flushOffsetFragment(painter, margin_, row_y, offset_mode, text);
     }
 }
 
 // Draws a fragment of byte view text at the specifiec location using colors
 // for the specified state. Clears the text and returns the pixel width of the
 // drawn text.
-qreal ByteViewText::flushOffsetFragment(QPainter &painter, qreal x, int y, highlight_state state, gboolean extra_highlight, QString &text)
+qreal ByteViewText::flushOffsetFragment(QPainter &painter, qreal x, int y, HighlightMode mode, QString &text)
 {
     if (text.length() < 1) {
         return 0;
@@ -474,34 +474,40 @@ qreal ByteViewText::flushOffsetFragment(QPainter &painter, qreal x, int y, highl
     qreal width = fm.width(text);
     QRectF area(x, y, width, line_spacing_);
     // Background
-    if (state == StateField) {
+    switch (mode) {
+    case ModeField:
         painter.fillRect(area, palette().highlight());
-    } else if (state == StateProtocol) {
+        break;
+    case ModeProtocol:
         painter.fillRect(area, palette().window());
+        break;
+    case ModeHover:
+        painter.fillRect(area, ColorUtils::byteViewHoverColor(true));
+        break;
+    default:
+        break;
     }
 
     // Text
     QBrush text_brush;
-    switch (state) {
-    case StateNormal:
-    case StateProtocol:
+    switch (mode) {
+    case ModeNormal:
+    case ModeProtocol:
     default:
         text_brush = palette().windowText();
         break;
-    case StateField:
+    case ModeField:
         text_brush = palette().highlightedText();
         break;
-    case StateOffsetNormal:
+    case ModeOffsetNormal:
         text_brush = offset_normal_fg_;
         break;
-    case StateOffsetField:
+    case ModeOffsetField:
         text_brush = offset_field_fg_;
         break;
-    }
-
-    if (extra_highlight) {
-        painter.fillRect(area, QColor("yellow"));
-        text_brush = QColor("blue");
+    case ModeHover:
+        text_brush = ColorUtils::byteViewHoverColor(false);
+        break;
     }
 
     painter.setPen(QPen(text_brush.color()));
index 8271f3116116510d7672f3e06b70658f74b9a012..0e91e084ba0efafa15691e500db0f22a7e0c5781 100644 (file)
@@ -69,16 +69,18 @@ protected:
     virtual void contextMenuEvent(QContextMenuEvent *event);
 
 private:
+    // Text highlight modes.
     typedef enum {
-        StateNormal,
-        StateField,
-        StateProtocol,
-        StateOffsetNormal,
-        StateOffsetField
-    } highlight_state;
+        ModeNormal,
+        ModeField,
+        ModeProtocol,
+        ModeOffsetNormal,
+        ModeOffsetField,
+        ModeHover
+    } HighlightMode;
 
     void drawOffsetLine(QPainter &painter, const guint offset, const int row_y);
-    qreal flushOffsetFragment(QPainter &painter, qreal x, int y, highlight_state state, gboolean extra_highlight, QString &text);
+    qreal flushOffsetFragment(QPainter &painter, qreal x, int y, HighlightMode mode, QString &text);
     void scrollToByte(int byte);
     int offsetChars();
     int offsetPixels();
index 4f273673930fa85c68bb82a12c641bf1d024fec1..e63512fb654a998d0bdc80957e3cd02b5c98f7ed 100644 (file)
 
 #include "tango_colors.h"
 
+// Colors we use in various parts of the UI.
+//
+// New colors should be chosen from tango_colors.h. The expert and hidden
+// colors come from the GTK+ UI and are grandfathered in.
+//
+// At some point we should probably make these configurable along with the
+// graph and sequence colors.
+
 const QColor ColorUtils::expert_color_comment    = QColor ( 0xb7, 0xf7, 0x74 );        /* Green */
 const QColor ColorUtils::expert_color_chat       = QColor ( 0x80, 0xb7, 0xf7 );        /* Light blue */
 const QColor ColorUtils::expert_color_note       = QColor ( 0xa0, 0xff, 0xff );        /* Bright turquoise */
@@ -31,6 +39,9 @@ const QColor ColorUtils::expert_color_error      = QColor ( 0xff, 0x5c, 0x5c );
 const QColor ColorUtils::expert_color_foreground = QColor ( 0x00, 0x00, 0x00 );        /* Black */
 const QColor ColorUtils::hidden_proto_item       = QColor ( 0x44, 0x44, 0x44 );        /* Gray */
 
+const QRgb ColorUtils::byte_view_hover_bg_ = tango_butter_2;
+const QRgb ColorUtils::byte_view_hover_fg_ = tango_sky_blue_5;
+
 ColorUtils::ColorUtils(QObject *parent) :
     QObject(parent)
 {
index 3dceadf474e16313c7eec56758ceb3b4dfcce900..69a904d2f102ede3d445d26649eb7d798db77347 100644 (file)
@@ -56,6 +56,7 @@ public:
     static const QList<QRgb> graphColors();
     static QRgb graphColor(int item);
     static QRgb sequenceColor(int item);
+    static QColor byteViewHoverColor(bool background) { return QColor(background ? byte_view_hover_bg_ : byte_view_hover_fg_); }
 
 signals:
 
@@ -64,6 +65,8 @@ public slots:
 private:
     static QList<QRgb> graph_colors_;
     static QList<QRgb> sequence_colors_;
+    static const QRgb byte_view_hover_bg_;
+    static const QRgb byte_view_hover_fg_;
 };
 
 void color_filter_qt_add_cb(color_filter_t *colorf, gpointer user_data);