rotated fonts, buttons, containers. Used for tabs for now
This commit is contained in:
parent
872f6a0e1e
commit
af74a22845
36 changed files with 658 additions and 212 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,5 +1,20 @@
|
||||||
(Format: Year/Month/Day)
|
(Format: Year/Month/Day)
|
||||||
Changes for 0.9.16:
|
Changes for 0.9.16:
|
||||||
|
*06/03/26:
|
||||||
|
* More external tabs work AND rotated Xft text (Simon)
|
||||||
|
- new tab positions (LeftTop, LeftBottom, etc)
|
||||||
|
- TextButtons and Containers can have orientation set on them
|
||||||
|
- XftFonts store all rotated versions (if used),
|
||||||
|
so the theme doesn't need to know about it. Pixmaps are also auto-rotated.
|
||||||
|
- TODO: Update XFontImp rotation code
|
||||||
|
- Note: many files touched because constness removed from many fonts
|
||||||
|
FbTk/ Button.hh FbPixmap.hh/cc Font.hh/cc FontImp.hh ImageControl.hh/cc
|
||||||
|
Text.hh/cc TextButton.hh/cc TextureRender.hh/cc XFontImp.hh/cc
|
||||||
|
XftFontImp.hh/cc XmbFontImp.hh/cc
|
||||||
|
Container.hh/cc FbWinFrame.hh/cc FbWinFrameTheme.hh IconButton.hh/cc
|
||||||
|
IconbarTheme.hh IconbarTool.hh Screen.cc ToolFactory.hh/cc
|
||||||
|
WinButtonTheme.hh/cc
|
||||||
|
tests/testFont.cc
|
||||||
*06/03/24:
|
*06/03/24:
|
||||||
* Fix compile error in Theme.cc (sf.net bug #1454204)
|
* Fix compile error in Theme.cc (sf.net bug #1454204)
|
||||||
FbTk/Theme.cc
|
FbTk/Theme.cc
|
||||||
|
@ -200,7 +215,6 @@ Changes for 0.9.15:
|
||||||
src/ScreenResources.cc
|
src/ScreenResources.cc
|
||||||
* Use fbsetroot in Default-Styles (Mathias)
|
* Use fbsetroot in Default-Styles (Mathias)
|
||||||
data/styles/*
|
data/styles/*
|
||||||
-------------------------------------------------------------
|
|
||||||
Changes for 0.9.14:
|
Changes for 0.9.14:
|
||||||
*05/09/12:
|
*05/09/12:
|
||||||
* Fixes #1281708, MenuIcon doesnt scale properly (thanx Erik-Jan)
|
* Fixes #1281708, MenuIcon doesnt scale properly (thanx Erik-Jan)
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
Container::Container(const FbTk::FbWindow &parent):
|
Container::Container(const FbTk::FbWindow &parent):
|
||||||
FbTk::FbWindow(parent, 0, 0, 1, 1, ExposureMask),
|
FbTk::FbWindow(parent, 0, 0, 1, 1, ExposureMask),
|
||||||
m_align(RELATIVE),
|
m_align(RELATIVE),
|
||||||
|
m_orientation(FbTk::ROT0),
|
||||||
m_max_size_per_client(60),
|
m_max_size_per_client(60),
|
||||||
m_max_total_size(0),
|
m_max_total_size(0),
|
||||||
m_selected(0),
|
m_selected(0),
|
||||||
|
@ -104,6 +105,7 @@ void Container::insertItem(Item item, int pos) {
|
||||||
if (item->parent() != this)
|
if (item->parent() != this)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
item->setOrientation(m_orientation);
|
||||||
if (pos >= size() || pos < 0) {
|
if (pos >= size() || pos < 0) {
|
||||||
m_item_list.push_back(item);
|
m_item_list.push_back(item);
|
||||||
} else if (pos == 0) {
|
} else if (pos == 0) {
|
||||||
|
@ -273,6 +275,9 @@ void Container::setMaxTotalSize(unsigned int size) {
|
||||||
unsigned int old = m_max_total_size;
|
unsigned int old = m_max_total_size;
|
||||||
m_max_total_size = size;
|
m_max_total_size = size;
|
||||||
|
|
||||||
|
repositionItems();
|
||||||
|
return;
|
||||||
|
|
||||||
if (m_max_total_size && width() > m_max_total_size) {
|
if (m_max_total_size && width() > m_max_total_size) {
|
||||||
resize(m_max_total_size, height());
|
resize(m_max_total_size, height());
|
||||||
} else if (!m_max_total_size && old) { // going from restricted to unrestricted
|
} else if (!m_max_total_size && old) { // going from restricted to unrestricted
|
||||||
|
@ -366,13 +371,25 @@ void Container::repositionItems() {
|
||||||
if (empty() || m_update_lock)
|
if (empty() || m_update_lock)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//!! TODO vertical position
|
/**
|
||||||
|
NOTE: all calculations here are done in non-rotated space
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned int max_width_per_client = maxWidthPerClient();
|
unsigned int max_width_per_client = maxWidthPerClient();
|
||||||
unsigned int borderW = m_item_list.front()->borderWidth();
|
unsigned int borderW = m_item_list.front()->borderWidth();
|
||||||
unsigned int num_items = m_item_list.size();
|
unsigned int num_items = m_item_list.size();
|
||||||
|
|
||||||
unsigned int total_width = width();
|
unsigned int total_width;
|
||||||
|
unsigned int cur_width;
|
||||||
|
unsigned int height;
|
||||||
|
// unrotate
|
||||||
|
if (m_orientation == FbTk::ROT0 || m_orientation == FbTk::ROT180) {
|
||||||
|
total_width = cur_width = width();
|
||||||
|
height = this->height();
|
||||||
|
} else {
|
||||||
|
total_width = cur_width = this->height();
|
||||||
|
height = width();
|
||||||
|
}
|
||||||
|
|
||||||
// if we have a max total size, then we must also resize ourself
|
// if we have a max total size, then we must also resize ourself
|
||||||
// within that bound
|
// within that bound
|
||||||
|
@ -387,12 +404,20 @@ void Container::repositionItems() {
|
||||||
} else
|
} else
|
||||||
max_width_per_client = 1;
|
max_width_per_client = 1;
|
||||||
}
|
}
|
||||||
if (total_width != width()) {
|
|
||||||
|
if (total_width != cur_width) {
|
||||||
// calling Container::resize here risks infinite loops
|
// calling Container::resize here risks infinite loops
|
||||||
if (align == RIGHT)
|
unsigned int neww = total_width, newh = height;
|
||||||
FbTk::FbWindow::moveResize(x() - (total_width - width()), y(), total_width, height());
|
translateSize(m_orientation, neww, newh);
|
||||||
else
|
if (align == RIGHT || m_orientation == FbTk::ROT270) {
|
||||||
FbTk::FbWindow::resize(total_width, height());
|
int deltax = - (total_width - cur_width);
|
||||||
|
int deltay = 0;
|
||||||
|
FbTk::translateCoords(m_orientation, deltax, deltay, total_width, height);
|
||||||
|
|
||||||
|
FbTk::FbWindow::moveResize(x() + deltax, y() + deltay, neww, newh);
|
||||||
|
} else {
|
||||||
|
FbTk::FbWindow::resize(neww, newh);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,6 +435,8 @@ void Container::repositionItems() {
|
||||||
next_x = total_width - max_width_per_client - borderW;
|
next_x = total_width - max_width_per_client - borderW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tmpx, tmpy;
|
||||||
|
unsigned int tmpw, tmph;
|
||||||
for (; it != it_end; ++it, next_x += direction*(max_width_per_client + borderW + extra)) {
|
for (; it != it_end; ++it, next_x += direction*(max_width_per_client + borderW + extra)) {
|
||||||
// we only need to do error stuff with alignment RELATIVE
|
// we only need to do error stuff with alignment RELATIVE
|
||||||
if (rounding_error != 0 && align == RELATIVE) {
|
if (rounding_error != 0 && align == RELATIVE) {
|
||||||
|
@ -418,11 +445,20 @@ void Container::repositionItems() {
|
||||||
} else {
|
} else {
|
||||||
extra = 0;
|
extra = 0;
|
||||||
}
|
}
|
||||||
|
// rotate the x and y coords
|
||||||
|
tmpx = next_x;
|
||||||
|
tmpy = -borderW;
|
||||||
|
tmpw = max_width_per_client + extra;
|
||||||
|
tmph = height;
|
||||||
|
|
||||||
|
FbTk::translateCoords(m_orientation, tmpx, tmpy, total_width, height);
|
||||||
|
FbTk::translatePosition(m_orientation, tmpx, tmpy, tmpw, tmph);
|
||||||
|
FbTk::translateSize(m_orientation, tmpw, tmph);
|
||||||
|
|
||||||
// resize each clients including border in size
|
// resize each clients including border in size
|
||||||
(*it)->moveResize(next_x,
|
(*it)->moveResize(tmpx, tmpy,
|
||||||
-borderW,
|
tmpw, tmph);
|
||||||
max_width_per_client + extra,
|
|
||||||
height());
|
|
||||||
// moveresize does a clear
|
// moveresize does a clear
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,3 +512,26 @@ void Container::clear() {
|
||||||
(*it)->clear();
|
(*it)->clear();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Container::setOrientation(FbTk::Orientation orient) {
|
||||||
|
if (m_orientation == orient)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ItemList::iterator it = m_item_list.begin();
|
||||||
|
ItemList::iterator it_end = m_item_list.end();
|
||||||
|
for (; it != it_end; ++it)
|
||||||
|
(*it)->setOrientation(orient);
|
||||||
|
|
||||||
|
if ((m_orientation == FbTk::ROT0 || m_orientation == FbTk::ROT180) &&
|
||||||
|
(orient == FbTk::ROT90 || orient == FbTk::ROT270) ||
|
||||||
|
(m_orientation == FbTk::ROT90 || m_orientation == FbTk::ROT270) &&
|
||||||
|
(orient == FbTk::ROT0 || orient == FbTk::ROT180)) {
|
||||||
|
// flip width and height
|
||||||
|
m_orientation = orient;
|
||||||
|
resize(height(), width());
|
||||||
|
} else {
|
||||||
|
m_orientation = orient;
|
||||||
|
repositionItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "FbTk/FbWindow.hh"
|
#include "FbTk/FbWindow.hh"
|
||||||
#include "FbTk/EventHandler.hh"
|
#include "FbTk/EventHandler.hh"
|
||||||
#include "FbTk/NotCopyable.hh"
|
#include "FbTk/NotCopyable.hh"
|
||||||
|
#include "FbTk/Text.hh" // for Orientation
|
||||||
|
|
||||||
namespace FbTk {
|
namespace FbTk {
|
||||||
class Button;
|
class Button;
|
||||||
|
@ -66,6 +67,7 @@ public:
|
||||||
void setMaxSizePerClient(unsigned int size);
|
void setMaxSizePerClient(unsigned int size);
|
||||||
void setMaxTotalSize(unsigned int size);
|
void setMaxTotalSize(unsigned int size);
|
||||||
void setAlignment(Alignment a);
|
void setAlignment(Alignment a);
|
||||||
|
void setOrientation(FbTk::Orientation orient);
|
||||||
|
|
||||||
Item back() { return m_item_list.back(); }
|
Item back() { return m_item_list.back(); }
|
||||||
|
|
||||||
|
@ -83,6 +85,7 @@ public:
|
||||||
|
|
||||||
/// accessors
|
/// accessors
|
||||||
inline Alignment alignment() const { return m_align; }
|
inline Alignment alignment() const { return m_align; }
|
||||||
|
inline FbTk::Orientation orientation() const { return m_orientation; }
|
||||||
inline int size() const { return m_item_list.size(); }
|
inline int size() const { return m_item_list.size(); }
|
||||||
inline bool empty() const { return m_item_list.empty(); }
|
inline bool empty() const { return m_item_list.empty(); }
|
||||||
inline const Item& selected() const { return m_selected; }
|
inline const Item& selected() const { return m_selected; }
|
||||||
|
@ -103,6 +106,8 @@ public:
|
||||||
private:
|
private:
|
||||||
void repositionItems();
|
void repositionItems();
|
||||||
|
|
||||||
|
FbTk::Orientation m_orientation;
|
||||||
|
|
||||||
Alignment m_align;
|
Alignment m_align;
|
||||||
unsigned int m_max_size_per_client;
|
unsigned int m_max_size_per_client;
|
||||||
unsigned int m_max_total_size;
|
unsigned int m_max_total_size;
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "FbWindow.hh"
|
#include "FbWindow.hh"
|
||||||
#include "Command.hh"
|
#include "Command.hh"
|
||||||
#include "Color.hh"
|
#include "Color.hh"
|
||||||
|
#include "Text.hh"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -57,6 +58,7 @@ public:
|
||||||
virtual void setBackgroundPixmap(Pixmap pm);
|
virtual void setBackgroundPixmap(Pixmap pm);
|
||||||
/// sets background color
|
/// sets background color
|
||||||
virtual void setBackgroundColor(const Color &color);
|
virtual void setBackgroundColor(const Color &color);
|
||||||
|
virtual bool setOrientation(FbTk::Orientation orient) { return orient == FbTk::ROT0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@name eventhandlers
|
@name eventhandlers
|
||||||
|
|
|
@ -201,25 +201,63 @@ void FbPixmap::copy(Pixmap pm, int depth, int screen_num) {
|
||||||
XFreeGC(display(), gc);
|
XFreeGC(display(), gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FbPixmap::rotate() {
|
void FbPixmap::rotate(FbTk::Orientation orient) {
|
||||||
|
if (orient == ROT0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned int oldw = width(), oldh = height();
|
||||||
|
unsigned int neww = oldw, newh = oldh;
|
||||||
|
translateSize(orient, neww, newh);
|
||||||
|
|
||||||
// make an image copy
|
// make an image copy
|
||||||
XImage *src_image = XGetImage(display(), drawable(),
|
XImage *src_image = XGetImage(display(), drawable(),
|
||||||
0, 0, // pos
|
0, 0, // pos
|
||||||
width(), height(), // size
|
oldw, oldh, // size
|
||||||
~0, // plane mask
|
~0, // plane mask
|
||||||
ZPixmap); // format
|
ZPixmap); // format
|
||||||
// reverse height/width for new pixmap
|
// reverse height/width for new pixmap
|
||||||
FbPixmap new_pm(drawable(), height(), width(), depth());
|
FbPixmap new_pm(drawable(), neww, newh, depth());
|
||||||
|
|
||||||
GContext gc(drawable());
|
GContext gc(drawable());
|
||||||
|
|
||||||
// copy new area
|
if (orient == ROT180) {
|
||||||
for (unsigned int y = 0; y < height(); ++y) {
|
unsigned int srcx, srcy, destx, desty;
|
||||||
for (unsigned int x = 0; x < width(); ++x) {
|
for (srcy = 0, desty = oldh; srcy < oldh; ++srcy, --desty) {
|
||||||
gc.setForeground(XGetPixel(src_image, x, y));
|
for (srcx = 0, destx = oldw; srcx < oldw; ++srcx, --destx) {
|
||||||
// revers coordinates
|
gc.setForeground(XGetPixel(src_image, srcx, srcy));
|
||||||
XDrawPoint(display(), new_pm.drawable(), gc.gc(), y, x);
|
XDrawPoint(display(), new_pm.drawable(), gc.gc(), destx, desty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// need to flip x and y
|
||||||
|
|
||||||
|
// set start, end and direction based on rotation
|
||||||
|
// NOTE that startx etc are in the direction of the OLD pixmap
|
||||||
|
unsigned int startx, starty;
|
||||||
|
int dirx, diry;
|
||||||
|
switch (orient) {
|
||||||
|
case ROT90:
|
||||||
|
startx = neww-1;
|
||||||
|
starty = 0;
|
||||||
|
dirx = -1;
|
||||||
|
diry = 1;
|
||||||
|
break;
|
||||||
|
case ROT270:
|
||||||
|
startx = 0;
|
||||||
|
starty = newh-1;
|
||||||
|
dirx = 1;
|
||||||
|
diry = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// copy new area
|
||||||
|
unsigned int srcx, srcy, destx, desty;
|
||||||
|
for (srcy = 0, destx = startx; srcy < oldh; ++srcy, destx+=dirx) {
|
||||||
|
for (srcx = 0, desty = starty; srcx < oldw; ++srcx, desty+=diry) {
|
||||||
|
gc.setForeground(XGetPixel(src_image, srcx, srcy));
|
||||||
|
XDrawPoint(display(), new_pm.drawable(), gc.gc(), destx, desty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#define FBTK_FBPIXMAP_HH
|
#define FBTK_FBPIXMAP_HH
|
||||||
|
|
||||||
#include "FbDrawable.hh"
|
#include "FbDrawable.hh"
|
||||||
|
#include "Text.hh"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
@ -49,8 +50,8 @@ public:
|
||||||
|
|
||||||
void copy(const FbPixmap &the_copy);
|
void copy(const FbPixmap &the_copy);
|
||||||
void copy(Pixmap pixmap, int depth_convert, int screen_num);
|
void copy(Pixmap pixmap, int depth_convert, int screen_num);
|
||||||
/// rotates the pixmap 90 deg, not implemented!
|
/// rotates the pixmap to specified orientation (assumes ROT0 now)
|
||||||
void rotate();
|
void rotate(FbTk::Orientation orient);
|
||||||
/// scales the pixmap to specified size
|
/// scales the pixmap to specified size
|
||||||
void scale(unsigned int width, unsigned int height);
|
void scale(unsigned int width, unsigned int height);
|
||||||
void resize(unsigned int width, unsigned int height);
|
void resize(unsigned int width, unsigned int height);
|
||||||
|
|
|
@ -201,7 +201,6 @@ void Font::shutdown() {
|
||||||
|
|
||||||
Font::Font(const char *name):
|
Font::Font(const char *name):
|
||||||
m_fontimp(0),
|
m_fontimp(0),
|
||||||
m_rotated(false),
|
|
||||||
m_shadow(false), m_shadow_color("black", DefaultScreen(App::instance()->display())),
|
m_shadow(false), m_shadow_color("black", DefaultScreen(App::instance()->display())),
|
||||||
m_shadow_offx(2), m_shadow_offy(2),
|
m_shadow_offx(2), m_shadow_offy(2),
|
||||||
m_halo(false), m_halo_color("white", DefaultScreen(App::instance()->display())),
|
m_halo(false), m_halo_color("white", DefaultScreen(App::instance()->display())),
|
||||||
|
@ -361,9 +360,13 @@ int Font::descent() const {
|
||||||
return m_fontimp->descent();
|
return m_fontimp->descent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Font::validOrientation(FbTk::Orientation orient) {
|
||||||
|
return m_fontimp->validOrientation(orient);
|
||||||
|
}
|
||||||
|
|
||||||
void Font::drawText(const FbDrawable &w, int screen, GC gc,
|
void Font::drawText(const FbDrawable &w, int screen, GC gc,
|
||||||
const char *text, size_t len, int x, int y,
|
const char *text, size_t len, int x, int y,
|
||||||
bool rotate) const {
|
Orientation orient) const {
|
||||||
if (text == 0 || len == 0)
|
if (text == 0 || len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -391,69 +394,26 @@ void Font::drawText(const FbDrawable &w, int screen, GC gc,
|
||||||
shadow_gc.setForeground(m_shadow_color);
|
shadow_gc.setForeground(m_shadow_color);
|
||||||
first_run = false;
|
first_run = false;
|
||||||
drawText(w, screen, shadow_gc.gc(), real_text, len,
|
drawText(w, screen, shadow_gc.gc(), real_text, len,
|
||||||
x + m_shadow_offx, y + m_shadow_offy, rotate);
|
x + m_shadow_offx, y + m_shadow_offy, orient);
|
||||||
first_run = true;
|
first_run = true;
|
||||||
} else if (m_halo) {
|
} else if (m_halo) {
|
||||||
FbTk::GContext halo_gc(w);
|
FbTk::GContext halo_gc(w);
|
||||||
halo_gc.setForeground(m_halo_color);
|
halo_gc.setForeground(m_halo_color);
|
||||||
first_run = false;
|
first_run = false;
|
||||||
drawText(w, screen, halo_gc.gc(), real_text, len, x + 1, y + 1, rotate);
|
drawText(w, screen, halo_gc.gc(), real_text, len, x + 1, y + 1, orient);
|
||||||
drawText(w, screen, halo_gc.gc(), real_text, len, x - 1, y + 1, rotate);
|
drawText(w, screen, halo_gc.gc(), real_text, len, x - 1, y + 1, orient);
|
||||||
drawText(w, screen, halo_gc.gc(), real_text, len, x - 1, y - 1, rotate);
|
drawText(w, screen, halo_gc.gc(), real_text, len, x - 1, y - 1, orient);
|
||||||
drawText(w, screen, halo_gc.gc(), real_text, len, x + 1, y - 1, rotate);
|
drawText(w, screen, halo_gc.gc(), real_text, len, x + 1, y - 1, orient);
|
||||||
first_run = true;
|
first_run = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rotate && isRotated()) {
|
m_fontimp->drawText(w, screen, gc, real_text, len, x, y, orient);
|
||||||
// if this was called with request to not rotated the text
|
|
||||||
// we just forward it to the implementation that handles rotation
|
|
||||||
// currently just XFontImp
|
|
||||||
// Using dynamic_cast just temporarly until there's a better solution
|
|
||||||
// to put in FontImp
|
|
||||||
try {
|
|
||||||
XFontImp *font = dynamic_cast<XFontImp *>(m_fontimp);
|
|
||||||
font->setRotate(false); // disable rotation temporarly
|
|
||||||
|
|
||||||
font->drawText(w, screen, gc, real_text, len, x, y);
|
|
||||||
font->setRotate(true); // enable rotation
|
|
||||||
} catch (std::bad_cast &bc) {
|
|
||||||
// draw normal...
|
|
||||||
m_fontimp->drawText(w, screen, gc, real_text, len, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else
|
|
||||||
m_fontimp->drawText(w, screen, gc, real_text, len, x, y);
|
|
||||||
|
|
||||||
if (rtext != 0)
|
if (rtext != 0)
|
||||||
delete[] rtext;
|
delete[] rtext;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::rotate(float angle) {
|
|
||||||
/* TODO: reimplement rotated text
|
|
||||||
#ifdef USE_XFT
|
|
||||||
// if we are rotated and we are changing to horiz text
|
|
||||||
// and we were antialiased before we rotated then change to XftFontImp
|
|
||||||
if (isRotated() && angle == 0 && !m_xftfontstr.empty())
|
|
||||||
m_fontimp.reset(new XftFontImp(m_fontstr.c_str(),s_utf8mode));
|
|
||||||
#endif // USE_XFT
|
|
||||||
// change to a font imp that handles rotated fonts (i.e just XFontImp at the moment)
|
|
||||||
// if we're going to rotate this font
|
|
||||||
if (angle != 0 && !isRotated()) {
|
|
||||||
m_fontimp.reset(new XFontImp(m_fontstr.c_str()));
|
|
||||||
if (!m_fontimp->loaded()) // if it failed to load font, try default font fixed
|
|
||||||
m_fontimp->load("fixed");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Note: only XFontImp implements FontImp::rotate
|
|
||||||
m_fontimp->rotate(angle);
|
|
||||||
|
|
||||||
m_rotated = (angle == 0 ? false : true);
|
|
||||||
m_angle = angle;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#endif // HAVE_ICONV
|
#endif // HAVE_ICONV
|
||||||
|
|
||||||
#include "Color.hh"
|
#include "Color.hh"
|
||||||
|
#include "Text.hh"
|
||||||
|
|
||||||
namespace FbTk {
|
namespace FbTk {
|
||||||
|
|
||||||
|
@ -89,11 +90,13 @@ public:
|
||||||
unsigned int height() const;
|
unsigned int height() const;
|
||||||
int ascent() const;
|
int ascent() const;
|
||||||
int descent() const;
|
int descent() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Rotate font in any angle
|
Returns whether we can draw this font in the given orientation.
|
||||||
(currently only 90 degrees supported and just XFont implementation)
|
(will instantiate that orientation, so do plan to use it...)
|
||||||
|
@param orient the orientation to test
|
||||||
*/
|
*/
|
||||||
void rotate(float angle);
|
bool validOrientation(FbTk::Orientation orient);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Draws text to drawable
|
Draws text to drawable
|
||||||
|
@ -108,11 +111,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void drawText(const FbDrawable &w, int screen, GC gc,
|
void drawText(const FbDrawable &w, int screen, GC gc,
|
||||||
const char *text, size_t len,
|
const char *text, size_t len,
|
||||||
int x, int y, bool rotate=true) const;
|
int x, int y, FbTk::Orientation orient = ROT0) const;
|
||||||
/// @return true if the font is rotated, else false
|
|
||||||
bool isRotated() const { return m_rotated; }
|
|
||||||
/// @return rotated angle
|
|
||||||
float angle() const { return m_angle; }
|
|
||||||
bool hasShadow() const { return m_shadow; }
|
bool hasShadow() const { return m_shadow; }
|
||||||
bool hasHalo() const { return m_halo; }
|
bool hasHalo() const { return m_halo; }
|
||||||
private:
|
private:
|
||||||
|
@ -123,8 +123,7 @@ private:
|
||||||
static bool s_multibyte; ///< if the fontimp should be a multibyte font
|
static bool s_multibyte; ///< if the fontimp should be a multibyte font
|
||||||
static bool s_utf8mode; ///< should the font use utf8 font imp
|
static bool s_utf8mode; ///< should the font use utf8 font imp
|
||||||
|
|
||||||
bool m_rotated; ///< wheter we're rotated or not
|
int m_angle; ///< rotation angle
|
||||||
float m_angle; ///< rotation angle
|
|
||||||
bool m_shadow; ///< shadow text
|
bool m_shadow; ///< shadow text
|
||||||
Color m_shadow_color; ///< shadow color
|
Color m_shadow_color; ///< shadow color
|
||||||
int m_shadow_offx; ///< offset y for shadow
|
int m_shadow_offx; ///< offset y for shadow
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#define FBTK_FONTIMP_HH
|
#define FBTK_FONTIMP_HH
|
||||||
|
|
||||||
#include "Color.hh"
|
#include "Color.hh"
|
||||||
|
#include "Font.hh"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
@ -43,13 +44,14 @@ class FontImp {
|
||||||
public:
|
public:
|
||||||
virtual ~FontImp() { }
|
virtual ~FontImp() { }
|
||||||
virtual bool load(const std::string &name) = 0;
|
virtual bool load(const std::string &name) = 0;
|
||||||
virtual void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y) const = 0;
|
virtual void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const = 0;
|
||||||
virtual unsigned int textWidth(const char * const text, unsigned int size) const = 0;
|
virtual unsigned int textWidth(const char * const text, unsigned int size) const = 0;
|
||||||
|
virtual bool validOrientation(FbTk::Orientation orient) { return orient == ROT0; }
|
||||||
virtual int ascent() const = 0;
|
virtual int ascent() const = 0;
|
||||||
virtual int descent() const = 0;
|
virtual int descent() const = 0;
|
||||||
virtual unsigned int height() const = 0;
|
virtual unsigned int height() const = 0;
|
||||||
virtual bool loaded() const = 0;
|
virtual bool loaded() const = 0;
|
||||||
virtual void rotate(float angle) { } // by default, no rotate support
|
virtual void rotate(int angle) { } // by default, no rotate support
|
||||||
virtual bool utf8() const { return false; };
|
virtual bool utf8() const { return false; };
|
||||||
protected:
|
protected:
|
||||||
FontImp() { }
|
FontImp() { }
|
||||||
|
|
|
@ -166,7 +166,7 @@ ImageControl::~ImageControl() {
|
||||||
|
|
||||||
|
|
||||||
Pixmap ImageControl::searchCache(unsigned int width, unsigned int height,
|
Pixmap ImageControl::searchCache(unsigned int width, unsigned int height,
|
||||||
const Texture &text) const {
|
const Texture &text, FbTk::Orientation orient) const {
|
||||||
|
|
||||||
if (text.pixmap().drawable() != None) {
|
if (text.pixmap().drawable() != None) {
|
||||||
// do comparsion with width/height and texture_pixmap
|
// do comparsion with width/height and texture_pixmap
|
||||||
|
@ -174,7 +174,9 @@ Pixmap ImageControl::searchCache(unsigned int width, unsigned int height,
|
||||||
CacheList::iterator it_end = cache.end();
|
CacheList::iterator it_end = cache.end();
|
||||||
for (; it != it_end; ++it) {
|
for (; it != it_end; ++it) {
|
||||||
if ((*it)->texture_pixmap == text.pixmap().drawable() &&
|
if ((*it)->texture_pixmap == text.pixmap().drawable() &&
|
||||||
(*it)->width == width && (*it)->height == height &&
|
(*it)->orient == orient &&
|
||||||
|
(*it)->width == width &&
|
||||||
|
(*it)->height == height &&
|
||||||
(*it)->texture == text.type()) {
|
(*it)->texture == text.type()) {
|
||||||
(*it)->count++;
|
(*it)->count++;
|
||||||
return (*it)->pixmap;
|
return (*it)->pixmap;
|
||||||
|
@ -196,6 +198,7 @@ Pixmap ImageControl::searchCache(unsigned int width, unsigned int height,
|
||||||
CacheList::iterator it_end = cache.end();
|
CacheList::iterator it_end = cache.end();
|
||||||
for (; it != it_end; ++it) {
|
for (; it != it_end; ++it) {
|
||||||
if (((*it)->width == width) &&
|
if (((*it)->width == width) &&
|
||||||
|
((*it)->orient == orient) &&
|
||||||
((*it)->height == height) &&
|
((*it)->height == height) &&
|
||||||
((*it)->texture == text.type()) &&
|
((*it)->texture == text.type()) &&
|
||||||
((*it)->pixel1 == text.color().pixel())) {
|
((*it)->pixel1 == text.color().pixel())) {
|
||||||
|
@ -217,19 +220,21 @@ Pixmap ImageControl::searchCache(unsigned int width, unsigned int height,
|
||||||
|
|
||||||
|
|
||||||
Pixmap ImageControl::renderImage(unsigned int width, unsigned int height,
|
Pixmap ImageControl::renderImage(unsigned int width, unsigned int height,
|
||||||
const FbTk::Texture &texture) {
|
const FbTk::Texture &texture,
|
||||||
|
FbTk::Orientation orient) {
|
||||||
|
|
||||||
if (texture.type() & FbTk::Texture::PARENTRELATIVE)
|
if (texture.type() & FbTk::Texture::PARENTRELATIVE)
|
||||||
return ParentRelative;
|
return ParentRelative;
|
||||||
|
|
||||||
// search cache first
|
// search cache first
|
||||||
Pixmap pixmap = searchCache(width, height, texture);
|
Pixmap pixmap = searchCache(width, height, texture, orient);
|
||||||
if (pixmap) {
|
if (pixmap) {
|
||||||
return pixmap; // return cache item
|
return pixmap; // return cache item
|
||||||
}
|
}
|
||||||
|
|
||||||
// render new image
|
// render new image
|
||||||
TextureRender image(*this, width, height, m_colors, m_num_colors);
|
|
||||||
|
TextureRender image(*this, width, height, orient, m_colors, m_num_colors);
|
||||||
pixmap = image.render(texture);
|
pixmap = image.render(texture);
|
||||||
|
|
||||||
if (pixmap) {
|
if (pixmap) {
|
||||||
|
@ -239,6 +244,7 @@ Pixmap ImageControl::renderImage(unsigned int width, unsigned int height,
|
||||||
|
|
||||||
tmp->pixmap = pixmap;
|
tmp->pixmap = pixmap;
|
||||||
tmp->texture_pixmap = texture.pixmap().drawable();
|
tmp->texture_pixmap = texture.pixmap().drawable();
|
||||||
|
tmp->orient = orient;
|
||||||
tmp->width = width;
|
tmp->width = width;
|
||||||
tmp->height = height;
|
tmp->height = height;
|
||||||
tmp->count = 1;
|
tmp->count = 1;
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#ifndef FBTK_IMAGECONTROL_HH
|
#ifndef FBTK_IMAGECONTROL_HH
|
||||||
#define FBTK_IMAGECONTROL_HH
|
#define FBTK_IMAGECONTROL_HH
|
||||||
|
|
||||||
|
// actually, Text is rather tool like, that's where orientation comes from
|
||||||
|
#include "Text.hh"
|
||||||
#include "Texture.hh"
|
#include "Texture.hh"
|
||||||
#include "Timer.hh"
|
#include "Timer.hh"
|
||||||
#include "NotCopyable.hh"
|
#include "NotCopyable.hh"
|
||||||
|
@ -61,7 +63,8 @@ public:
|
||||||
@return pixmap of the rendered image, on failure None
|
@return pixmap of the rendered image, on failure None
|
||||||
*/
|
*/
|
||||||
Pixmap renderImage(unsigned int width, unsigned int height,
|
Pixmap renderImage(unsigned int width, unsigned int height,
|
||||||
const FbTk::Texture &src_texture);
|
const FbTk::Texture &src_texture,
|
||||||
|
Orientation orient = ROT0);
|
||||||
|
|
||||||
void installRootColormap();
|
void installRootColormap();
|
||||||
void removeImage(Pixmap thepix);
|
void removeImage(Pixmap thepix);
|
||||||
|
@ -79,7 +82,7 @@ private:
|
||||||
Search cache for a specific pixmap
|
Search cache for a specific pixmap
|
||||||
@return None if no cache was found
|
@return None if no cache was found
|
||||||
*/
|
*/
|
||||||
Pixmap searchCache(unsigned int width, unsigned int height, const Texture &text) const;
|
Pixmap searchCache(unsigned int width, unsigned int height, const Texture &text, Orientation orient) const;
|
||||||
|
|
||||||
void createColorTable();
|
void createColorTable();
|
||||||
bool m_dither;
|
bool m_dither;
|
||||||
|
@ -109,19 +112,20 @@ private:
|
||||||
typedef struct Cache {
|
typedef struct Cache {
|
||||||
Pixmap pixmap;
|
Pixmap pixmap;
|
||||||
Pixmap texture_pixmap;
|
Pixmap texture_pixmap;
|
||||||
|
Orientation orient;
|
||||||
unsigned int count, width, height;
|
unsigned int count, width, height;
|
||||||
unsigned long pixel1, pixel2, texture;
|
unsigned long pixel1, pixel2, texture;
|
||||||
} Cache;
|
} Cache;
|
||||||
|
|
||||||
struct ltCacheEntry {
|
struct ltCacheEntry {
|
||||||
bool operator()(const Cache* s1, const Cache* s2) const {
|
bool operator()(const Cache* s1, const Cache* s2) const {
|
||||||
return (s1->width < s2->width || s1->width == s2->width &&
|
return (s1->orient < s2->orient || s1->orient == s2->orient
|
||||||
(s1->height < s2->height || s1->height == s2->height &&
|
&& (s1->width < s2->width || s1->width == s2->width
|
||||||
(s1->texture < s2->texture || s1->texture == s2->texture &&
|
&& (s1->height < s2->height || s1->height == s2->height
|
||||||
s1->pixel1 < s2->pixel1 || s1->pixel1 == s2->pixel1 &&
|
&& (s1->texture < s2->texture || s1->texture == s2->texture
|
||||||
(s1->texture & FbTk::Texture::GRADIENT) &&
|
&& (s1->pixel1 < s2->pixel1 || s1->pixel1 == s2->pixel1
|
||||||
s1->pixel2 < s2->pixel2)
|
&& ((s1->texture & FbTk::Texture::GRADIENT) && s1->pixel2 < s2->pixel2)
|
||||||
));
|
)))));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ int doAlignment(int max_width, int bevel, FbTk::Justify justify,
|
||||||
return dx;
|
return dx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// specialization for Justify
|
/// specialization for Justify
|
||||||
template <>
|
template <>
|
||||||
void ThemeItem<FbTk::Justify>::setDefaultValue() {
|
void ThemeItem<FbTk::Justify>::setDefaultValue() {
|
||||||
|
|
|
@ -29,6 +29,9 @@ namespace FbTk {
|
||||||
class Font;
|
class Font;
|
||||||
|
|
||||||
enum Justify {LEFT, RIGHT, CENTER};
|
enum Justify {LEFT, RIGHT, CENTER};
|
||||||
|
// clockwise
|
||||||
|
enum Orientation { ROT0=0, ROT90, ROT180, ROT270 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Aligns the text after max width and bevel
|
Aligns the text after max width and bevel
|
||||||
*/
|
*/
|
||||||
|
@ -36,6 +39,77 @@ int doAlignment(int max_width, int bevel, FbTk::Justify justify,
|
||||||
const FbTk::Font &font, const char * const text,
|
const FbTk::Font &font, const char * const text,
|
||||||
unsigned int textlen, unsigned int &newlen);
|
unsigned int textlen, unsigned int &newlen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
There are 3 interesting translations:
|
||||||
|
1) Coords = simple rotation of coordinates
|
||||||
|
2) Position = adjusting (x,y) coordinates to use to position a box with X coords
|
||||||
|
3) Size = swapping of width and height if necessary
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// translate coordinates from ROT0 into different orientations
|
||||||
|
// coords are relative to rot0 0,0 position
|
||||||
|
// Need width and height of the area being rotated (in ROT0 coords)
|
||||||
|
|
||||||
|
inline void translateCoords(Orientation orient, int &x, int &y, unsigned int w, unsigned int h) {
|
||||||
|
|
||||||
|
int orig_x = x;
|
||||||
|
int orig_y = y;
|
||||||
|
|
||||||
|
switch(orient) {
|
||||||
|
case ROT0:
|
||||||
|
break;
|
||||||
|
case ROT90:
|
||||||
|
x = h - orig_y;
|
||||||
|
y = orig_x;
|
||||||
|
break;
|
||||||
|
case ROT180:
|
||||||
|
x = w - orig_x;
|
||||||
|
y = h - orig_y;
|
||||||
|
break;
|
||||||
|
case ROT270:
|
||||||
|
x = orig_y;
|
||||||
|
y = w - orig_x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// When positioning an X11 box inside another area, we need to
|
||||||
|
// relocate the x,y coordinates
|
||||||
|
inline void translatePosition(Orientation orient, int &x, int &y, unsigned int w, unsigned int h) {
|
||||||
|
|
||||||
|
int orig_x = x;
|
||||||
|
int orig_y = y;
|
||||||
|
|
||||||
|
switch(orient) {
|
||||||
|
case ROT0:
|
||||||
|
break;
|
||||||
|
case ROT90:
|
||||||
|
x -= h;
|
||||||
|
break;
|
||||||
|
case ROT180:
|
||||||
|
x -= w;
|
||||||
|
y -= h;
|
||||||
|
break;
|
||||||
|
case ROT270:
|
||||||
|
y -= w;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void translateSize(Orientation orient, unsigned int &w, unsigned int &h) {
|
||||||
|
if (orient == ROT0 || orient == ROT180)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned int tmp;
|
||||||
|
tmp = w;
|
||||||
|
w = h;
|
||||||
|
h = tmp;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace FbTk
|
} // end namespace FbTk
|
||||||
|
|
||||||
#endif // FBTK_TEXT_HH
|
#endif // FBTK_TEXT_HH
|
||||||
|
|
|
@ -28,16 +28,18 @@
|
||||||
namespace FbTk {
|
namespace FbTk {
|
||||||
|
|
||||||
TextButton::TextButton(const FbTk::FbWindow &parent,
|
TextButton::TextButton(const FbTk::FbWindow &parent,
|
||||||
const FbTk::Font &font,
|
FbTk::Font &font,
|
||||||
const std::string &text):
|
const std::string &text):
|
||||||
FbTk::Button(parent, 0, 0, 10, 10),
|
FbTk::Button(parent, 0, 0, 10, 10),
|
||||||
m_font(&font),
|
m_font(&font),
|
||||||
m_text(text),
|
m_text(text),
|
||||||
m_justify(FbTk::LEFT), m_bevel(1),
|
m_justify(FbTk::LEFT),
|
||||||
|
m_orientation(FbTk::ROT0),
|
||||||
|
m_bevel(1),
|
||||||
m_left_padding(0),
|
m_left_padding(0),
|
||||||
m_right_padding(0) {
|
m_right_padding(0) {
|
||||||
setRenderer(*this);
|
|
||||||
|
|
||||||
|
setRenderer(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextButton::resize(unsigned int width, unsigned int height) {
|
void TextButton::resize(unsigned int width, unsigned int height) {
|
||||||
|
@ -60,6 +62,23 @@ void TextButton::setJustify(FbTk::Justify just) {
|
||||||
m_justify = just;
|
m_justify = just;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TextButton::setOrientation(FbTk::Orientation orient) {
|
||||||
|
if (!m_font->validOrientation(orient))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((m_orientation == FbTk::ROT0 || m_orientation == FbTk::ROT180) &&
|
||||||
|
(orient == FbTk::ROT90 || orient == FbTk::ROT270) ||
|
||||||
|
(m_orientation == FbTk::ROT90 || m_orientation == FbTk::ROT270) &&
|
||||||
|
(orient == FbTk::ROT0 || orient == FbTk::ROT180)) {
|
||||||
|
// flip width and height
|
||||||
|
m_orientation = orient;
|
||||||
|
resize(height(), width());
|
||||||
|
} else {
|
||||||
|
m_orientation = orient;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void TextButton::setText(const std::string &text) {
|
void TextButton::setText(const std::string &text) {
|
||||||
if (m_text != text) {
|
if (m_text != text) {
|
||||||
m_text = text;
|
m_text = text;
|
||||||
|
@ -68,7 +87,7 @@ void TextButton::setText(const std::string &text) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextButton::setFont(const FbTk::Font &font) {
|
void TextButton::setFont(FbTk::Font &font) {
|
||||||
// no need to set new font if it's the same
|
// no need to set new font if it's the same
|
||||||
if (&font == m_font)
|
if (&font == m_font)
|
||||||
return;
|
return;
|
||||||
|
@ -109,10 +128,16 @@ void TextButton::clearArea(int x, int y,
|
||||||
drawText(0, 0, this);
|
drawText(0, 0, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int TextButton::textWidth() const {
|
unsigned int TextButton::textWidth() const {
|
||||||
return font().textWidth(text().c_str(), text().size());
|
return font().textWidth(text().c_str(), text().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int TextButton::textHeight() const {
|
||||||
|
return font().height();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void TextButton::renderForeground(FbWindow &win, FbDrawable &drawable) {
|
void TextButton::renderForeground(FbWindow &win, FbDrawable &drawable) {
|
||||||
// (win should always be *this, no need to check)
|
// (win should always be *this, no need to check)
|
||||||
drawText(0, 0, &drawable);
|
drawText(0, 0, &drawable);
|
||||||
|
@ -122,7 +147,10 @@ void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) {
|
||||||
unsigned int textlen = text().size();
|
unsigned int textlen = text().size();
|
||||||
// do text alignment
|
// do text alignment
|
||||||
|
|
||||||
int align_x = FbTk::doAlignment(width() - x_offset - m_left_padding - m_right_padding,
|
unsigned int textw = width(), texth = height();
|
||||||
|
translateSize(m_orientation, textw, texth);
|
||||||
|
|
||||||
|
int align_x = FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding,
|
||||||
bevel(),
|
bevel(),
|
||||||
justify(),
|
justify(),
|
||||||
font(),
|
font(),
|
||||||
|
@ -130,17 +158,22 @@ void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) {
|
||||||
textlen); // return new text lne
|
textlen); // return new text lne
|
||||||
|
|
||||||
// center text by default
|
// center text by default
|
||||||
int center_pos = height()/2 + font().ascent()/2 - 1;
|
int center_pos = texth/2 + font().ascent()/2 - 1;
|
||||||
|
|
||||||
|
int textx = align_x + x_offset + m_left_padding;
|
||||||
|
int texty = center_pos + y_offset;
|
||||||
|
|
||||||
if (drawable == 0)
|
if (drawable == 0)
|
||||||
drawable = this;
|
drawable = this;
|
||||||
|
|
||||||
|
// give it ROT0 style coords
|
||||||
|
translateCoords(m_orientation, textx, texty, textw, texth);
|
||||||
|
|
||||||
font().drawText(*drawable,
|
font().drawText(*drawable,
|
||||||
screenNumber(),
|
screenNumber(),
|
||||||
gc(), // graphic context
|
gc(), // graphic context
|
||||||
text().c_str(), textlen, // string and string size
|
text().c_str(), textlen, // string and string size
|
||||||
align_x + x_offset + m_left_padding, center_pos + y_offset); // position
|
textx, texty, m_orientation); // position
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextButton::exposeEvent(XExposeEvent &event) {
|
void TextButton::exposeEvent(XExposeEvent &event) {
|
||||||
|
|
|
@ -38,11 +38,12 @@ class Font;
|
||||||
class TextButton: public FbTk::Button, FbTk::FbWindowRenderer {
|
class TextButton: public FbTk::Button, FbTk::FbWindowRenderer {
|
||||||
public:
|
public:
|
||||||
TextButton(const FbTk::FbWindow &parent,
|
TextButton(const FbTk::FbWindow &parent,
|
||||||
const FbTk::Font &font, const std::string &text);
|
FbTk::Font &font, const std::string &text);
|
||||||
|
|
||||||
void setJustify(FbTk::Justify just);
|
void setJustify(FbTk::Justify just);
|
||||||
|
bool setOrientation(FbTk::Orientation orient);
|
||||||
void setText(const std::string &text);
|
void setText(const std::string &text);
|
||||||
void setFont(const FbTk::Font &font);
|
void setFont(FbTk::Font &font);
|
||||||
void setBevel(int bevel);
|
void setBevel(int bevel);
|
||||||
void setTextPadding(unsigned int padding);
|
void setTextPadding(unsigned int padding);
|
||||||
void setTextPaddingLeft(unsigned int leftpadding);
|
void setTextPaddingLeft(unsigned int leftpadding);
|
||||||
|
@ -65,8 +66,9 @@ public:
|
||||||
|
|
||||||
inline FbTk::Justify justify() const { return m_justify; }
|
inline FbTk::Justify justify() const { return m_justify; }
|
||||||
inline const std::string &text() const { return m_text; }
|
inline const std::string &text() const { return m_text; }
|
||||||
inline const FbTk::Font &font() const { return *m_font; }
|
inline FbTk::Font &font() const { return *m_font; }
|
||||||
unsigned int textWidth() const;
|
unsigned int textWidth() const;
|
||||||
|
unsigned int textHeight() const;
|
||||||
int bevel() const { return m_bevel; }
|
int bevel() const { return m_bevel; }
|
||||||
unsigned int leftPadding() const { return m_left_padding; }
|
unsigned int leftPadding() const { return m_left_padding; }
|
||||||
unsigned int rightPadding() const { return m_right_padding; }
|
unsigned int rightPadding() const { return m_right_padding; }
|
||||||
|
@ -77,10 +79,11 @@ protected:
|
||||||
virtual void drawText(int x_offset, int y_offset, FbDrawable *drawable_override);
|
virtual void drawText(int x_offset, int y_offset, FbDrawable *drawable_override);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const FbTk::Font *m_font;
|
FbTk::Font *m_font;
|
||||||
std::string m_text;
|
std::string m_text;
|
||||||
FbTk::Justify m_justify;
|
FbTk::Justify m_justify;
|
||||||
|
FbTk::Orientation m_orientation;
|
||||||
|
|
||||||
int m_bevel;
|
int m_bevel;
|
||||||
unsigned int m_left_padding; ///< space between buttonborder and text
|
unsigned int m_left_padding; ///< space between buttonborder and text
|
||||||
unsigned int m_right_padding; ///< space between buttonborder and text
|
unsigned int m_right_padding; ///< space between buttonborder and text
|
||||||
|
|
|
@ -52,6 +52,7 @@ namespace FbTk {
|
||||||
|
|
||||||
TextureRender::TextureRender(ImageControl &imgctrl,
|
TextureRender::TextureRender(ImageControl &imgctrl,
|
||||||
unsigned int w, unsigned int h,
|
unsigned int w, unsigned int h,
|
||||||
|
FbTk::Orientation orient,
|
||||||
XColor *_colors, size_t num_colors):
|
XColor *_colors, size_t num_colors):
|
||||||
control(imgctrl),
|
control(imgctrl),
|
||||||
colors(_colors),
|
colors(_colors),
|
||||||
|
@ -59,6 +60,7 @@ TextureRender::TextureRender(ImageControl &imgctrl,
|
||||||
cpc(imgctrl.colorsPerChannel()),
|
cpc(imgctrl.colorsPerChannel()),
|
||||||
cpccpc(cpc * cpc),
|
cpccpc(cpc * cpc),
|
||||||
red(0), green(0), blue(0),
|
red(0), green(0), blue(0),
|
||||||
|
orientation(orient),
|
||||||
width(static_cast<signed>((w > 0 ? w : 1))), height(static_cast<signed>(h > 0 ? h : 1)),
|
width(static_cast<signed>((w > 0 ? w : 1))), height(static_cast<signed>(h > 0 ? h : 1)),
|
||||||
xtable(0), ytable(0) {
|
xtable(0), ytable(0) {
|
||||||
|
|
||||||
|
@ -231,6 +233,9 @@ Pixmap TextureRender::renderGradient(const FbTk::Texture &texture) {
|
||||||
|
|
||||||
bool inverted = false;
|
bool inverted = false;
|
||||||
|
|
||||||
|
// invert our width and height if necessary
|
||||||
|
translateSize(orientation, width, height);
|
||||||
|
|
||||||
using namespace FbTk;
|
using namespace FbTk;
|
||||||
|
|
||||||
interlaced = texture.type() & Texture::INTERLACED;
|
interlaced = texture.type() & Texture::INTERLACED;
|
||||||
|
@ -281,23 +286,30 @@ Pixmap TextureRender::renderGradient(const FbTk::Texture &texture) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Pixmap TextureRender::renderPixmap(const FbTk::Texture &src_texture) {
|
Pixmap TextureRender::renderPixmap(const FbTk::Texture &src_texture) {
|
||||||
if (width != src_texture.pixmap().width() ||
|
unsigned int tmpw = width, tmph = height;
|
||||||
height != src_texture.pixmap().height()) {
|
// we are given width and height in rotated form, we
|
||||||
|
// unrotate it here to render it
|
||||||
|
translateSize(orientation, tmpw, tmph);
|
||||||
|
if (tmpw != src_texture.pixmap().width() ||
|
||||||
|
tmph != src_texture.pixmap().height()) {
|
||||||
|
|
||||||
// copy src_texture's pixmap and
|
// copy src_texture's pixmap and
|
||||||
// scale/tile to fit our size
|
// scale/tile to fit our size
|
||||||
FbPixmap new_pm(src_texture.pixmap());
|
FbPixmap new_pm(src_texture.pixmap());
|
||||||
|
|
||||||
if ((src_texture.type() & Texture::TILED)) {
|
if ((src_texture.type() & Texture::TILED)) {
|
||||||
new_pm.tile(width,height);
|
new_pm.tile(tmpw,tmph);
|
||||||
} else {
|
} else {
|
||||||
new_pm.scale(width, height);
|
new_pm.scale(tmpw, tmph);
|
||||||
}
|
}
|
||||||
|
new_pm.rotate(orientation);
|
||||||
return new_pm.release();
|
return new_pm.release();
|
||||||
}
|
}
|
||||||
// return copy of pixmap
|
// return copy of pixmap
|
||||||
return FbPixmap(src_texture.pixmap()).release();
|
FbPixmap pm_copy = FbPixmap(src_texture.pixmap());
|
||||||
|
pm_copy.rotate(orientation);
|
||||||
|
|
||||||
|
return pm_copy.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
XImage *TextureRender::renderXImage() {
|
XImage *TextureRender::renderXImage() {
|
||||||
|
@ -728,6 +740,8 @@ Pixmap TextureRender::renderPixmap() {
|
||||||
|
|
||||||
XDestroyImage(image);
|
XDestroyImage(image);
|
||||||
|
|
||||||
|
pixmap.rotate(orientation);
|
||||||
|
|
||||||
return pixmap.release();
|
return pixmap.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#define FBTK_TEXTURRENDER_HH
|
#define FBTK_TEXTURRENDER_HH
|
||||||
|
|
||||||
#include "Texture.hh"
|
#include "Texture.hh"
|
||||||
|
#include "Text.hh"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
@ -43,6 +44,7 @@ class ImageControl;
|
||||||
class TextureRender {
|
class TextureRender {
|
||||||
public:
|
public:
|
||||||
TextureRender(ImageControl &ic, unsigned int width, unsigned int height,
|
TextureRender(ImageControl &ic, unsigned int width, unsigned int height,
|
||||||
|
Orientation orient = ROT0,
|
||||||
XColor *_colors=0, size_t num_colors=0);
|
XColor *_colors=0, size_t num_colors=0);
|
||||||
~TextureRender();
|
~TextureRender();
|
||||||
/// render to pixmap
|
/// render to pixmap
|
||||||
|
@ -94,6 +96,7 @@ private:
|
||||||
ncolors, cpc, cpccpc;
|
ncolors, cpc, cpccpc;
|
||||||
unsigned char *red, *green, *blue;
|
unsigned char *red, *green, *blue;
|
||||||
const unsigned char *red_table, *green_table, *blue_table;
|
const unsigned char *red_table, *green_table, *blue_table;
|
||||||
|
Orientation orientation;
|
||||||
unsigned int width, height;
|
unsigned int width, height;
|
||||||
unsigned int *xtable, *ytable;
|
unsigned int *xtable, *ytable;
|
||||||
};
|
};
|
||||||
|
|
|
@ -79,9 +79,10 @@ bool XFontImp::load(const std::string &fontname) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y) const {
|
void XFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const {
|
||||||
if (m_fontstruct == 0)
|
if (m_fontstruct == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// use roated font functions?
|
// use roated font functions?
|
||||||
if (m_rotfont != 0 && m_rotate) {
|
if (m_rotfont != 0 && m_rotate) {
|
||||||
drawRotText(w.drawable(), screen, gc, text, len, x, y);
|
drawRotText(w.drawable(), screen, gc, text, len, x, y);
|
||||||
|
@ -110,7 +111,7 @@ unsigned int XFontImp::height() const {
|
||||||
return m_fontstruct->ascent + m_fontstruct->descent;
|
return m_fontstruct->ascent + m_fontstruct->descent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XFontImp::rotate(float angle) {
|
void XFontImp::rotate(int angle) {
|
||||||
//we must have a font loaded before we rotate
|
//we must have a font loaded before we rotate
|
||||||
if (m_fontstruct == 0 || m_fontstruct->per_char == 0)
|
if (m_fontstruct == 0 || m_fontstruct->per_char == 0)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -38,12 +38,13 @@ public:
|
||||||
bool load(const std::string &filename);
|
bool load(const std::string &filename);
|
||||||
unsigned int textWidth(const char * const text, unsigned int size) const;
|
unsigned int textWidth(const char * const text, unsigned int size) const;
|
||||||
unsigned int height() const;
|
unsigned int height() const;
|
||||||
float angle() const { return m_angle; }
|
int angle() const { return m_angle; }
|
||||||
int ascent() const;
|
int ascent() const;
|
||||||
int descent() const { return m_fontstruct ? m_fontstruct->descent : 0; }
|
int descent() const { return m_fontstruct ? m_fontstruct->descent : 0; }
|
||||||
void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y) const;
|
void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const;
|
||||||
|
|
||||||
bool loaded() const { return m_fontstruct != 0; }
|
bool loaded() const { return m_fontstruct != 0; }
|
||||||
void rotate(float angle);
|
void rotate(int angle);
|
||||||
/// enable/disable rotation witout alloc/dealloc rotfont structures
|
/// enable/disable rotation witout alloc/dealloc rotfont structures
|
||||||
void setRotate(bool val) { m_rotate = val; }
|
void setRotate(bool val) { m_rotate = val; }
|
||||||
private:
|
private:
|
||||||
|
@ -79,7 +80,7 @@ private:
|
||||||
};
|
};
|
||||||
XRotFontStruct *m_rotfont; ///< rotated font structure
|
XRotFontStruct *m_rotfont; ///< rotated font structure
|
||||||
XFontStruct *m_fontstruct; ///< X font structure
|
XFontStruct *m_fontstruct; ///< X font structure
|
||||||
float m_angle; ///< the rotated angle
|
int m_angle; ///< the rotated angle
|
||||||
bool m_rotate; ///< used to disable/enable rotation temprarly without reallocating m_rotfont
|
bool m_rotate; ///< used to disable/enable rotation temprarly without reallocating m_rotfont
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,21 +25,28 @@
|
||||||
#include "App.hh"
|
#include "App.hh"
|
||||||
#include "FbDrawable.hh"
|
#include "FbDrawable.hh"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif //HAVE_CONFIG_H
|
#endif //HAVE_CONFIG_H
|
||||||
|
|
||||||
namespace FbTk {
|
namespace FbTk {
|
||||||
|
|
||||||
XftFontImp::XftFontImp(const char *name, bool utf8):m_xftfont(0),
|
XftFontImp::XftFontImp(const char *name, bool utf8):
|
||||||
m_utf8mode(utf8) {
|
m_utf8mode(utf8), m_name("") {
|
||||||
|
|
||||||
|
for (int r = ROT0; r <= ROT270; r++)
|
||||||
|
m_xftfonts[r] = 0;
|
||||||
|
|
||||||
if (name != 0)
|
if (name != 0)
|
||||||
load(name);
|
load(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
XftFontImp::~XftFontImp() {
|
XftFontImp::~XftFontImp() {
|
||||||
if (m_xftfont != 0)
|
for (int r = ROT0; r <= ROT270; r++)
|
||||||
XftFontClose(App::instance()->display(), m_xftfont);
|
if (m_xftfonts[r] != 0)
|
||||||
|
XftFontClose(App::instance()->display(), m_xftfonts[r]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XftFontImp::load(const std::string &name) {
|
bool XftFontImp::load(const std::string &name) {
|
||||||
|
@ -54,18 +61,39 @@ bool XftFontImp::load(const std::string &name) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy old font and set new
|
// destroy all old fonts and set new
|
||||||
if (m_xftfont != 0)
|
for (int r = ROT0; r <= ROT270; r++)
|
||||||
XftFontClose(disp, m_xftfont);
|
if (m_xftfonts[r] != 0)
|
||||||
|
XftFontClose(App::instance()->display(), m_xftfonts[r]);
|
||||||
|
|
||||||
m_xftfont = newxftfont;
|
m_xftfonts[ROT0] = newxftfont;
|
||||||
|
m_name = name;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y) const {
|
void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const {
|
||||||
if (m_xftfont == 0)
|
if (m_xftfonts[orient] == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// we adjust y slightly so that the baseline is in the right spot
|
||||||
|
// (it is offset one by rotation >=180 degrees)
|
||||||
|
switch (orient) {
|
||||||
|
case ROT0:
|
||||||
|
break;
|
||||||
|
case ROT90:
|
||||||
|
break;
|
||||||
|
case ROT180:
|
||||||
|
x+=1;
|
||||||
|
y+=1;
|
||||||
|
break;
|
||||||
|
case ROT270:
|
||||||
|
y+=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
XftFont *font = m_xftfonts[orient];
|
||||||
|
|
||||||
XftDraw *draw = XftDrawCreate(w.display(),
|
XftDraw *draw = XftDrawCreate(w.display(),
|
||||||
w.drawable(),
|
w.drawable(),
|
||||||
DefaultVisual(w.display(), screen),
|
DefaultVisual(w.display(), screen),
|
||||||
|
@ -101,13 +129,13 @@ void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *te
|
||||||
// if the size is zero we use the XftDrawString8 function instead.
|
// if the size is zero we use the XftDrawString8 function instead.
|
||||||
XGlyphInfo ginfo;
|
XGlyphInfo ginfo;
|
||||||
XftTextExtentsUtf8(w.display(),
|
XftTextExtentsUtf8(w.display(),
|
||||||
m_xftfont,
|
m_xftfonts[ROT0],
|
||||||
(XftChar8 *)text, len,
|
(XftChar8 *)text, len,
|
||||||
&ginfo);
|
&ginfo);
|
||||||
if (ginfo.xOff != 0) {
|
if (ginfo.xOff != 0) {
|
||||||
XftDrawStringUtf8(draw,
|
XftDrawStringUtf8(draw,
|
||||||
&xftcolor,
|
&xftcolor,
|
||||||
m_xftfont,
|
font,
|
||||||
x, y,
|
x, y,
|
||||||
(XftChar8 *)(text), len);
|
(XftChar8 *)(text), len);
|
||||||
XftColorFree(w.display(),
|
XftColorFree(w.display(),
|
||||||
|
@ -121,7 +149,7 @@ void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *te
|
||||||
|
|
||||||
XftDrawString8(draw,
|
XftDrawString8(draw,
|
||||||
&xftcolor,
|
&xftcolor,
|
||||||
m_xftfont,
|
font,
|
||||||
x, y,
|
x, y,
|
||||||
(XftChar8 *)(text), len);
|
(XftChar8 *)(text), len);
|
||||||
|
|
||||||
|
@ -133,16 +161,19 @@ void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *te
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int XftFontImp::textWidth(const char * const text, unsigned int len) const {
|
unsigned int XftFontImp::textWidth(const char * const text, unsigned int len) const {
|
||||||
if (m_xftfont == 0)
|
if (m_xftfonts[ROT0] == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
XGlyphInfo ginfo;
|
XGlyphInfo ginfo;
|
||||||
Display* disp = App::instance()->display();
|
Display* disp = App::instance()->display();
|
||||||
|
|
||||||
|
XftFont *font = m_xftfonts[ROT0];
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_XFT_UTF8_STRING
|
#ifdef HAVE_XFT_UTF8_STRING
|
||||||
if (m_utf8mode) {
|
if (m_utf8mode) {
|
||||||
XftTextExtentsUtf8(disp,
|
XftTextExtentsUtf8(disp,
|
||||||
m_xftfont,
|
font,
|
||||||
(XftChar8 *)text, len,
|
(XftChar8 *)text, len,
|
||||||
&ginfo);
|
&ginfo);
|
||||||
if (ginfo.xOff != 0)
|
if (ginfo.xOff != 0)
|
||||||
|
@ -153,7 +184,7 @@ unsigned int XftFontImp::textWidth(const char * const text, unsigned int len) co
|
||||||
#endif //HAVE_XFT_UTF8_STRING
|
#endif //HAVE_XFT_UTF8_STRING
|
||||||
|
|
||||||
XftTextExtents8(disp,
|
XftTextExtents8(disp,
|
||||||
m_xftfont,
|
font,
|
||||||
(XftChar8 *)text, len,
|
(XftChar8 *)text, len,
|
||||||
&ginfo);
|
&ginfo);
|
||||||
|
|
||||||
|
@ -161,12 +192,47 @@ unsigned int XftFontImp::textWidth(const char * const text, unsigned int len) co
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int XftFontImp::height() const {
|
unsigned int XftFontImp::height() const {
|
||||||
if (m_xftfont == 0)
|
if (m_xftfonts[ROT0] == 0)
|
||||||
return 0;
|
return 0;
|
||||||
return m_xftfont->height;
|
else
|
||||||
|
return m_xftfonts[ROT0]->height;
|
||||||
//m_xftfont->ascent + m_xftfont->descent;
|
//m_xftfont->ascent + m_xftfont->descent;
|
||||||
// curiously, fonts seem to have a smaller height, but the "height"
|
// curiously, fonts seem to have a smaller height, but the "height"
|
||||||
// is specified within the actual font, so it must be right, right?
|
// is specified within the actual font, so it must be right, right?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool XftFontImp::validOrientation(FbTk::Orientation orient) {
|
||||||
|
if (orient == ROT0 || m_xftfonts[orient])
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (m_xftfonts[ROT0] == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// otherwise, try to load that orientation
|
||||||
|
// radians is actually anti-clockwise, so we reverse it
|
||||||
|
double radians = -(orient) * 90 * M_PI / 180;
|
||||||
|
|
||||||
|
XftMatrix matrix;
|
||||||
|
XftMatrixInit(&matrix);
|
||||||
|
XftMatrixRotate(&matrix, cos(radians), sin(radians));
|
||||||
|
|
||||||
|
Display *disp = App::instance()->display();
|
||||||
|
|
||||||
|
XftPattern * pattern = XftNameParse(m_name.c_str());
|
||||||
|
XftPatternAddMatrix(pattern, XFT_MATRIX, &matrix);
|
||||||
|
XftResult result;
|
||||||
|
XftPattern * foundpat = XftFontMatch(disp, 0, pattern, &result);
|
||||||
|
XftPatternDestroy(pattern);
|
||||||
|
XftFont * new_font = XftFontOpenPattern(disp, foundpat);
|
||||||
|
|
||||||
|
if (new_font == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_xftfonts[orient] = new_font;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}; // end namespace FbTk
|
}; // end namespace FbTk
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include <X11/Xft/Xft.h>
|
#include <X11/Xft/Xft.h>
|
||||||
#include "FontImp.hh"
|
#include "FontImp.hh"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace FbTk {
|
namespace FbTk {
|
||||||
|
|
||||||
|
@ -35,16 +36,23 @@ public:
|
||||||
XftFontImp(const char *fontname, bool utf8);
|
XftFontImp(const char *fontname, bool utf8);
|
||||||
~XftFontImp();
|
~XftFontImp();
|
||||||
bool load(const std::string &name);
|
bool load(const std::string &name);
|
||||||
void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y) const;
|
void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y , FbTk::Orientation orient) const;
|
||||||
unsigned int textWidth(const char * const text, unsigned int len) const;
|
unsigned int textWidth(const char * const text, unsigned int len) const;
|
||||||
unsigned int height() const;
|
unsigned int height() const;
|
||||||
int ascent() const { return m_xftfont ? m_xftfont->ascent : 0; }
|
int ascent() const { return m_xftfonts[0] ? m_xftfonts[0]->ascent : 0; }
|
||||||
int descent() const { return m_xftfont ? m_xftfont->descent : 0; }
|
int descent() const { return m_xftfonts[0] ? m_xftfonts[0]->descent : 0; }
|
||||||
bool loaded() const { return m_xftfont != 0; }
|
bool loaded() const { return m_xftfonts[0] != 0; }
|
||||||
bool utf8() const { return m_utf8mode; }
|
bool utf8() const { return m_utf8mode; }
|
||||||
|
bool validOrientation(FbTk::Orientation orient);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XftFont *m_xftfont;
|
XftFont *m_xftfonts[4]; // 4 possible orientations
|
||||||
|
// rotated xft fonts don't give proper extents info, so we keep the "real"
|
||||||
|
// one around for it
|
||||||
bool m_utf8mode;
|
bool m_utf8mode;
|
||||||
|
|
||||||
|
std::string m_name;
|
||||||
|
int m_angle;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace FbTk
|
} // end namespace FbTk
|
||||||
|
|
|
@ -184,7 +184,7 @@ bool XmbFontImp::load(const std::string &fontname) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XmbFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *text,
|
void XmbFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *text,
|
||||||
size_t len, int x, int y) const {
|
size_t len, int x, int y, FbTk::Orientation orient) const {
|
||||||
|
|
||||||
if (m_fontset == 0)
|
if (m_fontset == 0)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
XmbFontImp(const char *fontname, bool utf8);
|
XmbFontImp(const char *fontname, bool utf8);
|
||||||
~XmbFontImp();
|
~XmbFontImp();
|
||||||
bool load(const std::string &name);
|
bool load(const std::string &name);
|
||||||
virtual void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y) const;
|
virtual void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const;
|
||||||
unsigned int textWidth(const char * const text, unsigned int len) const;
|
unsigned int textWidth(const char * const text, unsigned int len) const;
|
||||||
unsigned int height() const;
|
unsigned int height() const;
|
||||||
int ascent() const { return m_setextents ? -m_setextents->max_ink_extent.y : 0; }
|
int ascent() const { return m_setextents ? -m_setextents->max_ink_extent.y : 0; }
|
||||||
|
|
|
@ -41,9 +41,8 @@
|
||||||
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
|
#include <iostream>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
FbWinFrame::FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl,
|
FbWinFrame::FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl,
|
||||||
|
@ -146,26 +145,63 @@ bool FbWinFrame::setTabMode(TabMode tabmode) {
|
||||||
XUngrabButton(m_tab_container.display(), Button1, Mod1Mask|Mod2Mask|Mod3Mask, m_tab_container.window());
|
XUngrabButton(m_tab_container.display(), Button1, Mod1Mask|Mod2Mask|Mod3Mask, m_tab_container.window());
|
||||||
|
|
||||||
int tabx, taby;
|
int tabx, taby;
|
||||||
|
unsigned int maxtotal;
|
||||||
switch (m_screen.getTabPlacement()) {
|
switch (m_screen.getTabPlacement()) {
|
||||||
case TOPLEFT:
|
case TOPLEFT:
|
||||||
m_tab_container.setAlignment(Container::LEFT);
|
m_tab_container.setAlignment(Container::LEFT);
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT0);
|
||||||
tabx = x();
|
tabx = x();
|
||||||
taby = y() - yOffset();
|
taby = y() - yOffset();
|
||||||
|
maxtotal = m_window.width();
|
||||||
break;
|
break;
|
||||||
case TOPRIGHT:
|
case TOPRIGHT:
|
||||||
m_tab_container.setAlignment(Container::RIGHT);
|
m_tab_container.setAlignment(Container::RIGHT);
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT0);
|
||||||
tabx = x() + width() - m_tab_container.width();
|
tabx = x() + width() - m_tab_container.width();
|
||||||
taby = y() - yOffset();
|
taby = y() - yOffset();
|
||||||
|
maxtotal = m_window.width();
|
||||||
|
break;
|
||||||
|
case LEFTTOP:
|
||||||
|
m_tab_container.setAlignment(Container::RIGHT);
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT270);
|
||||||
|
tabx = x() - xOffset();
|
||||||
|
taby = y();
|
||||||
|
maxtotal = m_window.height();
|
||||||
|
break;
|
||||||
|
case LEFTBOTTOM:
|
||||||
|
m_tab_container.setAlignment(Container::LEFT);
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT270);
|
||||||
|
tabx = x() - xOffset();
|
||||||
|
taby = y() + height() - m_tab_container.height();
|
||||||
|
maxtotal = m_window.height();
|
||||||
|
break;
|
||||||
|
case RIGHTTOP:
|
||||||
|
m_tab_container.setAlignment(Container::LEFT);
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT90);
|
||||||
|
tabx = x() + width();
|
||||||
|
taby = y();
|
||||||
|
maxtotal = m_window.height();
|
||||||
|
break;
|
||||||
|
case RIGHTBOTTOM:
|
||||||
|
m_tab_container.setAlignment(Container::RIGHT);
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT90);
|
||||||
|
tabx = x() + width();
|
||||||
|
taby = y() + height() - m_tab_container.height();
|
||||||
|
maxtotal = m_window.height();
|
||||||
break;
|
break;
|
||||||
case BOTTOMLEFT:
|
case BOTTOMLEFT:
|
||||||
m_tab_container.setAlignment(Container::LEFT);
|
m_tab_container.setAlignment(Container::LEFT);
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT0);
|
||||||
tabx = x();
|
tabx = x();
|
||||||
taby = y() + height() + m_window.borderWidth();
|
taby = y() + height() + m_window.borderWidth();
|
||||||
|
maxtotal = m_window.width();
|
||||||
break;
|
break;
|
||||||
case BOTTOMRIGHT:
|
case BOTTOMRIGHT:
|
||||||
m_tab_container.setAlignment(Container::RIGHT);
|
m_tab_container.setAlignment(Container::RIGHT);
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT0);
|
||||||
tabx = x() + width() - m_tab_container.width();
|
tabx = x() + width() - m_tab_container.width();
|
||||||
taby = y() + height() + m_window.borderWidth();
|
taby = y() + height() + m_window.borderWidth();
|
||||||
|
maxtotal = m_window.width();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +212,7 @@ bool FbWinFrame::setTabMode(TabMode tabmode) {
|
||||||
|
|
||||||
m_tab_container.setMaxSizePerClient(m_screen.getTabWidth());
|
m_tab_container.setMaxSizePerClient(m_screen.getTabWidth());
|
||||||
m_tab_container.setUpdateLock(false);
|
m_tab_container.setUpdateLock(false);
|
||||||
m_tab_container.setMaxTotalSize(window().width());
|
m_tab_container.setMaxTotalSize(maxtotal);
|
||||||
|
|
||||||
renderTabContainer();
|
renderTabContainer();
|
||||||
applyTabContainer();
|
applyTabContainer();
|
||||||
|
@ -192,6 +228,7 @@ bool FbWinFrame::setTabMode(TabMode tabmode) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
m_tab_container.setAlignment(Container::RELATIVE);
|
m_tab_container.setAlignment(Container::RELATIVE);
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT0);
|
||||||
if (m_tab_container.parent()->window() == m_screen.rootWindow().window()) {
|
if (m_tab_container.parent()->window() == m_screen.rootWindow().window()) {
|
||||||
m_layeritem.removeWindow(m_tab_container);
|
m_layeritem.removeWindow(m_tab_container);
|
||||||
m_tab_container.reparent(m_titlebar, m_label.x(), m_label.y());
|
m_tab_container.reparent(m_titlebar, m_label.x(), m_label.y());
|
||||||
|
@ -329,8 +366,19 @@ void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int heigh
|
||||||
alignTabs();
|
alignTabs();
|
||||||
|
|
||||||
if (resize) {
|
if (resize) {
|
||||||
if (m_tabmode == EXTERNAL)
|
if (m_tabmode == EXTERNAL) {
|
||||||
m_tab_container.setMaxTotalSize(width);
|
switch(m_screen.getTabPlacement()) {
|
||||||
|
case LEFTTOP:
|
||||||
|
case RIGHTTOP:
|
||||||
|
case LEFTBOTTOM:
|
||||||
|
case RIGHTBOTTOM:
|
||||||
|
m_tab_container.setMaxTotalSize(height);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_tab_container.setMaxTotalSize(width);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
reconfigure();
|
reconfigure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,7 +387,18 @@ void FbWinFrame::quietMoveResize(int x, int y,
|
||||||
unsigned int width, unsigned int height) {
|
unsigned int width, unsigned int height) {
|
||||||
m_window.moveResize(x, y, width, height);
|
m_window.moveResize(x, y, width, height);
|
||||||
if (m_tabmode == EXTERNAL) {
|
if (m_tabmode == EXTERNAL) {
|
||||||
m_tab_container.setMaxTotalSize(width);
|
|
||||||
|
switch(m_screen.getTabPlacement()) {
|
||||||
|
case LEFTTOP:
|
||||||
|
case RIGHTTOP:
|
||||||
|
case LEFTBOTTOM:
|
||||||
|
case RIGHTBOTTOM:
|
||||||
|
m_tab_container.setMaxTotalSize(height);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_tab_container.setMaxTotalSize(width);
|
||||||
|
break;
|
||||||
|
}
|
||||||
alignTabs();
|
alignTabs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,18 +416,42 @@ void FbWinFrame::alignTabs() {
|
||||||
int tabx = 0, taby = 0;
|
int tabx = 0, taby = 0;
|
||||||
switch (m_screen.getTabPlacement()) {
|
switch (m_screen.getTabPlacement()) {
|
||||||
case TOPLEFT:
|
case TOPLEFT:
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT0);
|
||||||
tabx = x();
|
tabx = x();
|
||||||
taby = y() - yOffset();
|
taby = y() - yOffset();
|
||||||
break;
|
break;
|
||||||
case TOPRIGHT:
|
case TOPRIGHT:
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT0);
|
||||||
tabx = x() + width() - m_tab_container.width();
|
tabx = x() + width() - m_tab_container.width();
|
||||||
taby = y() - yOffset();
|
taby = y() - yOffset();
|
||||||
break;
|
break;
|
||||||
|
case LEFTTOP:
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT270);
|
||||||
|
tabx = x() - xOffset();
|
||||||
|
taby = y();
|
||||||
|
break;
|
||||||
|
case LEFTBOTTOM:
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT270);
|
||||||
|
tabx = x() - xOffset();
|
||||||
|
taby = y() + height() - m_tab_container.height();
|
||||||
|
break;
|
||||||
|
case RIGHTTOP:
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT90);
|
||||||
|
tabx = x() + width();
|
||||||
|
taby = y();
|
||||||
|
break;
|
||||||
|
case RIGHTBOTTOM:
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT90);
|
||||||
|
tabx = x() + width();
|
||||||
|
taby = y() + height() - m_tab_container.height();
|
||||||
|
break;
|
||||||
case BOTTOMLEFT:
|
case BOTTOMLEFT:
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT0);
|
||||||
tabx = x();
|
tabx = x();
|
||||||
taby = y() + height() + m_window.borderWidth();
|
taby = y() + height() + m_window.borderWidth();
|
||||||
break;
|
break;
|
||||||
case BOTTOMRIGHT:
|
case BOTTOMRIGHT:
|
||||||
|
m_tab_container.setOrientation(FbTk::ROT0);
|
||||||
tabx = x() + width() - m_tab_container.width();
|
tabx = x() + width() - m_tab_container.width();
|
||||||
taby = y() + height() + m_window.borderWidth();
|
taby = y() + height() + m_window.borderWidth();
|
||||||
break;
|
break;
|
||||||
|
@ -899,7 +982,21 @@ void FbWinFrame::reconfigure() {
|
||||||
m_titlebar.lower();
|
m_titlebar.lower();
|
||||||
|
|
||||||
if (m_tabmode == EXTERNAL) {
|
if (m_tabmode == EXTERNAL) {
|
||||||
m_tab_container.resize(m_tab_container.width(), buttonHeight());
|
unsigned int neww, newh;
|
||||||
|
switch (m_screen.getTabPlacement()) {
|
||||||
|
case TOPLEFT:
|
||||||
|
case TOPRIGHT:
|
||||||
|
case BOTTOMLEFT:
|
||||||
|
case BOTTOMRIGHT:
|
||||||
|
neww = m_tab_container.width();
|
||||||
|
newh = buttonHeight();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
neww = buttonHeight();
|
||||||
|
newh = m_tab_container.height();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_tab_container.resize(neww, newh);
|
||||||
alignTabs();
|
alignTabs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1112,23 +1209,23 @@ void FbWinFrame::renderTabContainer() {
|
||||||
|
|
||||||
render(m_theme.labelFocusTexture(), m_tabcontainer_focused_color,
|
render(m_theme.labelFocusTexture(), m_tabcontainer_focused_color,
|
||||||
m_tabcontainer_focused_pm,
|
m_tabcontainer_focused_pm,
|
||||||
m_tab_container.width(), m_tab_container.height());
|
m_tab_container.width(), m_tab_container.height(), m_tab_container.orientation());
|
||||||
|
|
||||||
render(m_theme.labelUnfocusTexture(), m_tabcontainer_unfocused_color,
|
render(m_theme.labelUnfocusTexture(), m_tabcontainer_unfocused_color,
|
||||||
m_tabcontainer_unfocused_pm,
|
m_tabcontainer_unfocused_pm,
|
||||||
m_tab_container.width(), m_tab_container.height());
|
m_tab_container.width(), m_tab_container.height(), m_tab_container.orientation());
|
||||||
|
|
||||||
render(m_theme.labelFocusTexture(), m_labelbutton_focused_color,
|
render(m_theme.labelFocusTexture(), m_labelbutton_focused_color,
|
||||||
m_labelbutton_focused_pm,
|
m_labelbutton_focused_pm,
|
||||||
m_tab_container.width(), m_tab_container.height());
|
m_tab_container.width(), m_tab_container.height(), m_tab_container.orientation());
|
||||||
|
|
||||||
render(m_theme.labelUnfocusTexture(), m_labelbutton_unfocused_color,
|
render(m_theme.labelUnfocusTexture(), m_labelbutton_unfocused_color,
|
||||||
m_labelbutton_unfocused_pm,
|
m_labelbutton_unfocused_pm,
|
||||||
m_tab_container.width(), m_tab_container.height());
|
m_tab_container.width(), m_tab_container.height(), m_tab_container.orientation());
|
||||||
|
|
||||||
render(m_theme.labelActiveTexture(), m_labelbutton_active_color,
|
render(m_theme.labelActiveTexture(), m_labelbutton_active_color,
|
||||||
m_labelbutton_active_pm,
|
m_labelbutton_active_pm,
|
||||||
m_tab_container.width(), m_tab_container.height());
|
m_tab_container.width(), m_tab_container.height(), m_tab_container.orientation());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1338,14 +1435,14 @@ void FbWinFrame::applyButton(FbTk::Button &btn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FbWinFrame::render(const FbTk::Texture &tex, FbTk::Color &col, Pixmap &pm,
|
void FbWinFrame::render(const FbTk::Texture &tex, FbTk::Color &col, Pixmap &pm,
|
||||||
unsigned int w, unsigned int h) {
|
unsigned int w, unsigned int h, FbTk::Orientation orient) {
|
||||||
|
|
||||||
Pixmap tmp = pm;
|
Pixmap tmp = pm;
|
||||||
if (!tex.usePixmap()) {
|
if (!tex.usePixmap()) {
|
||||||
pm = None;
|
pm = None;
|
||||||
col = tex.color();
|
col = tex.color();
|
||||||
} else {
|
} else {
|
||||||
pm = m_imagectrl.renderImage(w, h, tex);
|
pm = m_imagectrl.renderImage(w, h, tex, orient);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp)
|
if (tmp)
|
||||||
|
@ -1610,12 +1707,48 @@ void FbWinFrame::gravityTranslate(int &x, int &y, unsigned int width, unsigned i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FbWinFrame::heightOffset() const {
|
int FbWinFrame::widthOffset() const {
|
||||||
if (m_tabmode != EXTERNAL || !m_use_tabs)
|
if (m_tabmode != EXTERNAL || !m_use_tabs)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// same height offset for top and bottom tabs
|
// same height offset for top and bottom tabs
|
||||||
return m_tab_container.height() + m_window.borderWidth();
|
switch (m_screen.getTabPlacement()) {
|
||||||
|
case LEFTTOP:
|
||||||
|
case RIGHTTOP:
|
||||||
|
case LEFTBOTTOM:
|
||||||
|
case RIGHTBOTTOM:
|
||||||
|
return m_tab_container.width() + m_window.borderWidth();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FbWinFrame::heightOffset() const {
|
||||||
|
if (m_tabmode != EXTERNAL || !m_use_tabs)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (m_screen.getTabPlacement()) {
|
||||||
|
case TOPLEFT:
|
||||||
|
case TOPRIGHT:
|
||||||
|
case BOTTOMLEFT:
|
||||||
|
case BOTTOMRIGHT:
|
||||||
|
return m_tab_container.height() + m_window.borderWidth();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FbWinFrame::xOffset() const {
|
||||||
|
if (m_tabmode != EXTERNAL || !m_use_tabs)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (m_screen.getTabPlacement()) {
|
||||||
|
case LEFTTOP:
|
||||||
|
case LEFTBOTTOM:
|
||||||
|
return m_tab_container.width() + m_window.borderWidth();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FbWinFrame::yOffset() const {
|
int FbWinFrame::yOffset() const {
|
||||||
|
@ -1627,10 +1760,7 @@ int FbWinFrame::yOffset() const {
|
||||||
case TOPRIGHT:
|
case TOPRIGHT:
|
||||||
return m_tab_container.height() + m_window.borderWidth();
|
return m_tab_container.height() + m_window.borderWidth();
|
||||||
break;
|
break;
|
||||||
case BOTTOMLEFT:
|
|
||||||
case BOTTOMRIGHT:
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,10 +63,10 @@ public:
|
||||||
enum TabPlacement{
|
enum TabPlacement{
|
||||||
// top and bottom placement
|
// top and bottom placement
|
||||||
TOPLEFT = 1, BOTTOMLEFT,
|
TOPLEFT = 1, BOTTOMLEFT,
|
||||||
TOPRIGHT, BOTTOMRIGHT
|
TOPRIGHT, BOTTOMRIGHT,
|
||||||
// left and right placement
|
// left and right placement
|
||||||
// LEFTBOTTOM, LEFTTOP,
|
LEFTBOTTOM, LEFTTOP,
|
||||||
// RIGHTBOTTOM, RIGHTTOP
|
RIGHTBOTTOM, RIGHTTOP
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -200,9 +200,9 @@ public:
|
||||||
inline unsigned int height() const { return m_window.height(); }
|
inline unsigned int height() const { return m_window.height(); }
|
||||||
|
|
||||||
// extra bits for tabs
|
// extra bits for tabs
|
||||||
inline int xOffset() const { return 0; }
|
int xOffset() const;
|
||||||
int yOffset() const;
|
int yOffset() const;
|
||||||
inline int widthOffset() const { return 0; }
|
int widthOffset() const;
|
||||||
int heightOffset() const;
|
int heightOffset() const;
|
||||||
|
|
||||||
inline const FbTk::FbWindow &window() const { return m_window; }
|
inline const FbTk::FbWindow &window() const { return m_window; }
|
||||||
|
@ -229,7 +229,7 @@ public:
|
||||||
inline const FbTk::TextButton *currentLabel() const { return m_current_label; }
|
inline const FbTk::TextButton *currentLabel() const { return m_current_label; }
|
||||||
inline bool focused() const { return m_focused; }
|
inline bool focused() const { return m_focused; }
|
||||||
inline bool isShaded() const { return m_shaded; }
|
inline bool isShaded() const { return m_shaded; }
|
||||||
inline const FbWinFrameTheme &theme() const { return m_theme; }
|
inline FbWinFrameTheme &theme() const { return m_theme; }
|
||||||
/// @return titlebar height
|
/// @return titlebar height
|
||||||
unsigned int titlebarHeight() const { return m_titlebar.height(); }
|
unsigned int titlebarHeight() const { return m_titlebar.height(); }
|
||||||
/// @return size of button
|
/// @return size of button
|
||||||
|
@ -259,7 +259,7 @@ private:
|
||||||
|
|
||||||
/// renders to pixmap or sets color
|
/// renders to pixmap or sets color
|
||||||
void render(const FbTk::Texture &tex, FbTk::Color &col, Pixmap &pm,
|
void render(const FbTk::Texture &tex, FbTk::Color &col, Pixmap &pm,
|
||||||
unsigned int width, unsigned int height);
|
unsigned int width, unsigned int height, FbTk::Orientation orient = FbTk::ROT0);
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,6 @@ public:
|
||||||
const FbTk::Color &buttonFocuscolor() const { return *m_button_focus_color; }
|
const FbTk::Color &buttonFocuscolor() const { return *m_button_focus_color; }
|
||||||
const FbTk::Color &buttonUnfocuscolor() const { return *m_button_unfocus_color; }
|
const FbTk::Color &buttonUnfocuscolor() const { return *m_button_unfocus_color; }
|
||||||
//@}
|
//@}
|
||||||
const FbTk::Font &font() const { return *m_font; }
|
|
||||||
FbTk::Font &font() { return *m_font; }
|
FbTk::Font &font() { return *m_font; }
|
||||||
|
|
||||||
FbTk::Justify justify() const { return *m_textjustify; }
|
FbTk::Justify justify() const { return *m_textjustify; }
|
||||||
|
|
|
@ -134,7 +134,7 @@ private:
|
||||||
|
|
||||||
|
|
||||||
IconButton::IconButton(const IconbarTool& tool, const FbTk::FbWindow &parent,
|
IconButton::IconButton(const IconbarTool& tool, const FbTk::FbWindow &parent,
|
||||||
const FbTk::Font &font, FluxboxWindow &win):
|
FbTk::Font &font, FluxboxWindow &win):
|
||||||
FbTk::TextButton(parent, font, win.winClient().title()),
|
FbTk::TextButton(parent, font, win.winClient().title()),
|
||||||
m_win(win),
|
m_win(win),
|
||||||
m_icon_window(*this, 1, 1, 1, 1,
|
m_icon_window(*this, 1, 1, 1, 1,
|
||||||
|
|
|
@ -35,7 +35,7 @@ class IconbarTool;
|
||||||
class IconButton: public FbTk::TextButton, public FbTk::Observer {
|
class IconButton: public FbTk::TextButton, public FbTk::Observer {
|
||||||
public:
|
public:
|
||||||
IconButton(const IconbarTool& tool, const FbTk::FbWindow &parent,
|
IconButton(const IconbarTool& tool, const FbTk::FbWindow &parent,
|
||||||
const FbTk::Font &font, FluxboxWindow &window);
|
FbTk::Font &font, FluxboxWindow &window);
|
||||||
virtual ~IconButton();
|
virtual ~IconButton();
|
||||||
|
|
||||||
void exposeEvent(XExposeEvent &event);
|
void exposeEvent(XExposeEvent &event);
|
||||||
|
|
|
@ -41,8 +41,8 @@ public:
|
||||||
|
|
||||||
void setAntialias(bool antialias);
|
void setAntialias(bool antialias);
|
||||||
|
|
||||||
const TextTheme &focusedText() const { return m_focused_text; }
|
TextTheme &focusedText() { return m_focused_text; }
|
||||||
const TextTheme &unfocusedText() const { return m_unfocused_text; }
|
TextTheme &unfocusedText() { return m_unfocused_text; }
|
||||||
|
|
||||||
const BorderTheme &focusedBorder() const { return m_focused_border; }
|
const BorderTheme &focusedBorder() const { return m_focused_border; }
|
||||||
const BorderTheme &unfocusedBorder() const { return m_unfocused_border; }
|
const BorderTheme &unfocusedBorder() const { return m_unfocused_border; }
|
||||||
|
|
|
@ -128,7 +128,7 @@ private:
|
||||||
|
|
||||||
BScreen &m_screen;
|
BScreen &m_screen;
|
||||||
Container m_icon_container;
|
Container m_icon_container;
|
||||||
const IconbarTheme &m_theme;
|
IconbarTheme &m_theme;
|
||||||
// cached pixmaps
|
// cached pixmaps
|
||||||
Pixmap m_focused_pm, m_unfocused_pm;
|
Pixmap m_focused_pm, m_unfocused_pm;
|
||||||
// some are a fraction bigger due to rounding
|
// some are a fraction bigger due to rounding
|
||||||
|
|
|
@ -192,7 +192,6 @@ setFromString(const char *strval) {
|
||||||
m_value = FbWinFrame::TOPRIGHT;
|
m_value = FbWinFrame::TOPRIGHT;
|
||||||
else if (strcasecmp(strval, "BottomRight")==0)
|
else if (strcasecmp(strval, "BottomRight")==0)
|
||||||
m_value = FbWinFrame::BOTTOMRIGHT;
|
m_value = FbWinFrame::BOTTOMRIGHT;
|
||||||
/*
|
|
||||||
else if (strcasecmp(strval, "LeftTop") == 0)
|
else if (strcasecmp(strval, "LeftTop") == 0)
|
||||||
m_value = FbWinFrame::LEFTTOP;
|
m_value = FbWinFrame::LEFTTOP;
|
||||||
else if (strcasecmp(strval, "LeftBottom") == 0)
|
else if (strcasecmp(strval, "LeftBottom") == 0)
|
||||||
|
@ -201,7 +200,6 @@ setFromString(const char *strval) {
|
||||||
m_value = FbWinFrame::RIGHTTOP;
|
m_value = FbWinFrame::RIGHTTOP;
|
||||||
else if (strcasecmp(strval, "RightBottom") == 0)
|
else if (strcasecmp(strval, "RightBottom") == 0)
|
||||||
m_value = FbWinFrame::RIGHTBOTTOM;
|
m_value = FbWinFrame::RIGHTBOTTOM;
|
||||||
*/
|
|
||||||
else
|
else
|
||||||
setDefaultValue();
|
setDefaultValue();
|
||||||
}
|
}
|
||||||
|
@ -222,7 +220,6 @@ getString() const {
|
||||||
case FbWinFrame::BOTTOMRIGHT:
|
case FbWinFrame::BOTTOMRIGHT:
|
||||||
return string("BottomRight");
|
return string("BottomRight");
|
||||||
break;
|
break;
|
||||||
/*
|
|
||||||
case FbWinFrame::LEFTTOP:
|
case FbWinFrame::LEFTTOP:
|
||||||
return string("LeftTop");
|
return string("LeftTop");
|
||||||
break;
|
break;
|
||||||
|
@ -235,7 +232,6 @@ getString() const {
|
||||||
case FbWinFrame::RIGHTBOTTOM:
|
case FbWinFrame::RIGHTBOTTOM:
|
||||||
return string("RightBottom");
|
return string("RightBottom");
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
//default string
|
//default string
|
||||||
return string("TopLeft");
|
return string("TopLeft");
|
||||||
|
@ -1659,16 +1655,13 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
|
||||||
|
|
||||||
// menu is 2 wide, 2 down
|
// menu is 2 wide, 2 down
|
||||||
place_menu.push_back(PlacementP(_FBTEXT(Align, TopLeft, "Top Left", "Top Left"), FbWinFrame::TOPLEFT));
|
place_menu.push_back(PlacementP(_FBTEXT(Align, TopLeft, "Top Left", "Top Left"), FbWinFrame::TOPLEFT));
|
||||||
place_menu.push_back(PlacementP(_FBTEXT(Align, BottomLeft, "Bottom Left", "Bottom Left"), FbWinFrame::BOTTOMLEFT));
|
|
||||||
place_menu.push_back(PlacementP(_FBTEXT(Align, TopRight, "Top Right", "Top Right"), FbWinFrame::TOPRIGHT));
|
|
||||||
place_menu.push_back(PlacementP(_FBTEXT(Align, BottomRight, "Bottom Right", "Bottom Right"), FbWinFrame::BOTTOMRIGHT));
|
|
||||||
|
|
||||||
/*
|
|
||||||
place_menu.push_back(PlacementP(_FBTEXT(Align, LeftTop, "Left Top", "Left Top"), FbWinFrame::LEFTTOP));
|
place_menu.push_back(PlacementP(_FBTEXT(Align, LeftTop, "Left Top", "Left Top"), FbWinFrame::LEFTTOP));
|
||||||
place_menu.push_back(PlacementP(_FBTEXT(Align, LeftBottom, "Left Bottom", "Left Bottom"), FbWinFrame::LEFTBOTTOM));
|
place_menu.push_back(PlacementP(_FBTEXT(Align, LeftBottom, "Left Bottom", "Left Bottom"), FbWinFrame::LEFTBOTTOM));
|
||||||
|
place_menu.push_back(PlacementP(_FBTEXT(Align, BottomLeft, "Bottom Left", "Bottom Left"), FbWinFrame::BOTTOMLEFT));
|
||||||
|
place_menu.push_back(PlacementP(_FBTEXT(Align, TopRight, "Top Right", "Top Right"), FbWinFrame::TOPRIGHT));
|
||||||
place_menu.push_back(PlacementP(_FBTEXT(Align, RightTop, "Right Top", "Right Top"), FbWinFrame::RIGHTTOP));
|
place_menu.push_back(PlacementP(_FBTEXT(Align, RightTop, "Right Top", "Right Top"), FbWinFrame::RIGHTTOP));
|
||||||
place_menu.push_back(PlacementP(_FBTEXT(Align, RightBottom, "Right Bottom", "Right Bottom"), FbWinFrame::RIGHTBOTTOM));
|
place_menu.push_back(PlacementP(_FBTEXT(Align, RightBottom, "Right Bottom", "Right Bottom"), FbWinFrame::RIGHTBOTTOM));
|
||||||
*/
|
place_menu.push_back(PlacementP(_FBTEXT(Align, BottomRight, "Bottom Right", "Bottom Right"), FbWinFrame::BOTTOMRIGHT));
|
||||||
|
|
||||||
tabplacement_menu->setMinimumSublevels(2);
|
tabplacement_menu->setMinimumSublevels(2);
|
||||||
// create items in sub menu
|
// create items in sub menu
|
||||||
|
|
|
@ -159,7 +159,7 @@ void ToolFactory::updateThemes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ToolFactory::maxFontHeight() const {
|
int ToolFactory::maxFontHeight() {
|
||||||
unsigned int max_height = 0;
|
unsigned int max_height = 0;
|
||||||
if (max_height < m_clock_theme.font().height())
|
if (max_height < m_clock_theme.font().height())
|
||||||
max_height = m_clock_theme.font().height();
|
max_height = m_clock_theme.font().height();
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
|
|
||||||
ToolbarItem *create(const std::string &name, const FbTk::FbWindow &parent, Toolbar &tbar);
|
ToolbarItem *create(const std::string &name, const FbTk::FbWindow &parent, Toolbar &tbar);
|
||||||
void updateThemes();
|
void updateThemes();
|
||||||
int maxFontHeight() const;
|
int maxFontHeight();
|
||||||
inline const BScreen &screen() const { return m_screen; }
|
inline const BScreen &screen() const { return m_screen; }
|
||||||
inline BScreen &screen() { return m_screen; }
|
inline BScreen &screen() { return m_screen; }
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
#include "FbWinFrameTheme.hh"
|
#include "FbWinFrameTheme.hh"
|
||||||
|
|
||||||
WinButtonTheme::WinButtonTheme(int screen_num, const FbWinFrameTheme &frame_theme):
|
WinButtonTheme::WinButtonTheme(int screen_num, FbWinFrameTheme &frame_theme):
|
||||||
FbTk::Theme(screen_num),
|
FbTk::Theme(screen_num),
|
||||||
m_close_pm(*this, "window.close.pixmap", "Window.Close.Pixmap"),
|
m_close_pm(*this, "window.close.pixmap", "Window.Close.Pixmap"),
|
||||||
m_close_unfocus_pm(*this, "window.close.unfocus.pixmap", "Window.Close.Unfocus.Pixmap"),
|
m_close_unfocus_pm(*this, "window.close.unfocus.pixmap", "Window.Close.Unfocus.Pixmap"),
|
||||||
|
|
|
@ -31,7 +31,7 @@ class FbWinFrameTheme;
|
||||||
|
|
||||||
class WinButtonTheme: public FbTk::Theme {
|
class WinButtonTheme: public FbTk::Theme {
|
||||||
public:
|
public:
|
||||||
WinButtonTheme(int screen_num, const FbWinFrameTheme &frame_theme);
|
WinButtonTheme(int screen_num, FbWinFrameTheme &frame_theme);
|
||||||
~WinButtonTheme();
|
~WinButtonTheme();
|
||||||
|
|
||||||
void reconfigTheme();
|
void reconfigTheme();
|
||||||
|
@ -99,7 +99,7 @@ private:
|
||||||
FbTk::ThemeItem<FbTk::PixmapWithMask> m_stick_pm, m_stick_unfocus_pm, m_stick_pressed_pm;
|
FbTk::ThemeItem<FbTk::PixmapWithMask> m_stick_pm, m_stick_unfocus_pm, m_stick_pressed_pm;
|
||||||
FbTk::ThemeItem<FbTk::PixmapWithMask> m_stuck_pm, m_stuck_unfocus_pm;
|
FbTk::ThemeItem<FbTk::PixmapWithMask> m_stuck_pm, m_stuck_unfocus_pm;
|
||||||
|
|
||||||
const FbWinFrameTheme &m_frame_theme;
|
FbWinFrameTheme &m_frame_theme;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WINBUTTONTHEME_HH
|
#endif // WINBUTTONTHEME_HH
|
||||||
|
|
|
@ -43,6 +43,7 @@ public:
|
||||||
0, 0, 640, 480, KeyPressMask | ExposureMask) {
|
0, 0, 640, 480, KeyPressMask | ExposureMask) {
|
||||||
m_background = background;
|
m_background = background;
|
||||||
m_foreground = foreground;
|
m_foreground = foreground;
|
||||||
|
m_orient = FbTk::ROT0;
|
||||||
m_win.show();
|
m_win.show();
|
||||||
m_win.setBackgroundColor(FbTk::Color(background.c_str(), m_win.screenNumber()));
|
m_win.setBackgroundColor(FbTk::Color(background.c_str(), m_win.screenNumber()));
|
||||||
FbTk::EventManager::instance()->add(*this, m_win);
|
FbTk::EventManager::instance()->add(*this, m_win);
|
||||||
|
@ -70,43 +71,70 @@ public:
|
||||||
|
|
||||||
void redraw() {
|
void redraw() {
|
||||||
size_t text_w = m_font.textWidth(m_text.c_str(), m_text.size());
|
size_t text_w = m_font.textWidth(m_text.c_str(), m_text.size());
|
||||||
|
int mult = 1;
|
||||||
|
if (m_orient == FbTk::ROT180)
|
||||||
|
mult = -1;
|
||||||
size_t text_h = m_font.height();
|
size_t text_h = m_font.height();
|
||||||
int x = 640/2 - text_w/2;
|
int x = 640/2 - mult* text_w/2;
|
||||||
int y = 480/2 - text_h/2;
|
int y = 480/2 - mult*text_h/2;
|
||||||
m_win.clear();
|
m_win.clear();
|
||||||
FbTk::GContext wingc(m_win.drawable());
|
FbTk::GContext wingc(m_win.drawable());
|
||||||
|
|
||||||
|
int bx1 = 0;
|
||||||
|
int by1 = 0;
|
||||||
|
int bx2 = text_w;
|
||||||
|
int by2 = 0;
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
switch (m_orient) {
|
||||||
|
case FbTk::ROT90:
|
||||||
|
by2 = bx2;
|
||||||
|
bx2 = 0;
|
||||||
|
break;
|
||||||
|
case FbTk::ROT180:
|
||||||
|
bx2 = -bx2;
|
||||||
|
break;
|
||||||
|
case FbTk::ROT270:
|
||||||
|
by2 = -bx2;
|
||||||
|
bx2 = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
m_win.drawLine(wingc.gc(),
|
m_win.drawLine(wingc.gc(),
|
||||||
x, y + m_font.descent(),
|
x, y + m_font.descent(),
|
||||||
x + text_w, y + m_font.descent());
|
x + text_w, y + m_font.descent());
|
||||||
m_win.drawLine(wingc.gc(),
|
m_win.drawLine(wingc.gc(),
|
||||||
x, y - text_h,
|
x, y - text_h,
|
||||||
x + text_w, y - text_h);
|
x + text_w, y - text_h);
|
||||||
|
*/
|
||||||
|
// draw the baseline in red
|
||||||
wingc.setForeground(FbTk::Color("red", m_win.screenNumber()));
|
wingc.setForeground(FbTk::Color("red", m_win.screenNumber()));
|
||||||
m_win.drawLine(wingc.gc(),
|
m_win.drawLine(wingc.gc(),
|
||||||
x, y, x + text_w, y);
|
x + bx1, y + by1, x + bx2, y+by2);
|
||||||
wingc.setForeground(FbTk::Color(m_foreground.c_str(), m_win.screenNumber()));
|
wingc.setForeground(FbTk::Color(m_foreground.c_str(), m_win.screenNumber()));
|
||||||
//cerr<<"text width: "<<m_font.textWidth(m_text.c_str(), m_text.size())<<endl;
|
cerr<<"text size "<<text_w<<"x"<<text_h<<endl;
|
||||||
m_font.drawText(m_win,
|
m_font.drawText(m_win,
|
||||||
0, wingc.gc(),
|
0, wingc.gc(),
|
||||||
m_text.c_str(), m_text.size(),
|
m_text.c_str(), m_text.size(),
|
||||||
x, y);
|
x, y, m_orient);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FbTk::Font &font() { return m_font; }
|
FbTk::Font &font() { return m_font; }
|
||||||
void setText(const std::string& text) { m_text = text; }
|
void setText(const std::string& text, const FbTk::Orientation orient) { m_text = text; m_orient = orient; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
string m_foreground, m_background;
|
string m_foreground, m_background;
|
||||||
FbTk::FbWindow m_win;
|
FbTk::FbWindow m_win;
|
||||||
FbTk::Font m_font;
|
FbTk::Font m_font;
|
||||||
|
FbTk::Orientation m_orient;
|
||||||
string m_text;
|
string m_text;
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
//bool antialias = false;
|
//bool antialias = false;
|
||||||
bool rotate = false;
|
FbTk::Orientation orient = FbTk::ROT0;
|
||||||
bool xft = false;
|
bool xft = false;
|
||||||
string fontname("");
|
string fontname("");
|
||||||
string displayname("");
|
string displayname("");
|
||||||
|
@ -122,8 +150,8 @@ int main(int argc, char **argv) {
|
||||||
displayname = argv[++a];
|
displayname = argv[++a];
|
||||||
} else if (strcmp("-text", argv[a]) == 0 && a + 1 < argc) {
|
} else if (strcmp("-text", argv[a]) == 0 && a + 1 < argc) {
|
||||||
text = argv[++a];
|
text = argv[++a];
|
||||||
} else if (strcmp("-rotate", argv[a]) == 0) {
|
} else if (strcmp("-orient", argv[a]) == 0) {
|
||||||
rotate = true;
|
orient = (FbTk::Orientation) (atoi(argv[++a]) % 4);
|
||||||
} else if (strcmp("-bg", argv[a]) == 0 && a + 1 < argc) {
|
} else if (strcmp("-bg", argv[a]) == 0 && a + 1 < argc) {
|
||||||
background = argv[++a];
|
background = argv[++a];
|
||||||
} else if (strcmp("-fg", argv[a]) == 0 && a + 1 < argc) {
|
} else if (strcmp("-fg", argv[a]) == 0 && a + 1 < argc) {
|
||||||
|
@ -134,7 +162,7 @@ int main(int argc, char **argv) {
|
||||||
// cerr<<"-antialias"<<endl;
|
// cerr<<"-antialias"<<endl;
|
||||||
cerr<<"-display <display>"<<endl;
|
cerr<<"-display <display>"<<endl;
|
||||||
cerr<<"-text <text>"<<endl;
|
cerr<<"-text <text>"<<endl;
|
||||||
cerr<<"-rotate"<<endl;
|
cerr<<"-orient"<<endl;
|
||||||
cerr<<"-fg <foreground color>"<<endl;
|
cerr<<"-fg <foreground color>"<<endl;
|
||||||
cerr<<"-bg <background color>"<<endl;
|
cerr<<"-bg <background color>"<<endl;
|
||||||
cerr<<"-h"<<endl;
|
cerr<<"-h"<<endl;
|
||||||
|
@ -148,10 +176,12 @@ int main(int argc, char **argv) {
|
||||||
//app.font().setAntialias(antialias);
|
//app.font().setAntialias(antialias);
|
||||||
if (!app.font().load(fontname.c_str()))
|
if (!app.font().load(fontname.c_str()))
|
||||||
cerr<<"Failed to load: "<<fontname<<endl;
|
cerr<<"Failed to load: "<<fontname<<endl;
|
||||||
|
if (orient && !app.font().validOrientation(orient)) {
|
||||||
|
cerr<<"Orientation not valid ("<<orient<<")"<<endl;
|
||||||
|
orient = FbTk::ROT0;
|
||||||
|
}
|
||||||
cerr<<"Setting text: "<<text<<endl;
|
cerr<<"Setting text: "<<text<<endl;
|
||||||
app.setText(text);
|
app.setText(text, orient);
|
||||||
if (rotate)
|
|
||||||
app.font().rotate(90);
|
|
||||||
|
|
||||||
app.redraw();
|
app.redraw();
|
||||||
app.eventLoop();
|
app.eventLoop();
|
||||||
|
|
Loading…
Reference in a new issue