Button face-lift: use mouse hover-buttons.

* src/insets/insetbase.h: add setMouseHover function
	* src/insets/insetcommand.h/C: handle setMouseHover
	* src/insets/insetcollapsable.h/C: handle setMouseHover
	* src/LColor.h/C: redefine some colors
	* src/insets/render_base.h: add state_
	* src/insets/render_button.C: draw differently according to state_
	* src/frontends/Painter.h/C: hover-stype button
	* src/frontends/qt4/GuiWorkArea.C: enable mouse tracking
	* src/BufferView.C: track mouse_motion without button events


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16162 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Bo Peng 2006-12-04 04:31:18 +00:00
parent ed71ed4fab
commit 7c184e5426
13 changed files with 84 additions and 38 deletions

View File

@ -1055,6 +1055,25 @@ std::pair<bool, bool> BufferView::workAreaDispatch(FuncRequest const & cmd0)
//lyxerr << BOOST_CURRENT_FUNCTION
// << " * created temp cursor:" << cur << endl;
// NOTE: eidtXY returns the top level inset of nested insets. If you happen
// to move from a text (inset=0) to a text inside an inset (e.g. an opened
// footnote inset, again inset=0), that inset will not be redrawn.
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->setMouseHover(false);
if (inset)
need_update |= inset->setMouseHover(true);
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();

View File

@ -107,7 +107,7 @@ LColor::LColor()
{ selection, N_("selection"), "selection", "LightBlue", "selection" },
{ latex, N_("LaTeX text"), "latex", "DarkRed", "latex" },
{ preview, N_("previewed snippet"), "preview", "black", "preview" },
{ note, N_("note"), "note", "yellow", "note" },
{ note, N_("note"), "note", "blue", "note" },
{ notebg, N_("note background"), "notebg", "yellow", "notebg" },
{ comment, N_("comment"), "comment", "magenta", "comment" },
{ commentbg, N_("comment background"), "commentbg", "linen", "commentbg" },
@ -145,11 +145,9 @@ LColor::LColor()
"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 }

View File

@ -166,16 +166,12 @@ public:
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

View File

@ -26,27 +26,22 @@ using std::string;
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);
}
void Painter::buttonFrame(int x, int y, int w, int h)
{
// Width of a side of the button
int const d = 2;
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);
}
line(x, y, x, y + h - 1, LColor::buttonframe);
line(x - 1 + w, y, x - 1 + w, y + h - 1, LColor::buttonframe);
line(x, y - 1, x - 1 + w, y - 1, LColor::buttonframe);
line(x, y + h - 1, x - 1 + w, y + h - 1, LColor::buttonframe);
}
@ -74,7 +69,8 @@ void Painter::rectText(int x, int y,
}
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 +79,11 @@ void Painter::buttonText(int x, int y, docstring const & str, LyXFont const & fo
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);
}

View File

@ -118,7 +118,7 @@ public:
/// 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 @@ public:
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

View File

@ -166,6 +166,7 @@ GuiWorkArea::GuiWorkArea(int w, int h, int id, LyXView & lyx_view)
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setAcceptDrops(true);
setMouseTracking(true);
setMinimumSize(100, 70);
viewport()->setAutoFillBackground(false);

View File

@ -180,6 +180,9 @@ public:
/// 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 or leave this inset
/// return true if this inset needs repaint
virtual bool setMouseHover(bool mouse_hover) { return false; }
/// request "external features"
virtual void validate(LaTeXFeatures &) const {}

View File

@ -53,7 +53,7 @@ InsetCollapsable::CollapseStatus InsetCollapsable::status() const
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,13 @@ bool InsetCollapsable::metrics(MetricsInfo & mi, Dimension & dim) const
}
bool InsetCollapsable::setMouseHover(bool mouse_hover)
{
mouse_hover_ = mouse_hover;
return true;
}
void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
{
const int xx = x + TEXT_TO_INSET_OFFSET;
@ -181,7 +188,7 @@ void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
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;
@ -281,7 +288,7 @@ void InsetCollapsable::edit(LCursor & cur, bool left)
InsetBase * InsetCollapsable::editXY(LCursor & cur, int x, int y)
{
//lyxerr << "InsetCollapsable: edit xy" << endl;
if (status() == Collapsed)
if (status() == Collapsed || button_dim.contains(x, y))
return this;
cur.push(*this);
return InsetText::editXY(cur, x, y);

View File

@ -80,6 +80,8 @@ public:
bool getStatus(LCursor &, FuncRequest const &, FuncStatus &) const;
///
void setStatus(LCursor & cur, CollapseStatus st);
///
bool setMouseHover(bool mouse_hover);
protected:
///
@ -117,6 +119,8 @@ private:
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.

View File

@ -35,6 +35,7 @@ InsetCommand::InsetCommand(InsetCommandParams const & p,
string const & mailer_name)
: p_(p),
mailer_name_(mailer_name),
mouse_hover_(false),
updateButtonLabel_(true)
{}
@ -60,9 +61,17 @@ bool InsetCommand::metrics(MetricsInfo & mi, Dimension & dim) const
}
bool InsetCommand::setMouseHover(bool mouse_hover)
{
mouse_hover_ = mouse_hover;
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);
}

View File

@ -91,6 +91,8 @@ public:
std::string const getSecOptions() const { return p_.getSecOptions(); }
///
RenderButton & button() const { return button_; }
///
bool setMouseHover(bool mouse_hover);
protected:
///
@ -128,6 +130,8 @@ private:
///
InsetCommandParams p_;
std::string mailer_name_;
/// changes color when mouse enters/leaves this inset
bool mouse_hover_;
mutable bool updateButtonLabel_;
mutable RenderButton button_;
};

View File

@ -39,6 +39,10 @@ public:
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 @@ protected:
RenderBase(RenderBase const &) {}
RenderBase & operator=(RenderBase const &) { return *this; }
/// render state. currently, render_button uses this to store mouse_hover_
int state_;
/// Cached
mutable Dimension dim_;
};

View File

@ -71,7 +71,7 @@ void RenderButton::draw(PainterInfo & pi, int x, int y) const
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);