rotated fonts, buttons, containers. Used for tabs for now

This commit is contained in:
simonb 2006-03-26 04:02:30 +00:00
parent 872f6a0e1e
commit af74a22845
36 changed files with 658 additions and 212 deletions

View file

@ -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)

View file

@ -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();
}
}

View file

@ -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;

View file

@ -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

View file

@ -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);
}
} }
} }

View file

@ -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);

View file

@ -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;
*/
}
}; };

View file

@ -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

View file

@ -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() { }

View file

@ -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;

View file

@ -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)
)); )))));
} }
}; };

View file

@ -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() {

View file

@ -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

View file

@ -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) {

View file

@ -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

View file

@ -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();
} }

View file

@ -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;
}; };

View file

@ -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;

View file

@ -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
}; };

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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; }

View file

@ -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;
} }

View file

@ -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);
//@} //@}

View file

@ -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; }

View file

@ -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,

View file

@ -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);

View file

@ -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; }

View file

@ -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

View file

@ -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

View file

@ -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();

View file

@ -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; }

View file

@ -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"),

View file

@ -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

View file

@ -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();