Dear all,

The attached patch will be applied tomorrow morning if there is no
objection. The main design ideas are that
1. enable mouse tracking
2. get inset under mouse (done by editXY) and pass notifyMouseEnter
and notifyMouseLeave to it.
3. if an inset (currently insetcommand and insetcollapsable) decides
to respond to notifyMouseEnter, it returns true to the notify
functions to be redrawn.
4. button painter now paints hover-style buttons. I have changed some
default colors for this.

Please test and comment.

Bo
Index: src/insets/insetbase.h
===================================================================
--- src/insets/insetbase.h	(revision 16145)
+++ src/insets/insetbase.h	(working copy)
@@ -180,6 +180,12 @@
 	/// is called when the cursor leaves this inset
 	//  returns true if cursor is now invalid.
 	virtual bool notifyCursorLeaves(LCursor &) { return false; }
+	/// is called when the mouse enter this inset
+	/// return true if this inset need to be repaint
+	virtual bool notifyMouseEnter() { return false; }
+	/// is called when the mouse leave this inset
+	/// return true if this inset need to be repaint
+	virtual bool notifyMouseLeave() { return false; }
 
 	/// request "external features"
 	virtual void validate(LaTeXFeatures &) const {}
Index: src/insets/insetcollapsable.C
===================================================================
--- src/insets/insetcollapsable.C	(revision 16145)
+++ src/insets/insetcollapsable.C	(working copy)
@@ -53,7 +53,7 @@
 InsetCollapsable::InsetCollapsable
 		(BufferParams const & bp, CollapseStatus status)
 	: InsetText(bp), label(from_ascii("Label")), status_(status),
-	  openinlined_(false), autoOpen_(false)
+	  openinlined_(false), autoOpen_(false), mouse_hover_(false)
 {
 	setAutoBreakRows(true);
 	setDrawFrame(true);
@@ -168,6 +168,20 @@
 }
 
 
+bool InsetCollapsable::notifyMouseEnter()
+{
+	mouse_hover_ = true;
+	return true;
+}
+
+
+bool InsetCollapsable::notifyMouseLeave()
+{
+	mouse_hover_ = false;
+	return true;
+}
+
+
 void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
 {
 	const int xx = x + TEXT_TO_INSET_OFFSET;
@@ -181,7 +195,7 @@
 		button_dim.y1 = top;
 		button_dim.y2 = top + dimc.height();
 
-		pi.pain.buttonText(xx, top + dimc.asc, label, labelfont_);
+		pi.pain.buttonText(xx, top + dimc.asc, label, labelfont_, mouse_hover_);
 
 		if (status() == Open) {
 			int textx, texty;
Index: src/insets/insetcommand.h
===================================================================
--- src/insets/insetcommand.h	(revision 16145)
+++ src/insets/insetcommand.h	(working copy)
@@ -91,6 +91,10 @@
 	std::string const getSecOptions() const { return p_.getSecOptions(); }
 	///
 	RenderButton & button() const { return button_; }
+	///
+	bool notifyMouseEnter();
+	///
+	bool notifyMouseLeave();
 
 protected:
 	///
@@ -128,6 +132,8 @@
 	///
 	InsetCommandParams p_;
 	std::string mailer_name_;
+	/// changes color when mouse enters/leaves this inset
+	bool mouse_hover_;
 	mutable bool updateButtonLabel_;
 	mutable RenderButton button_;
 };
Index: src/insets/insetcollapsable.h
===================================================================
--- src/insets/insetcollapsable.h	(revision 16145)
+++ src/insets/insetcollapsable.h	(working copy)
@@ -80,6 +80,10 @@
 	bool getStatus(LCursor &, FuncRequest const &, FuncStatus &) const;
 	///
 	void setStatus(LCursor & cur, CollapseStatus st);
+	///
+	bool notifyMouseEnter();
+	///
+	bool notifyMouseLeave();
 
 protected:
 	///
@@ -117,6 +121,8 @@
 	mutable bool autoOpen_;
 	///
 	mutable Dimension textdim_;
+	/// changes color when mouse enters/leaves this inset
+	bool mouse_hover_;
 };
 
 // A helper function that pushes the cursor out of the inset.
Index: src/insets/render_base.h
===================================================================
--- src/insets/render_base.h	(revision 16145)
+++ src/insets/render_base.h	(working copy)
@@ -39,6 +39,10 @@
 	virtual bool metrics(MetricsInfo & mi, Dimension & dim) const = 0;
 	/// draw inset and update (xo, yo)-cache
 	virtual void draw(PainterInfo & pi, int x, int y) const = 0;
+	/// render state, exact meaning of state is render-specific
+	void setRenderState(int state) { state_ = state; }
+	/// get render state
+	int renderState() const { return state_; } 
 
 	/// equivalent to dynamic_cast
 	virtual RenderButton * asButton() { return 0; }
@@ -51,6 +55,8 @@
 	RenderBase(RenderBase const &) {}
 	RenderBase & operator=(RenderBase const &) { return *this; }
 
+	/// render status. currently, render_button use this to store mouse_hover_ state
+	int state_;
 	/// Cached
 	mutable Dimension dim_;
 };
Index: src/insets/render_button.C
===================================================================
--- src/insets/render_button.C	(revision 16145)
+++ src/insets/render_button.C	(working copy)
@@ -71,7 +71,7 @@
 	font.decSize();
 
 	if (editable_) {
-		pi.pain.buttonText(x + 2, y, text_, font);
+		pi.pain.buttonText(x + 2, y, text_, font, renderState());
 	} else {
 		pi.pain.rectText(x + 2, y, text_, font,
 				 LColor::commandbg, LColor::commandframe);
Index: src/insets/insetcommand.C
===================================================================
--- src/insets/insetcommand.C	(revision 16145)
+++ src/insets/insetcommand.C	(working copy)
@@ -35,6 +35,7 @@
 			   string const & mailer_name)
 	: p_(p),
 	  mailer_name_(mailer_name),
+	  mouse_hover_(false),
 	  updateButtonLabel_(true)
 {}
 
@@ -60,9 +61,24 @@
 }
 
 
+bool InsetCommand::notifyMouseEnter()
+{
+	mouse_hover_ = true;
+	return true;
+}
+
+
+bool InsetCommand::notifyMouseLeave()
+{
+	mouse_hover_ = false;
+	return true;
+}
+
+
 void InsetCommand::draw(PainterInfo & pi, int x, int y) const
 {
 	setPosCache(pi, x, y);
+	button_.setRenderState(mouse_hover_);
 	button_.draw(pi, x, y);
 }
 
Index: src/frontends/Painter.C
===================================================================
--- src/frontends/Painter.C	(revision 16145)
+++ src/frontends/Painter.C	(working copy)
@@ -26,9 +26,12 @@
 namespace lyx {
 namespace frontend {
 
-void Painter::button(int x, int y, int w, int h)
+void Painter::button(int x, int y, int w, int h, bool mouseHover)
 {
-	fillRectangle(x, y, w, h, LColor::buttonbg);
+	if (mouseHover)
+		fillRectangle(x, y, w, h, LColor::buttonhoverbg);
+	else
+		fillRectangle(x, y, w, h, LColor::buttonbg);
 	buttonFrame(x, y, w, h);
 }
 
@@ -36,16 +39,13 @@
 void Painter::buttonFrame(int x, int y, int w, int h)
 {
 	//  Width of a side of the button
-	int const d = 2;
+	int const d = 1;
 
-	fillRectangle(x, y, w, d, LColor::top);
-	fillRectangle(x, y + h - d, w, d, LColor::bottom);
-
-	for (int i = 0 ; i < d ; ++i) {
-		line(x + i, y + i,
-		     x + i, y + h - 1 - i, LColor::left);
-		line(x + w - 1 - i, y + i + 1,
-		     x + w - 1 - i, y + h - 1 - i, LColor::right);
+	for (int i = 0; i < d; ++i) {
+		line(x + i, y + i, x + i, y + h - 1 - i, LColor::buttonframe);
+		line(x - i - 1 + w, y + i, x - i - 1 + w, y + h - 1 - i, LColor::buttonframe);
+		line(x + i, y - i - 1, x - i - 1 + w, y - i - 1, LColor::buttonframe);
+		line(x + i, y + h - i - 1, x - i - 1 + w, y + h - i - 1, LColor::buttonframe);
 	}
 }
 
@@ -74,7 +74,8 @@
 }
 
 
-void Painter::buttonText(int x, int y, docstring const & str, LyXFont const & font)
+void Painter::buttonText(int x, int y, docstring const & str, 
+	LyXFont const & font, bool mouseHover)
 {
 	int width;
 	int ascent;
@@ -83,8 +84,11 @@
 	FontMetrics const & fm = theFontMetrics(font);
 	fm.buttonText(str, width, ascent, descent);
 
-	button(x, y - ascent, width, descent + ascent);
-	text(x + 4, y, str, font);
+	button(x, y - ascent, width, descent + ascent, mouseHover);
+	if (mouseHover)
+		text(x + 4, y, str, font);
+	else
+		text(x + 3, y - 1, str, font);
 }
 
 
Index: src/frontends/qt4/GuiWorkArea.C
===================================================================
--- src/frontends/qt4/GuiWorkArea.C	(revision 16145)
+++ src/frontends/qt4/GuiWorkArea.C	(working copy)
@@ -166,6 +166,7 @@
 	setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
 	setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
 	setAcceptDrops(true);
+	setMouseTracking(true);
 	setMinimumSize(100, 70);
 
 	viewport()->setAutoFillBackground(false);
Index: src/frontends/Painter.h
===================================================================
--- src/frontends/Painter.h	(revision 16145)
+++ src/frontends/Painter.h	(working copy)
@@ -118,7 +118,7 @@
 
 	/// draw a filled rectangle with the shape of a 3D button
 	virtual void button(int x, int y,
-		int w, int h);
+		int w, int h, bool mouseHover);
 
 	/// draw an image from the image cache
 	virtual void image(int x, int y,
@@ -162,8 +162,8 @@
 		LColor_color frame);
 
 	/// draw a string and enclose it inside a button frame
-	void buttonText(int x,
-		int baseline, docstring const & s, LyXFont const & font);
+	void buttonText(int x, int baseline, docstring const & s,
+		LyXFont const & font, bool mouseHover);
 
 protected:
 	/// check the font, and if set, draw an underline
Index: src/BufferView.C
===================================================================
--- src/BufferView.C	(revision 16145)
+++ src/BufferView.C	(working copy)
@@ -1055,6 +1055,21 @@
 	//lyxerr << BOOST_CURRENT_FUNCTION
 	//       << " * created temp cursor:" << cur << endl;
 
+	static InsetBase * last_inset = NULL;
+	if (cmd.action == LFUN_MOUSE_MOTION && cmd.button() == mouse_button::none) {
+		bool need_update = false;
+		if (inset != last_inset) {
+			if (last_inset)
+				need_update |= last_inset->notifyMouseLeave();
+			if (inset)
+				need_update |= inset->notifyMouseEnter();
+			last_inset = inset;
+		}
+		// This event (moving without mouse click) is not passed further.
+		// This should be changed if it is further utilized.
+		return make_pair(need_update, need_update);
+	}
+
 	// Put anchor at the same position.
 	cur.resetAnchor();
 
Index: src/LColor.C
===================================================================
--- src/LColor.C	(revision 16145)
+++ src/LColor.C	(working copy)
@@ -145,11 +145,9 @@
 	     "LightSteelBlue", "tabularonoffline" },
 	{ bottomarea, N_("bottom area"), "bottomarea", "grey40", "bottomarea" },
 	{ pagebreak, N_("page break"), "pagebreak", "RoyalBlue", "pagebreak" },
-	{ top, N_("top of button"), "top", "grey90", "top" },
-	{ bottom, N_("bottom of button"), "bottom", "grey60", "bottom" },
-	{ left, N_("left of button"), "left", "grey90", "left" },
-	{ right, N_("right of button"), "right", "grey60", "right" },
-	{ buttonbg, N_("button background"), "buttonbg", "grey80", "buttonbg" },
+	{ buttonframe, N_("frame of button"), "buttonframe", "#A9ABB5", "buttonframe" },
+	{ buttonbg, N_("button background"), "buttonbg", "linen", "buttonbg" },
+	{ buttonhoverbg, N_("button background under focus"), "buttonhoverbg", "#C7C7CA", "buttonhoverbg" },
 	{ inherit, N_("inherit"), "inherit", "black", "inherit" },
 	{ ignore, N_("ignore"), "ignore", "black", "ignore" },
 	{ ignore, 0, 0, 0, 0 }
Index: src/LColor.h
===================================================================
--- src/LColor.h	(revision 16145)
+++ src/LColor.h	(working copy)
@@ -166,16 +166,12 @@
 		pagebreak,
 
 		// FIXME: why are the next four separate ??
-		/// Color used for top of boxes
-		top,
-		/// Color used for bottom of boxes
-		bottom,
-		/// Color used for left side of boxes
-		left,
-		/// Color used for right side of boxes
-		right,
+		/// Color used for button frame
+		buttonframe,
 		/// Color used for bottom background
 		buttonbg,
+		/// Color used for buttom under focus
+		buttonhoverbg,
 
 		// Logical attributes
 

Reply via email to