From af30481a47f13a27251b6ab0e4cff66f924f326a Mon Sep 17 00:00:00 2001
From: fluxgen <fluxgen>
Date: Thu, 10 Jun 2004 11:40:43 +0000
Subject: icon in menu item

---
 src/FbTk/MenuItem.cc | 80 +++++++++++++++++++++++++++++++++++++++++++++++++---
 src/FbTk/MenuItem.hh | 17 ++++++++---
 2 files changed, 89 insertions(+), 8 deletions(-)

diff --git a/src/FbTk/MenuItem.cc b/src/FbTk/MenuItem.cc
index 55aef9a..0d5989f 100644
--- a/src/FbTk/MenuItem.cc
+++ b/src/FbTk/MenuItem.cc
@@ -19,12 +19,14 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: MenuItem.cc,v 1.2 2004/06/07 20:34:23 fluxgen Exp $
+// $Id: MenuItem.cc,v 1.3 2004/06/10 11:40:43 fluxgen Exp $
 
 #include "MenuItem.hh"
 #include "Command.hh"
 #include "GContext.hh"
 #include "MenuTheme.hh"
+#include "PixmapWithMask.hh"
+#include "Image.hh"
 #include "App.hh"
 
 namespace FbTk {
@@ -39,12 +41,51 @@ void MenuItem::draw(FbDrawable &draw,
                     bool highlight,
                     int x, int y, 
                     unsigned int width, unsigned int height) const {
+    //
+    // Icon
+    //
+    if (m_icon.get() != 0 && m_icon->pixmap.get() != 0) {
+        // scale pixmap to right size
+        if (height - 2*theme.bevelWidth() != m_icon->pixmap->height() &&
+            !m_icon->filename.empty()) {
+            unsigned int scale_size = height - 2*theme.bevelWidth();
+            m_icon->pixmap->scale(scale_size, scale_size);
+        }
+
+        if (m_icon->pixmap->pixmap().drawable() != 0) {
+            GC gc = theme.frameTextGC().gc();
+            int icon_x = x + theme.bevelWidth();
+            int icon_y = y + theme.bevelWidth();
+            // enable clip mask
+            XSetClipMask(FbTk::App::instance()->display(),
+                         gc,
+                         m_icon->pixmap->mask().drawable());
+            XSetClipOrigin(FbTk::App::instance()->display(),
+                           gc, icon_x, icon_y);
+
+            draw.copyArea(m_icon->pixmap->pixmap().drawable(),
+                          gc,
+                          0, 0,
+                          icon_x, icon_y,
+                          m_icon->pixmap->width(), m_icon->pixmap->height());
+
+            // restore clip mask
+            XSetClipMask(FbTk::App::instance()->display(),
+                         gc,
+                         None);
+        }
+
+    }
+
     if (label().empty())
         return;
 
     const GContext &tgc =
         (highlight ? theme.hiliteTextGC() :
          (isEnabled() ? theme.frameTextGC() : theme.disableTextGC() ) );
+    //
+    // Text
+    //
     int text_y = y, text_x = x;
 
     int text_w = theme.frameFont().textWidth(label().c_str(), label().size());
@@ -63,7 +104,7 @@ void MenuItem::draw(FbDrawable &draw,
         text_x = x + ((width + 1 - text_w) / 2);
         break;
     }
-
+    
     theme.frameFont().drawText(draw.drawable(), // drawable
                                theme.screenNum(),
                                tgc.gc(),
@@ -80,6 +121,9 @@ void MenuItem::draw(FbDrawable &draw,
     if (theme.bulletPos() == FbTk::RIGHT)
         sel_x += width - height - 2*theme.bevelWidth();
 
+    //
+    // ToggleItem
+    //
     if (isToggleItem() && theme.unselectedPixmap().pixmap().drawable() != 0) {
         XSetClipMask(FbTk::App::instance()->display(),
                      gc,
@@ -99,7 +143,9 @@ void MenuItem::draw(FbDrawable &draw,
                      None);
     }
 
-
+    // 
+    // Submenu
+    //
     if (submenu()) {
         if (theme.bulletPixmap().pixmap().drawable() != 0) {
             // enable clip mask
@@ -171,6 +217,21 @@ void MenuItem::draw(FbDrawable &draw,
         }
     }
 
+
+}
+
+void MenuItem::setIcon(const std::string &filename, int screen_num) {
+    if (filename.empty()) {
+        if (m_icon.get() != 0)
+            m_icon.reset(0);
+        return;
+    }
+
+    if (m_icon.get() == 0)
+        m_icon.reset(new Icon);
+
+    m_icon->filename = filename;
+    m_icon->pixmap.reset(Image::load(filename.c_str(), screen_num));
 }
 
 unsigned int MenuItem::height(const MenuTheme &theme) const {
@@ -179,10 +240,21 @@ unsigned int MenuItem::height(const MenuTheme &theme) const {
 
 unsigned int MenuItem::width(const MenuTheme &theme) const {
     // textwidth + bevel width on each side of the text
-    return theme.frameFont().textWidth(label().c_str(), label().size()) + 2*(theme.bevelWidth() + height(theme));
+    int normal = theme.frameFont().textWidth(label().c_str(), label().size()) + 2*(theme.bevelWidth() + height(theme));
+    if (m_icon.get() == 0) 
+        return normal;
+    else
+        return normal + 2 * (theme.bevelWidth()  + height(theme));
     
 }
 
+void MenuItem::updateTheme(const MenuTheme &theme) {
+    if (m_icon.get() == 0)
+        return;
 
+    m_icon->pixmap.reset(Image::load(m_icon->filename.c_str(), theme.screenNum()));
+
+
+}
 
 }; // end namespace FbTk
diff --git a/src/FbTk/MenuItem.hh b/src/FbTk/MenuItem.hh
index 1d9ed20..efeab4d 100644
--- a/src/FbTk/MenuItem.hh
+++ b/src/FbTk/MenuItem.hh
@@ -1,5 +1,5 @@
 // MenuItem.hh for FbTk - Fluxbox Toolkit
-// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
+// Copyright (c) 2003-2004 Henrik Kinnunen (fluxgen at users.sourceforge.net)
 //
 // Permission is hereby granted, free of charge, to any person obtaining a
 // copy of this software and associated documentation files (the "Software"),
@@ -19,20 +19,22 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: MenuItem.hh,v 1.5 2004/06/07 20:33:20 fluxgen Exp $
+// $Id: MenuItem.hh,v 1.6 2004/06/10 11:40:43 fluxgen Exp $
 
 #ifndef FBTK_MENUITEM_HH
 #define FBTK_MENUITEM_HH
 
 #include "RefCount.hh"
 #include "Command.hh"
-#include <string>
 
+#include <string>
+#include <memory>
 namespace FbTk {
 
 class Menu;
 class MenuTheme;
 class FbDrawable;
+class PixmapWithMask;
 
 ///   An interface for a menu item in Menu
 class MenuItem {
@@ -77,6 +79,7 @@ public:
     virtual inline void setEnabled(bool enabled) { m_enabled = enabled; }
     virtual inline void setLabel(const char *label) { m_label = (label ? label : ""); }
     virtual inline void setToggleItem(bool val) { m_toggle_item = val; }
+    void setIcon(const std::string &filename, int screen_num);
     Menu *submenu() { return m_submenu; }
     /** 
         @name accessors
@@ -94,7 +97,7 @@ public:
                       bool highlight,
                       int x, int y,
                       unsigned int width, unsigned int height) const;
-    virtual void updateTheme(const MenuTheme &theme) { }
+    virtual void updateTheme(const MenuTheme &theme);
     /**
        Called when the item was clicked with a specific button
        @param button the button number
@@ -111,6 +114,12 @@ private:
     RefCount<Command> m_command; ///< command to be executed
     bool m_enabled, m_selected;
     bool m_toggle_item;
+
+    struct Icon {
+        std::auto_ptr<PixmapWithMask> pixmap;
+        std::string filename;
+    };
+    std::auto_ptr<Icon> m_icon;
 };
 
 } // end namespace FbTk
-- 
cgit v0.11.2