move triangle drawing into FbDrawable
Make MenuItem triangles proportional
This commit is contained in:
parent
2e438fde2c
commit
1f7b12cc49
8 changed files with 118 additions and 91 deletions
|
@ -1,5 +1,11 @@
|
||||||
(Format: Year/Month/Day)
|
(Format: Year/Month/Day)
|
||||||
Changes for 1.0rc3:
|
Changes for 1.0rc3:
|
||||||
|
*07/01/06:
|
||||||
|
* Move triangle drawing into a generic function in FbDrawable (Simon)
|
||||||
|
Make submenu triangles in MenuItems proportional to the icon size
|
||||||
|
(alternate implementation of sf.net patch #1526813)
|
||||||
|
FbTk/... FbDrawable.hh/cc MenuItem.cc
|
||||||
|
ArrowButton.hh/cc WinButton.cc ToolFactory.cc
|
||||||
*07/01/05:
|
*07/01/05:
|
||||||
* When a client in an unfocused tab creates a transient window, set that
|
* When a client in an unfocused tab creates a transient window, set that
|
||||||
client to the active tab (Mark)
|
client to the active tab (Mark)
|
||||||
|
|
|
@ -24,27 +24,27 @@
|
||||||
#include "ArrowButton.hh"
|
#include "ArrowButton.hh"
|
||||||
#include "ButtonTheme.hh"
|
#include "ButtonTheme.hh"
|
||||||
|
|
||||||
ArrowButton::ArrowButton(ArrowButton::Type arrow_type,
|
ArrowButton::ArrowButton(FbTk::FbDrawable::TriangleType arrow_type,
|
||||||
const FbTk::FbWindow &parent,
|
const FbTk::FbWindow &parent,
|
||||||
int x, int y,
|
int x, int y,
|
||||||
unsigned int width, unsigned int height):
|
unsigned int width, unsigned int height):
|
||||||
FbTk::Button(parent, x, y, width, height),
|
FbTk::Button(parent, x, y, width, height),
|
||||||
m_arrow_type(arrow_type),
|
m_arrow_type(arrow_type),
|
||||||
m_mouse_handler(0),
|
m_mouse_handler(0),
|
||||||
m_arrowscale(300) {
|
m_arrowscale(250) {
|
||||||
|
|
||||||
setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask |
|
setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask |
|
||||||
EnterWindowMask | LeaveWindowMask);
|
EnterWindowMask | LeaveWindowMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrowButton::ArrowButton(ArrowButton::Type arrow_type,
|
ArrowButton::ArrowButton(FbTk::FbDrawable::TriangleType arrow_type,
|
||||||
int screen_num,
|
int screen_num,
|
||||||
int x, int y,
|
int x, int y,
|
||||||
unsigned int width, unsigned int height):
|
unsigned int width, unsigned int height):
|
||||||
FbTk::Button(screen_num, x, y, width, height),
|
FbTk::Button(screen_num, x, y, width, height),
|
||||||
m_arrow_type(arrow_type),
|
m_arrow_type(arrow_type),
|
||||||
m_mouse_handler(0),
|
m_mouse_handler(0),
|
||||||
m_arrowscale(300) {
|
m_arrowscale(250) {
|
||||||
|
|
||||||
setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask |
|
setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask |
|
||||||
EnterWindowMask | LeaveWindowMask);
|
EnterWindowMask | LeaveWindowMask);
|
||||||
|
@ -84,46 +84,8 @@ void ArrowButton::leaveNotifyEvent(XCrossingEvent &ce) {
|
||||||
redraws the arrow button
|
redraws the arrow button
|
||||||
*/
|
*/
|
||||||
void ArrowButton::drawArrow() {
|
void ArrowButton::drawArrow() {
|
||||||
XPoint pts[3];
|
if (gc() != 0)
|
||||||
unsigned int w = width();
|
drawTriangle(gc(), m_arrow_type, 0, 0, width(), height(), m_arrowscale);
|
||||||
unsigned int h = height();
|
|
||||||
|
|
||||||
int arrowscale_n = m_arrowscale;
|
|
||||||
int arrowscale_d = 100;
|
|
||||||
unsigned int ax = arrowscale_d * w / arrowscale_n;
|
|
||||||
unsigned int ay = arrowscale_d * h / arrowscale_n;
|
|
||||||
// if these aren't an even number, left and right arrows end up different
|
|
||||||
if (( ax % 2 ) == 1) ax++;
|
|
||||||
if (( ay % 2 ) == 1) ay++;
|
|
||||||
switch (m_arrow_type) {
|
|
||||||
case LEFT:
|
|
||||||
// start at the tip
|
|
||||||
pts[0].x = (w / 2) - (ax / 2); pts[0].y = h / 2;
|
|
||||||
pts[1].x = ax; pts[1].y = -ay / 2;
|
|
||||||
pts[2].x = 0; pts[2].y = ay;
|
|
||||||
break;
|
|
||||||
case RIGHT:
|
|
||||||
pts[0].x = (w / 2) + (ax / 2); pts[0].y = h / 2;
|
|
||||||
pts[1].x = - ax; pts[1].y = ay / 2;
|
|
||||||
pts[2].x = 0; pts[2].y = - ay;
|
|
||||||
break;
|
|
||||||
case UP:
|
|
||||||
pts[0].x = (w / 2); pts[0].y = (h / 2) - (ay / 2);
|
|
||||||
pts[1].x = ax / 2; pts[1].y = ay;
|
|
||||||
pts[2].x = - ax; pts[2].y = 0;
|
|
||||||
break;
|
|
||||||
case DOWN:
|
|
||||||
pts[0].x = (w / 2); pts[0].y = (h / 2) + (ay / 2);
|
|
||||||
pts[1].x = ax / 2; pts[1].y = - ay;
|
|
||||||
pts[2].x = - ax; pts[2].y = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gc() != 0) {
|
|
||||||
fillPolygon(gc(),
|
|
||||||
pts, 3,
|
|
||||||
Convex, CoordModePrevious);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArrowButton::updateTheme(const FbTk::Theme &theme) {
|
void ArrowButton::updateTheme(const FbTk::Theme &theme) {
|
||||||
|
@ -131,7 +93,7 @@ void ArrowButton::updateTheme(const FbTk::Theme &theme) {
|
||||||
const ButtonTheme &btheme = static_cast<const ButtonTheme &>(theme);
|
const ButtonTheme &btheme = static_cast<const ButtonTheme &>(theme);
|
||||||
|
|
||||||
m_arrowscale = btheme.scale();
|
m_arrowscale = btheme.scale();
|
||||||
if (m_arrowscale == 0) m_arrowscale = 300; // default is 0 => 300
|
if (m_arrowscale == 0) m_arrowscale = 250; // default is 0 => 300
|
||||||
else if (m_arrowscale < 100) m_arrowscale = 100; // otherwise clamp
|
else if (m_arrowscale < 100) m_arrowscale = 100; // otherwise clamp
|
||||||
else if (m_arrowscale > 100000) m_arrowscale = 100000; // clamp below overflow when *100
|
else if (m_arrowscale > 100000) m_arrowscale = 100000; // clamp below overflow when *100
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,18 +29,11 @@
|
||||||
/// Displays a arrow on a button
|
/// Displays a arrow on a button
|
||||||
class ArrowButton: public FbTk::Button {
|
class ArrowButton: public FbTk::Button {
|
||||||
public:
|
public:
|
||||||
/// type of arrow that should be drawn
|
|
||||||
enum Type {
|
|
||||||
LEFT,
|
|
||||||
RIGHT,
|
|
||||||
UP,
|
|
||||||
DOWN
|
|
||||||
};
|
|
||||||
|
|
||||||
ArrowButton(ArrowButton::Type arrow_type, const FbTk::FbWindow &parent,
|
ArrowButton(FbTk::FbDrawable::TriangleType arrow_type, const FbTk::FbWindow &parent,
|
||||||
int x, int y,
|
int x, int y,
|
||||||
unsigned int width, unsigned int height);
|
unsigned int width, unsigned int height);
|
||||||
ArrowButton(ArrowButton::Type arrow_type, int screen_num,
|
ArrowButton(FbTk::FbDrawable::TriangleType arrow_type, int screen_num,
|
||||||
int x, int y,
|
int x, int y,
|
||||||
unsigned int width, unsigned int height);
|
unsigned int width, unsigned int height);
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -53,7 +46,7 @@ public:
|
||||||
void updateTheme(const FbTk::Theme &theme);
|
void updateTheme(const FbTk::Theme &theme);
|
||||||
private:
|
private:
|
||||||
void drawArrow();
|
void drawArrow();
|
||||||
Type m_arrow_type;
|
FbTk::FbDrawable::TriangleType m_arrow_type;
|
||||||
FbTk::EventHandler *m_mouse_handler;
|
FbTk::EventHandler *m_mouse_handler;
|
||||||
int m_arrowscale;
|
int m_arrowscale;
|
||||||
};
|
};
|
||||||
|
|
|
@ -89,6 +89,70 @@ void FbDrawable::fillPolygon(GC gc, XPoint *points, int npoints,
|
||||||
shape, mode);
|
shape, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// x, y, width and height define a space within which we're drawing a triangle (centred)
|
||||||
|
// scale defines number of triangles that'd fit in a space of 100 width x 100 height
|
||||||
|
// (i.e. 200 = half size, 300 = a third). Its a bit backwards but it allows more flexibility
|
||||||
|
void FbDrawable::drawTriangle(GC gc, FbDrawable::TriangleType type,
|
||||||
|
int x, int y, unsigned int width, unsigned int height,
|
||||||
|
int scale) {
|
||||||
|
if (drawable() == 0 || gc == 0 || width == 0 || height == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
XPoint pts[3];
|
||||||
|
|
||||||
|
if (scale < 100) scale = 100; // not bigger than the space allowed
|
||||||
|
else if (scale > 10000) scale = 10000; // not too small...
|
||||||
|
|
||||||
|
int arrowscale_n = scale;
|
||||||
|
int arrowscale_d = 100;
|
||||||
|
unsigned int ax = arrowscale_d * width / arrowscale_n;
|
||||||
|
unsigned int ay = arrowscale_d * height / arrowscale_n;
|
||||||
|
// if these aren't an even number, left and right arrows end up different
|
||||||
|
if (type == FbTk::FbDrawable::LEFT ||
|
||||||
|
type == FbTk::FbDrawable::RIGHT) {
|
||||||
|
if (( ax % 2 ) == 1) ax--;
|
||||||
|
if (( ay % 2 ) == 1) ay--;
|
||||||
|
} else {
|
||||||
|
if (( ax % 2 ) == 0) ax--;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case FbTk::FbDrawable::LEFT:
|
||||||
|
// start at the tip
|
||||||
|
pts[0].x = (width / 2) - (ax / 2); pts[0].y = height / 2;
|
||||||
|
pts[1].x = ax; pts[1].y = -ay / 2;
|
||||||
|
pts[2].x = 0; pts[2].y = ay;
|
||||||
|
break;
|
||||||
|
case FbTk::FbDrawable::RIGHT:
|
||||||
|
pts[0].x = (width / 2) + (ax / 2); pts[0].y = height / 2;
|
||||||
|
pts[1].x = - ax; pts[1].y = ay / 2;
|
||||||
|
pts[2].x = 0; pts[2].y = - ay;
|
||||||
|
break;
|
||||||
|
case FbTk::FbDrawable::UP:
|
||||||
|
pts[0].x = (width / 2); pts[0].y = (height / 2) - (ay / 2)-1;
|
||||||
|
pts[1].x = ax / 2; pts[1].y = ay+1;
|
||||||
|
pts[2].x = - ax; pts[2].y = 0;
|
||||||
|
break;
|
||||||
|
case FbTk::FbDrawable::DOWN:
|
||||||
|
/* I tried and tried, but couldn't get the left diagonal of the down
|
||||||
|
arrow to be symmetrical with the right (for small widths)!
|
||||||
|
So we opt for this setup. It is symmetrical with larger widths */
|
||||||
|
pts[0].x = (width / 2) ; pts[0].y = (height / 2) + (ay / 2);
|
||||||
|
pts[1].x = -ax/2+1; pts[1].y = -ay;
|
||||||
|
pts[2].x = ax-1; pts[2].y = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// re-centre on the specified points
|
||||||
|
pts[0].x += x;
|
||||||
|
pts[0].y += y;
|
||||||
|
|
||||||
|
fillPolygon(gc,
|
||||||
|
pts, 3,
|
||||||
|
Convex, CoordModePrevious);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NOT_USED
|
#ifdef NOT_USED
|
||||||
void FbDrawable::drawPoint(GC gc, int x, int y) {
|
void FbDrawable::drawPoint(GC gc, int x, int y) {
|
||||||
if (drawable() == 0 || gc == 0)
|
if (drawable() == 0 || gc == 0)
|
||||||
|
|
|
@ -48,6 +48,20 @@ public:
|
||||||
virtual void fillPolygon(GC gc, XPoint *points, int npoints,
|
virtual void fillPolygon(GC gc, XPoint *points, int npoints,
|
||||||
int shape, int mode);
|
int shape, int mode);
|
||||||
|
|
||||||
|
/// type of arrow that should be drawn
|
||||||
|
enum TriangleType {
|
||||||
|
LEFT,
|
||||||
|
RIGHT,
|
||||||
|
UP,
|
||||||
|
DOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
// x, y, width and height define a space within which we're drawing a triangle
|
||||||
|
// scale defines number of triangles that'd fit in a space of 100 width x 100 height
|
||||||
|
// (i.e. 200 = half size, 300 = a third).
|
||||||
|
|
||||||
|
virtual void drawTriangle(GC gc, TriangleType type, int x, int y, unsigned int width, unsigned int height, int scale);
|
||||||
|
|
||||||
#ifdef NOT_USED
|
#ifdef NOT_USED
|
||||||
virtual void drawPoint(GC gc, int x, int y);
|
virtual void drawPoint(GC gc, int x, int y);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -216,26 +216,13 @@ void MenuItem::draw(FbDrawable &draw,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MenuTheme::TRIANGLE:
|
case MenuTheme::TRIANGLE:
|
||||||
XPoint tri[3];
|
draw.drawTriangle(gc, ((theme.bulletPos() == FbTk::RIGHT)?
|
||||||
|
FbTk::FbDrawable::RIGHT:
|
||||||
if (theme.bulletPos() == FbTk::RIGHT) {
|
FbTk::FbDrawable::LEFT),
|
||||||
tri[0].x = sel_x + half_w - 2;
|
sel_x, sel_y,
|
||||||
tri[0].y = sel_y + half_w - 2;
|
item_pm_height,
|
||||||
tri[1].x = 4;
|
item_pm_height,
|
||||||
tri[1].y = 2;
|
300); // 33% triangle
|
||||||
tri[2].x = -4;
|
|
||||||
tri[2].y = 2;
|
|
||||||
} else { // point the other way
|
|
||||||
tri[0].x = sel_x + half_w - 2;
|
|
||||||
tri[0].y = sel_y + half_w;
|
|
||||||
tri[1].x = 4;
|
|
||||||
tri[1].y = 2;
|
|
||||||
tri[2].x = 0;
|
|
||||||
tri[2].y = -4;
|
|
||||||
}
|
|
||||||
|
|
||||||
draw.fillPolygon(gc, tri, 3, Convex,
|
|
||||||
CoordModePrevious);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MenuTheme::DIAMOND:
|
case MenuTheme::DIAMOND:
|
||||||
|
|
|
@ -112,9 +112,9 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// TODO maybe direction of arrows should depend on toolbar layout ?
|
// TODO maybe direction of arrows should depend on toolbar layout ?
|
||||||
ArrowButton::Type arrow_type = ArrowButton::LEFT;
|
FbTk::FbDrawable::TriangleType arrow_type = FbTk::FbDrawable::UP;
|
||||||
if (name == "nextworkspace")
|
if (name == "nextworkspace")
|
||||||
arrow_type = ArrowButton::RIGHT;
|
arrow_type = FbTk::FbDrawable::DOWN;
|
||||||
|
|
||||||
ArrowButton *win = new ArrowButton(arrow_type, parent,
|
ArrowButton *win = new ArrowButton(arrow_type, parent,
|
||||||
0, 0,
|
0, 0,
|
||||||
|
@ -131,9 +131,9 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
|
||||||
if (*cmd == 0) // we need a command
|
if (*cmd == 0) // we need a command
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ArrowButton::Type arrow_type = ArrowButton::LEFT;
|
FbTk::FbDrawable::TriangleType arrow_type = FbTk::FbDrawable::LEFT;
|
||||||
if (name == "nextwindow")
|
if (name == "nextwindow")
|
||||||
arrow_type = ArrowButton::RIGHT;
|
arrow_type = FbTk::FbDrawable::RIGHT;
|
||||||
|
|
||||||
ArrowButton *win = new ArrowButton(arrow_type, parent,
|
ArrowButton *win = new ArrowButton(arrow_type, parent,
|
||||||
0, 0,
|
0, 0,
|
||||||
|
|
|
@ -265,20 +265,21 @@ void WinButton::drawType() {
|
||||||
break;
|
break;
|
||||||
case SHADE:
|
case SHADE:
|
||||||
|
|
||||||
drawRectangle(gc(), 2, 2, width() - 5 - oddW, 2);
|
{
|
||||||
|
int size = width() - 5 - oddW;
|
||||||
|
|
||||||
|
drawRectangle(gc(), 2, 2, size, 2);
|
||||||
|
|
||||||
XPoint points[3];
|
// draw a one-quarter triangle below the rectangle
|
||||||
if (m_listen_to.isShaded()) {
|
drawTriangle(gc(), (m_listen_to.isShaded() ?
|
||||||
points[1].x = (width() / 2) - 3; points[1].y = 7;
|
FbTk::FbDrawable::DOWN:
|
||||||
points[2].x = (width() / 2) + 4 - oddW; points[2].y = 7;
|
FbTk::FbDrawable::UP),
|
||||||
points[0].x = (width() / 2); points[0].y = height() / 2 + 2;
|
4, 6,
|
||||||
} else {
|
size-2, size/2 - 1,
|
||||||
points[0].x = (width() / 2); points[0].y = 6;
|
100);
|
||||||
points[1].x = (width() / 2) - 4; points[1].y = height() / 2 + 2;
|
|
||||||
points[2].x = (width() / 2) + 4 - oddW; points[2].y = height() / 2 + 2;
|
|
||||||
}
|
|
||||||
fillPolygon(gc(), points, 3, Convex, CoordModeOrigin);
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case MENUICON:
|
case MENUICON:
|
||||||
if (m_icon_pixmap.drawable()) {
|
if (m_icon_pixmap.drawable()) {
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue