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)
|
||||
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:
|
||||
* When a client in an unfocused tab creates a transient window, set that
|
||||
client to the active tab (Mark)
|
||||
|
|
|
@ -24,27 +24,27 @@
|
|||
#include "ArrowButton.hh"
|
||||
#include "ButtonTheme.hh"
|
||||
|
||||
ArrowButton::ArrowButton(ArrowButton::Type arrow_type,
|
||||
ArrowButton::ArrowButton(FbTk::FbDrawable::TriangleType arrow_type,
|
||||
const FbTk::FbWindow &parent,
|
||||
int x, int y,
|
||||
unsigned int width, unsigned int height):
|
||||
FbTk::Button(parent, x, y, width, height),
|
||||
m_arrow_type(arrow_type),
|
||||
m_mouse_handler(0),
|
||||
m_arrowscale(300) {
|
||||
m_arrowscale(250) {
|
||||
|
||||
setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask |
|
||||
EnterWindowMask | LeaveWindowMask);
|
||||
}
|
||||
|
||||
ArrowButton::ArrowButton(ArrowButton::Type arrow_type,
|
||||
ArrowButton::ArrowButton(FbTk::FbDrawable::TriangleType arrow_type,
|
||||
int screen_num,
|
||||
int x, int y,
|
||||
unsigned int width, unsigned int height):
|
||||
FbTk::Button(screen_num, x, y, width, height),
|
||||
m_arrow_type(arrow_type),
|
||||
m_mouse_handler(0),
|
||||
m_arrowscale(300) {
|
||||
m_arrowscale(250) {
|
||||
|
||||
setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask |
|
||||
EnterWindowMask | LeaveWindowMask);
|
||||
|
@ -84,46 +84,8 @@ void ArrowButton::leaveNotifyEvent(XCrossingEvent &ce) {
|
|||
redraws the arrow button
|
||||
*/
|
||||
void ArrowButton::drawArrow() {
|
||||
XPoint pts[3];
|
||||
unsigned int w = width();
|
||||
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);
|
||||
}
|
||||
if (gc() != 0)
|
||||
drawTriangle(gc(), m_arrow_type, 0, 0, width(), height(), m_arrowscale);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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 > 100000) m_arrowscale = 100000; // clamp below overflow when *100
|
||||
}
|
||||
|
|
|
@ -29,18 +29,11 @@
|
|||
/// Displays a arrow on a button
|
||||
class ArrowButton: public FbTk::Button {
|
||||
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,
|
||||
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,
|
||||
unsigned int width, unsigned int height);
|
||||
void clear();
|
||||
|
@ -53,7 +46,7 @@ public:
|
|||
void updateTheme(const FbTk::Theme &theme);
|
||||
private:
|
||||
void drawArrow();
|
||||
Type m_arrow_type;
|
||||
FbTk::FbDrawable::TriangleType m_arrow_type;
|
||||
FbTk::EventHandler *m_mouse_handler;
|
||||
int m_arrowscale;
|
||||
};
|
||||
|
|
|
@ -89,6 +89,70 @@ void FbDrawable::fillPolygon(GC gc, XPoint *points, int npoints,
|
|||
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
|
||||
void FbDrawable::drawPoint(GC gc, int x, int y) {
|
||||
if (drawable() == 0 || gc == 0)
|
||||
|
|
|
@ -48,6 +48,20 @@ public:
|
|||
virtual void fillPolygon(GC gc, XPoint *points, int npoints,
|
||||
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
|
||||
virtual void drawPoint(GC gc, int x, int y);
|
||||
#endif
|
||||
|
|
|
@ -216,26 +216,13 @@ void MenuItem::draw(FbDrawable &draw,
|
|||
break;
|
||||
|
||||
case MenuTheme::TRIANGLE:
|
||||
XPoint tri[3];
|
||||
|
||||
if (theme.bulletPos() == FbTk::RIGHT) {
|
||||
tri[0].x = sel_x + half_w - 2;
|
||||
tri[0].y = sel_y + half_w - 2;
|
||||
tri[1].x = 4;
|
||||
tri[1].y = 2;
|
||||
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);
|
||||
draw.drawTriangle(gc, ((theme.bulletPos() == FbTk::RIGHT)?
|
||||
FbTk::FbDrawable::RIGHT:
|
||||
FbTk::FbDrawable::LEFT),
|
||||
sel_x, sel_y,
|
||||
item_pm_height,
|
||||
item_pm_height,
|
||||
300); // 33% triangle
|
||||
break;
|
||||
|
||||
case MenuTheme::DIAMOND:
|
||||
|
|
|
@ -112,9 +112,9 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
|
|||
return 0;
|
||||
|
||||
// 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")
|
||||
arrow_type = ArrowButton::RIGHT;
|
||||
arrow_type = FbTk::FbDrawable::DOWN;
|
||||
|
||||
ArrowButton *win = new ArrowButton(arrow_type, parent,
|
||||
0, 0,
|
||||
|
@ -131,9 +131,9 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
|
|||
if (*cmd == 0) // we need a command
|
||||
return 0;
|
||||
|
||||
ArrowButton::Type arrow_type = ArrowButton::LEFT;
|
||||
FbTk::FbDrawable::TriangleType arrow_type = FbTk::FbDrawable::LEFT;
|
||||
if (name == "nextwindow")
|
||||
arrow_type = ArrowButton::RIGHT;
|
||||
arrow_type = FbTk::FbDrawable::RIGHT;
|
||||
|
||||
ArrowButton *win = new ArrowButton(arrow_type, parent,
|
||||
0, 0,
|
||||
|
|
|
@ -265,20 +265,21 @@ void WinButton::drawType() {
|
|||
break;
|
||||
case SHADE:
|
||||
|
||||
drawRectangle(gc(), 2, 2, width() - 5 - oddW, 2);
|
||||
{
|
||||
int size = width() - 5 - oddW;
|
||||
|
||||
drawRectangle(gc(), 2, 2, size, 2);
|
||||
|
||||
XPoint points[3];
|
||||
if (m_listen_to.isShaded()) {
|
||||
points[1].x = (width() / 2) - 3; points[1].y = 7;
|
||||
points[2].x = (width() / 2) + 4 - oddW; points[2].y = 7;
|
||||
points[0].x = (width() / 2); points[0].y = height() / 2 + 2;
|
||||
} else {
|
||||
points[0].x = (width() / 2); points[0].y = 6;
|
||||
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);
|
||||
// draw a one-quarter triangle below the rectangle
|
||||
drawTriangle(gc(), (m_listen_to.isShaded() ?
|
||||
FbTk::FbDrawable::DOWN:
|
||||
FbTk::FbDrawable::UP),
|
||||
4, 6,
|
||||
size-2, size/2 - 1,
|
||||
100);
|
||||
|
||||
break;
|
||||
}
|
||||
case MENUICON:
|
||||
if (m_icon_pixmap.drawable()) {
|
||||
|
||||
|
|
Loading…
Reference in a new issue