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)
|
||||
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:
|
||||
* Fix compile error in Theme.cc (sf.net bug #1454204)
|
||||
FbTk/Theme.cc
|
||||
|
@ -200,7 +215,6 @@ Changes for 0.9.15:
|
|||
src/ScreenResources.cc
|
||||
* Use fbsetroot in Default-Styles (Mathias)
|
||||
data/styles/*
|
||||
-------------------------------------------------------------
|
||||
Changes for 0.9.14:
|
||||
*05/09/12:
|
||||
* Fixes #1281708, MenuIcon doesnt scale properly (thanx Erik-Jan)
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
Container::Container(const FbTk::FbWindow &parent):
|
||||
FbTk::FbWindow(parent, 0, 0, 1, 1, ExposureMask),
|
||||
m_align(RELATIVE),
|
||||
m_orientation(FbTk::ROT0),
|
||||
m_max_size_per_client(60),
|
||||
m_max_total_size(0),
|
||||
m_selected(0),
|
||||
|
@ -104,6 +105,7 @@ void Container::insertItem(Item item, int pos) {
|
|||
if (item->parent() != this)
|
||||
return;
|
||||
|
||||
item->setOrientation(m_orientation);
|
||||
if (pos >= size() || pos < 0) {
|
||||
m_item_list.push_back(item);
|
||||
} else if (pos == 0) {
|
||||
|
@ -273,6 +275,9 @@ void Container::setMaxTotalSize(unsigned int size) {
|
|||
unsigned int old = m_max_total_size;
|
||||
m_max_total_size = size;
|
||||
|
||||
repositionItems();
|
||||
return;
|
||||
|
||||
if (m_max_total_size && width() > m_max_total_size) {
|
||||
resize(m_max_total_size, height());
|
||||
} else if (!m_max_total_size && old) { // going from restricted to unrestricted
|
||||
|
@ -366,13 +371,25 @@ void Container::repositionItems() {
|
|||
if (empty() || m_update_lock)
|
||||
return;
|
||||
|
||||
//!! TODO vertical position
|
||||
/**
|
||||
NOTE: all calculations here are done in non-rotated space
|
||||
*/
|
||||
|
||||
unsigned int max_width_per_client = maxWidthPerClient();
|
||||
unsigned int borderW = m_item_list.front()->borderWidth();
|
||||
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
|
||||
// within that bound
|
||||
|
@ -387,12 +404,20 @@ void Container::repositionItems() {
|
|||
} else
|
||||
max_width_per_client = 1;
|
||||
}
|
||||
if (total_width != width()) {
|
||||
|
||||
if (total_width != cur_width) {
|
||||
// calling Container::resize here risks infinite loops
|
||||
if (align == RIGHT)
|
||||
FbTk::FbWindow::moveResize(x() - (total_width - width()), y(), total_width, height());
|
||||
else
|
||||
FbTk::FbWindow::resize(total_width, height());
|
||||
unsigned int neww = total_width, newh = height;
|
||||
translateSize(m_orientation, neww, newh);
|
||||
if (align == RIGHT || m_orientation == FbTk::ROT270) {
|
||||
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;
|
||||
}
|
||||
|
||||
int tmpx, tmpy;
|
||||
unsigned int tmpw, tmph;
|
||||
for (; it != it_end; ++it, next_x += direction*(max_width_per_client + borderW + extra)) {
|
||||
// we only need to do error stuff with alignment RELATIVE
|
||||
if (rounding_error != 0 && align == RELATIVE) {
|
||||
|
@ -418,11 +445,20 @@ void Container::repositionItems() {
|
|||
} else {
|
||||
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
|
||||
(*it)->moveResize(next_x,
|
||||
-borderW,
|
||||
max_width_per_client + extra,
|
||||
height());
|
||||
(*it)->moveResize(tmpx, tmpy,
|
||||
tmpw, tmph);
|
||||
|
||||
// moveresize does a clear
|
||||
}
|
||||
|
||||
|
@ -476,3 +512,26 @@ void Container::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/EventHandler.hh"
|
||||
#include "FbTk/NotCopyable.hh"
|
||||
#include "FbTk/Text.hh" // for Orientation
|
||||
|
||||
namespace FbTk {
|
||||
class Button;
|
||||
|
@ -66,6 +67,7 @@ public:
|
|||
void setMaxSizePerClient(unsigned int size);
|
||||
void setMaxTotalSize(unsigned int size);
|
||||
void setAlignment(Alignment a);
|
||||
void setOrientation(FbTk::Orientation orient);
|
||||
|
||||
Item back() { return m_item_list.back(); }
|
||||
|
||||
|
@ -83,6 +85,7 @@ public:
|
|||
|
||||
/// accessors
|
||||
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 bool empty() const { return m_item_list.empty(); }
|
||||
inline const Item& selected() const { return m_selected; }
|
||||
|
@ -103,6 +106,8 @@ public:
|
|||
private:
|
||||
void repositionItems();
|
||||
|
||||
FbTk::Orientation m_orientation;
|
||||
|
||||
Alignment m_align;
|
||||
unsigned int m_max_size_per_client;
|
||||
unsigned int m_max_total_size;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "FbWindow.hh"
|
||||
#include "Command.hh"
|
||||
#include "Color.hh"
|
||||
#include "Text.hh"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <memory>
|
||||
|
@ -57,6 +58,7 @@ public:
|
|||
virtual void setBackgroundPixmap(Pixmap pm);
|
||||
/// sets background color
|
||||
virtual void setBackgroundColor(const Color &color);
|
||||
virtual bool setOrientation(FbTk::Orientation orient) { return orient == FbTk::ROT0; }
|
||||
|
||||
/**
|
||||
@name eventhandlers
|
||||
|
|
|
@ -201,25 +201,63 @@ void FbPixmap::copy(Pixmap pm, int depth, int screen_num) {
|
|||
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
|
||||
XImage *src_image = XGetImage(display(), drawable(),
|
||||
0, 0, // pos
|
||||
width(), height(), // size
|
||||
oldw, oldh, // size
|
||||
~0, // plane mask
|
||||
ZPixmap); // format
|
||||
// reverse height/width for new pixmap
|
||||
FbPixmap new_pm(drawable(), height(), width(), depth());
|
||||
FbPixmap new_pm(drawable(), neww, newh, depth());
|
||||
|
||||
GContext gc(drawable());
|
||||
|
||||
// copy new area
|
||||
for (unsigned int y = 0; y < height(); ++y) {
|
||||
for (unsigned int x = 0; x < width(); ++x) {
|
||||
gc.setForeground(XGetPixel(src_image, x, y));
|
||||
// revers coordinates
|
||||
XDrawPoint(display(), new_pm.drawable(), gc.gc(), y, x);
|
||||
if (orient == ROT180) {
|
||||
unsigned int srcx, srcy, destx, desty;
|
||||
for (srcy = 0, desty = oldh; srcy < oldh; ++srcy, --desty) {
|
||||
for (srcx = 0, destx = oldw; srcx < oldw; ++srcx, --destx) {
|
||||
gc.setForeground(XGetPixel(src_image, srcx, srcy));
|
||||
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
|
||||
|
||||
#include "FbDrawable.hh"
|
||||
#include "Text.hh"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
|
@ -49,8 +50,8 @@ public:
|
|||
|
||||
void copy(const FbPixmap &the_copy);
|
||||
void copy(Pixmap pixmap, int depth_convert, int screen_num);
|
||||
/// rotates the pixmap 90 deg, not implemented!
|
||||
void rotate();
|
||||
/// rotates the pixmap to specified orientation (assumes ROT0 now)
|
||||
void rotate(FbTk::Orientation orient);
|
||||
/// scales the pixmap to specified size
|
||||
void scale(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):
|
||||
m_fontimp(0),
|
||||
m_rotated(false),
|
||||
m_shadow(false), m_shadow_color("black", DefaultScreen(App::instance()->display())),
|
||||
m_shadow_offx(2), m_shadow_offy(2),
|
||||
m_halo(false), m_halo_color("white", DefaultScreen(App::instance()->display())),
|
||||
|
@ -361,9 +360,13 @@ int Font::descent() const {
|
|||
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,
|
||||
const char *text, size_t len, int x, int y,
|
||||
bool rotate) const {
|
||||
Orientation orient) const {
|
||||
if (text == 0 || len == 0)
|
||||
return;
|
||||
|
||||
|
@ -391,69 +394,26 @@ void Font::drawText(const FbDrawable &w, int screen, GC gc,
|
|||
shadow_gc.setForeground(m_shadow_color);
|
||||
first_run = false;
|
||||
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;
|
||||
} else if (m_halo) {
|
||||
FbTk::GContext halo_gc(w);
|
||||
halo_gc.setForeground(m_halo_color);
|
||||
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, rotate);
|
||||
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, 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, orient);
|
||||
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, orient);
|
||||
first_run = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rotate && isRotated()) {
|
||||
// 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);
|
||||
m_fontimp->drawText(w, screen, gc, real_text, len, x, y, orient);
|
||||
|
||||
if (rtext != 0)
|
||||
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
|
||||
|
||||
#include "Color.hh"
|
||||
#include "Text.hh"
|
||||
|
||||
namespace FbTk {
|
||||
|
||||
|
@ -89,11 +90,13 @@ public:
|
|||
unsigned int height() const;
|
||||
int ascent() const;
|
||||
int descent() const;
|
||||
|
||||
/**
|
||||
Rotate font in any angle
|
||||
(currently only 90 degrees supported and just XFont implementation)
|
||||
Returns whether we can draw this font in the given orientation.
|
||||
(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
|
||||
|
@ -108,11 +111,8 @@ public:
|
|||
*/
|
||||
void drawText(const FbDrawable &w, int screen, GC gc,
|
||||
const char *text, size_t len,
|
||||
int x, int y, bool rotate=true) 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; }
|
||||
int x, int y, FbTk::Orientation orient = ROT0) const;
|
||||
|
||||
bool hasShadow() const { return m_shadow; }
|
||||
bool hasHalo() const { return m_halo; }
|
||||
private:
|
||||
|
@ -123,8 +123,7 @@ private:
|
|||
static bool s_multibyte; ///< if the fontimp should be a multibyte font
|
||||
static bool s_utf8mode; ///< should the font use utf8 font imp
|
||||
|
||||
bool m_rotated; ///< wheter we're rotated or not
|
||||
float m_angle; ///< rotation angle
|
||||
int m_angle; ///< rotation angle
|
||||
bool m_shadow; ///< shadow text
|
||||
Color m_shadow_color; ///< shadow color
|
||||
int m_shadow_offx; ///< offset y for shadow
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#define FBTK_FONTIMP_HH
|
||||
|
||||
#include "Color.hh"
|
||||
#include "Font.hh"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
|
@ -43,13 +44,14 @@ class FontImp {
|
|||
public:
|
||||
virtual ~FontImp() { }
|
||||
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 bool validOrientation(FbTk::Orientation orient) { return orient == ROT0; }
|
||||
virtual int ascent() const = 0;
|
||||
virtual int descent() const = 0;
|
||||
virtual unsigned int height() 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; };
|
||||
protected:
|
||||
FontImp() { }
|
||||
|
|
|
@ -166,7 +166,7 @@ ImageControl::~ImageControl() {
|
|||
|
||||
|
||||
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) {
|
||||
// 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();
|
||||
for (; it != it_end; ++it) {
|
||||
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)->count++;
|
||||
return (*it)->pixmap;
|
||||
|
@ -196,6 +198,7 @@ Pixmap ImageControl::searchCache(unsigned int width, unsigned int height,
|
|||
CacheList::iterator it_end = cache.end();
|
||||
for (; it != it_end; ++it) {
|
||||
if (((*it)->width == width) &&
|
||||
((*it)->orient == orient) &&
|
||||
((*it)->height == height) &&
|
||||
((*it)->texture == text.type()) &&
|
||||
((*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,
|
||||
const FbTk::Texture &texture) {
|
||||
const FbTk::Texture &texture,
|
||||
FbTk::Orientation orient) {
|
||||
|
||||
if (texture.type() & FbTk::Texture::PARENTRELATIVE)
|
||||
return ParentRelative;
|
||||
|
||||
// search cache first
|
||||
Pixmap pixmap = searchCache(width, height, texture);
|
||||
Pixmap pixmap = searchCache(width, height, texture, orient);
|
||||
if (pixmap) {
|
||||
return pixmap; // return cache item
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
if (pixmap) {
|
||||
|
@ -239,6 +244,7 @@ Pixmap ImageControl::renderImage(unsigned int width, unsigned int height,
|
|||
|
||||
tmp->pixmap = pixmap;
|
||||
tmp->texture_pixmap = texture.pixmap().drawable();
|
||||
tmp->orient = orient;
|
||||
tmp->width = width;
|
||||
tmp->height = height;
|
||||
tmp->count = 1;
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#ifndef 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 "Timer.hh"
|
||||
#include "NotCopyable.hh"
|
||||
|
@ -61,7 +63,8 @@ public:
|
|||
@return pixmap of the rendered image, on failure None
|
||||
*/
|
||||
Pixmap renderImage(unsigned int width, unsigned int height,
|
||||
const FbTk::Texture &src_texture);
|
||||
const FbTk::Texture &src_texture,
|
||||
Orientation orient = ROT0);
|
||||
|
||||
void installRootColormap();
|
||||
void removeImage(Pixmap thepix);
|
||||
|
@ -79,7 +82,7 @@ private:
|
|||
Search cache for a specific pixmap
|
||||
@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();
|
||||
bool m_dither;
|
||||
|
@ -109,19 +112,20 @@ private:
|
|||
typedef struct Cache {
|
||||
Pixmap pixmap;
|
||||
Pixmap texture_pixmap;
|
||||
Orientation orient;
|
||||
unsigned int count, width, height;
|
||||
unsigned long pixel1, pixel2, texture;
|
||||
} Cache;
|
||||
|
||||
struct ltCacheEntry {
|
||||
bool operator()(const Cache* s1, const Cache* s2) const {
|
||||
return (s1->width < s2->width || s1->width == s2->width &&
|
||||
(s1->height < s2->height || s1->height == s2->height &&
|
||||
(s1->texture < s2->texture || s1->texture == s2->texture &&
|
||||
s1->pixel1 < s2->pixel1 || s1->pixel1 == s2->pixel1 &&
|
||||
(s1->texture & FbTk::Texture::GRADIENT) &&
|
||||
s1->pixel2 < s2->pixel2)
|
||||
));
|
||||
return (s1->orient < s2->orient || s1->orient == s2->orient
|
||||
&& (s1->width < s2->width || s1->width == s2->width
|
||||
&& (s1->height < s2->height || s1->height == s2->height
|
||||
&& (s1->texture < s2->texture || s1->texture == s2->texture
|
||||
&& (s1->pixel1 < s2->pixel1 || s1->pixel1 == s2->pixel1
|
||||
&& ((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;
|
||||
}
|
||||
|
||||
|
||||
/// specialization for Justify
|
||||
template <>
|
||||
void ThemeItem<FbTk::Justify>::setDefaultValue() {
|
||||
|
|
|
@ -29,6 +29,9 @@ namespace FbTk {
|
|||
class Font;
|
||||
|
||||
enum Justify {LEFT, RIGHT, CENTER};
|
||||
// clockwise
|
||||
enum Orientation { ROT0=0, ROT90, ROT180, ROT270 };
|
||||
|
||||
/**
|
||||
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,
|
||||
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
|
||||
|
||||
#endif // FBTK_TEXT_HH
|
||||
|
|
|
@ -28,16 +28,18 @@
|
|||
namespace FbTk {
|
||||
|
||||
TextButton::TextButton(const FbTk::FbWindow &parent,
|
||||
const FbTk::Font &font,
|
||||
FbTk::Font &font,
|
||||
const std::string &text):
|
||||
FbTk::Button(parent, 0, 0, 10, 10),
|
||||
m_font(&font),
|
||||
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_right_padding(0) {
|
||||
setRenderer(*this);
|
||||
|
||||
setRenderer(*this);
|
||||
}
|
||||
|
||||
void TextButton::resize(unsigned int width, unsigned int height) {
|
||||
|
@ -60,6 +62,23 @@ void TextButton::setJustify(FbTk::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) {
|
||||
if (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
|
||||
if (&font == m_font)
|
||||
return;
|
||||
|
@ -109,10 +128,16 @@ void TextButton::clearArea(int x, int y,
|
|||
drawText(0, 0, this);
|
||||
}
|
||||
|
||||
|
||||
unsigned int TextButton::textWidth() const {
|
||||
return font().textWidth(text().c_str(), text().size());
|
||||
}
|
||||
|
||||
unsigned int TextButton::textHeight() const {
|
||||
return font().height();
|
||||
|
||||
}
|
||||
|
||||
void TextButton::renderForeground(FbWindow &win, FbDrawable &drawable) {
|
||||
// (win should always be *this, no need to check)
|
||||
drawText(0, 0, &drawable);
|
||||
|
@ -122,7 +147,10 @@ void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) {
|
|||
unsigned int textlen = text().size();
|
||||
// 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(),
|
||||
justify(),
|
||||
font(),
|
||||
|
@ -130,17 +158,22 @@ void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) {
|
|||
textlen); // return new text lne
|
||||
|
||||
// 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)
|
||||
drawable = this;
|
||||
|
||||
// give it ROT0 style coords
|
||||
translateCoords(m_orientation, textx, texty, textw, texth);
|
||||
|
||||
font().drawText(*drawable,
|
||||
screenNumber(),
|
||||
gc(), // graphic context
|
||||
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) {
|
||||
|
|
|
@ -38,11 +38,12 @@ class Font;
|
|||
class TextButton: public FbTk::Button, FbTk::FbWindowRenderer {
|
||||
public:
|
||||
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);
|
||||
bool setOrientation(FbTk::Orientation orient);
|
||||
void setText(const std::string &text);
|
||||
void setFont(const FbTk::Font &font);
|
||||
void setFont(FbTk::Font &font);
|
||||
void setBevel(int bevel);
|
||||
void setTextPadding(unsigned int padding);
|
||||
void setTextPaddingLeft(unsigned int leftpadding);
|
||||
|
@ -65,8 +66,9 @@ public:
|
|||
|
||||
inline FbTk::Justify justify() const { return m_justify; }
|
||||
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 textHeight() const;
|
||||
int bevel() const { return m_bevel; }
|
||||
unsigned int leftPadding() const { return m_left_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);
|
||||
|
||||
private:
|
||||
const FbTk::Font *m_font;
|
||||
FbTk::Font *m_font;
|
||||
std::string m_text;
|
||||
FbTk::Justify m_justify;
|
||||
|
||||
FbTk::Orientation m_orientation;
|
||||
|
||||
int m_bevel;
|
||||
unsigned int m_left_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,
|
||||
unsigned int w, unsigned int h,
|
||||
FbTk::Orientation orient,
|
||||
XColor *_colors, size_t num_colors):
|
||||
control(imgctrl),
|
||||
colors(_colors),
|
||||
|
@ -59,6 +60,7 @@ TextureRender::TextureRender(ImageControl &imgctrl,
|
|||
cpc(imgctrl.colorsPerChannel()),
|
||||
cpccpc(cpc * cpc),
|
||||
red(0), green(0), blue(0),
|
||||
orientation(orient),
|
||||
width(static_cast<signed>((w > 0 ? w : 1))), height(static_cast<signed>(h > 0 ? h : 1)),
|
||||
xtable(0), ytable(0) {
|
||||
|
||||
|
@ -231,6 +233,9 @@ Pixmap TextureRender::renderGradient(const FbTk::Texture &texture) {
|
|||
|
||||
bool inverted = false;
|
||||
|
||||
// invert our width and height if necessary
|
||||
translateSize(orientation, width, height);
|
||||
|
||||
using namespace FbTk;
|
||||
|
||||
interlaced = texture.type() & Texture::INTERLACED;
|
||||
|
@ -281,23 +286,30 @@ Pixmap TextureRender::renderGradient(const FbTk::Texture &texture) {
|
|||
}
|
||||
|
||||
Pixmap TextureRender::renderPixmap(const FbTk::Texture &src_texture) {
|
||||
if (width != src_texture.pixmap().width() ||
|
||||
height != src_texture.pixmap().height()) {
|
||||
unsigned int tmpw = width, tmph = 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
|
||||
// scale/tile to fit our size
|
||||
FbPixmap new_pm(src_texture.pixmap());
|
||||
|
||||
if ((src_texture.type() & Texture::TILED)) {
|
||||
new_pm.tile(width,height);
|
||||
new_pm.tile(tmpw,tmph);
|
||||
} else {
|
||||
new_pm.scale(width, height);
|
||||
new_pm.scale(tmpw, tmph);
|
||||
}
|
||||
|
||||
new_pm.rotate(orientation);
|
||||
return new_pm.release();
|
||||
}
|
||||
// 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() {
|
||||
|
@ -728,6 +740,8 @@ Pixmap TextureRender::renderPixmap() {
|
|||
|
||||
XDestroyImage(image);
|
||||
|
||||
pixmap.rotate(orientation);
|
||||
|
||||
return pixmap.release();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#define FBTK_TEXTURRENDER_HH
|
||||
|
||||
#include "Texture.hh"
|
||||
#include "Text.hh"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
|
@ -43,6 +44,7 @@ class ImageControl;
|
|||
class TextureRender {
|
||||
public:
|
||||
TextureRender(ImageControl &ic, unsigned int width, unsigned int height,
|
||||
Orientation orient = ROT0,
|
||||
XColor *_colors=0, size_t num_colors=0);
|
||||
~TextureRender();
|
||||
/// render to pixmap
|
||||
|
@ -94,6 +96,7 @@ private:
|
|||
ncolors, cpc, cpccpc;
|
||||
unsigned char *red, *green, *blue;
|
||||
const unsigned char *red_table, *green_table, *blue_table;
|
||||
Orientation orientation;
|
||||
unsigned int width, height;
|
||||
unsigned int *xtable, *ytable;
|
||||
};
|
||||
|
|
|
@ -79,9 +79,10 @@ bool XFontImp::load(const std::string &fontname) {
|
|||
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)
|
||||
return;
|
||||
|
||||
// use roated font functions?
|
||||
if (m_rotfont != 0 && m_rotate) {
|
||||
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;
|
||||
}
|
||||
|
||||
void XFontImp::rotate(float angle) {
|
||||
void XFontImp::rotate(int angle) {
|
||||
//we must have a font loaded before we rotate
|
||||
if (m_fontstruct == 0 || m_fontstruct->per_char == 0)
|
||||
return;
|
||||
|
|
|
@ -38,12 +38,13 @@ public:
|
|||
bool load(const std::string &filename);
|
||||
unsigned int textWidth(const char * const text, unsigned int size) const;
|
||||
unsigned int height() const;
|
||||
float angle() const { return m_angle; }
|
||||
int angle() const { return m_angle; }
|
||||
int ascent() const;
|
||||
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; }
|
||||
void rotate(float angle);
|
||||
void rotate(int angle);
|
||||
/// enable/disable rotation witout alloc/dealloc rotfont structures
|
||||
void setRotate(bool val) { m_rotate = val; }
|
||||
private:
|
||||
|
@ -79,7 +80,7 @@ private:
|
|||
};
|
||||
XRotFontStruct *m_rotfont; ///< rotated 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
|
||||
};
|
||||
|
||||
|
|
|
@ -25,21 +25,28 @@
|
|||
#include "App.hh"
|
||||
#include "FbDrawable.hh"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif //HAVE_CONFIG_H
|
||||
|
||||
namespace FbTk {
|
||||
|
||||
XftFontImp::XftFontImp(const char *name, bool utf8):m_xftfont(0),
|
||||
m_utf8mode(utf8) {
|
||||
XftFontImp::XftFontImp(const char *name, bool utf8):
|
||||
m_utf8mode(utf8), m_name("") {
|
||||
|
||||
for (int r = ROT0; r <= ROT270; r++)
|
||||
m_xftfonts[r] = 0;
|
||||
|
||||
if (name != 0)
|
||||
load(name);
|
||||
}
|
||||
|
||||
XftFontImp::~XftFontImp() {
|
||||
if (m_xftfont != 0)
|
||||
XftFontClose(App::instance()->display(), m_xftfont);
|
||||
for (int r = ROT0; r <= ROT270; r++)
|
||||
if (m_xftfonts[r] != 0)
|
||||
XftFontClose(App::instance()->display(), m_xftfonts[r]);
|
||||
}
|
||||
|
||||
bool XftFontImp::load(const std::string &name) {
|
||||
|
@ -54,18 +61,39 @@ bool XftFontImp::load(const std::string &name) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// destroy old font and set new
|
||||
if (m_xftfont != 0)
|
||||
XftFontClose(disp, m_xftfont);
|
||||
// destroy all old fonts and set new
|
||||
for (int r = ROT0; r <= ROT270; r++)
|
||||
if (m_xftfonts[r] != 0)
|
||||
XftFontClose(App::instance()->display(), m_xftfonts[r]);
|
||||
|
||||
m_xftfont = newxftfont;
|
||||
m_xftfonts[ROT0] = newxftfont;
|
||||
m_name = name;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y) const {
|
||||
if (m_xftfont == 0)
|
||||
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_xftfonts[orient] == 0)
|
||||
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(),
|
||||
w.drawable(),
|
||||
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.
|
||||
XGlyphInfo ginfo;
|
||||
XftTextExtentsUtf8(w.display(),
|
||||
m_xftfont,
|
||||
m_xftfonts[ROT0],
|
||||
(XftChar8 *)text, len,
|
||||
&ginfo);
|
||||
if (ginfo.xOff != 0) {
|
||||
XftDrawStringUtf8(draw,
|
||||
&xftcolor,
|
||||
m_xftfont,
|
||||
font,
|
||||
x, y,
|
||||
(XftChar8 *)(text), len);
|
||||
XftColorFree(w.display(),
|
||||
|
@ -121,7 +149,7 @@ void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *te
|
|||
|
||||
XftDrawString8(draw,
|
||||
&xftcolor,
|
||||
m_xftfont,
|
||||
font,
|
||||
x, y,
|
||||
(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 {
|
||||
if (m_xftfont == 0)
|
||||
if (m_xftfonts[ROT0] == 0)
|
||||
return 0;
|
||||
|
||||
XGlyphInfo ginfo;
|
||||
Display* disp = App::instance()->display();
|
||||
|
||||
XftFont *font = m_xftfonts[ROT0];
|
||||
|
||||
|
||||
#ifdef HAVE_XFT_UTF8_STRING
|
||||
if (m_utf8mode) {
|
||||
XftTextExtentsUtf8(disp,
|
||||
m_xftfont,
|
||||
font,
|
||||
(XftChar8 *)text, len,
|
||||
&ginfo);
|
||||
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
|
||||
|
||||
XftTextExtents8(disp,
|
||||
m_xftfont,
|
||||
font,
|
||||
(XftChar8 *)text, len,
|
||||
&ginfo);
|
||||
|
||||
|
@ -161,12 +192,47 @@ unsigned int XftFontImp::textWidth(const char * const text, unsigned int len) co
|
|||
}
|
||||
|
||||
unsigned int XftFontImp::height() const {
|
||||
if (m_xftfont == 0)
|
||||
if (m_xftfonts[ROT0] == 0)
|
||||
return 0;
|
||||
return m_xftfont->height;
|
||||
else
|
||||
return m_xftfonts[ROT0]->height;
|
||||
//m_xftfont->ascent + m_xftfont->descent;
|
||||
// curiously, fonts seem to have a smaller height, but the "height"
|
||||
// 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
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <X11/Xft/Xft.h>
|
||||
#include "FontImp.hh"
|
||||
#include <string>
|
||||
|
||||
namespace FbTk {
|
||||
|
||||
|
@ -35,16 +36,23 @@ public:
|
|||
XftFontImp(const char *fontname, bool utf8);
|
||||
~XftFontImp();
|
||||
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 height() const;
|
||||
int ascent() const { return m_xftfont ? m_xftfont->ascent : 0; }
|
||||
int descent() const { return m_xftfont ? m_xftfont->descent : 0; }
|
||||
bool loaded() const { return m_xftfont != 0; }
|
||||
int ascent() const { return m_xftfonts[0] ? m_xftfonts[0]->ascent : 0; }
|
||||
int descent() const { return m_xftfonts[0] ? m_xftfonts[0]->descent : 0; }
|
||||
bool loaded() const { return m_xftfonts[0] != 0; }
|
||||
bool utf8() const { return m_utf8mode; }
|
||||
bool validOrientation(FbTk::Orientation orient);
|
||||
|
||||
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;
|
||||
|
||||
std::string m_name;
|
||||
int m_angle;
|
||||
};
|
||||
|
||||
} // 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,
|
||||
size_t len, int x, int y) const {
|
||||
size_t len, int x, int y, FbTk::Orientation orient) const {
|
||||
|
||||
if (m_fontset == 0)
|
||||
return;
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
XmbFontImp(const char *fontname, bool utf8);
|
||||
~XmbFontImp();
|
||||
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 height() const;
|
||||
int ascent() const { return m_setextents ? -m_setextents->max_ink_extent.y : 0; }
|
||||
|
|
|
@ -41,9 +41,8 @@
|
|||
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <X11/X.h>
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
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());
|
||||
|
||||
int tabx, taby;
|
||||
unsigned int maxtotal;
|
||||
switch (m_screen.getTabPlacement()) {
|
||||
case TOPLEFT:
|
||||
m_tab_container.setAlignment(Container::LEFT);
|
||||
m_tab_container.setOrientation(FbTk::ROT0);
|
||||
tabx = x();
|
||||
taby = y() - yOffset();
|
||||
maxtotal = m_window.width();
|
||||
break;
|
||||
case TOPRIGHT:
|
||||
m_tab_container.setAlignment(Container::RIGHT);
|
||||
m_tab_container.setOrientation(FbTk::ROT0);
|
||||
tabx = x() + width() - m_tab_container.width();
|
||||
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;
|
||||
case BOTTOMLEFT:
|
||||
m_tab_container.setAlignment(Container::LEFT);
|
||||
m_tab_container.setOrientation(FbTk::ROT0);
|
||||
tabx = x();
|
||||
taby = y() + height() + m_window.borderWidth();
|
||||
maxtotal = m_window.width();
|
||||
break;
|
||||
case BOTTOMRIGHT:
|
||||
m_tab_container.setAlignment(Container::RIGHT);
|
||||
m_tab_container.setOrientation(FbTk::ROT0);
|
||||
tabx = x() + width() - m_tab_container.width();
|
||||
taby = y() + height() + m_window.borderWidth();
|
||||
maxtotal = m_window.width();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -176,7 +212,7 @@ bool FbWinFrame::setTabMode(TabMode tabmode) {
|
|||
|
||||
m_tab_container.setMaxSizePerClient(m_screen.getTabWidth());
|
||||
m_tab_container.setUpdateLock(false);
|
||||
m_tab_container.setMaxTotalSize(window().width());
|
||||
m_tab_container.setMaxTotalSize(maxtotal);
|
||||
|
||||
renderTabContainer();
|
||||
applyTabContainer();
|
||||
|
@ -192,6 +228,7 @@ bool FbWinFrame::setTabMode(TabMode tabmode) {
|
|||
|
||||
} else {
|
||||
m_tab_container.setAlignment(Container::RELATIVE);
|
||||
m_tab_container.setOrientation(FbTk::ROT0);
|
||||
if (m_tab_container.parent()->window() == m_screen.rootWindow().window()) {
|
||||
m_layeritem.removeWindow(m_tab_container);
|
||||
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();
|
||||
|
||||
if (resize) {
|
||||
if (m_tabmode == EXTERNAL)
|
||||
m_tab_container.setMaxTotalSize(width);
|
||||
if (m_tabmode == EXTERNAL) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -339,7 +387,18 @@ void FbWinFrame::quietMoveResize(int x, int y,
|
|||
unsigned int width, unsigned int height) {
|
||||
m_window.moveResize(x, y, width, height);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -357,18 +416,42 @@ void FbWinFrame::alignTabs() {
|
|||
int tabx = 0, taby = 0;
|
||||
switch (m_screen.getTabPlacement()) {
|
||||
case TOPLEFT:
|
||||
m_tab_container.setOrientation(FbTk::ROT0);
|
||||
tabx = x();
|
||||
taby = y() - yOffset();
|
||||
break;
|
||||
case TOPRIGHT:
|
||||
m_tab_container.setOrientation(FbTk::ROT0);
|
||||
tabx = x() + width() - m_tab_container.width();
|
||||
taby = y() - yOffset();
|
||||
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:
|
||||
m_tab_container.setOrientation(FbTk::ROT0);
|
||||
tabx = x();
|
||||
taby = y() + height() + m_window.borderWidth();
|
||||
break;
|
||||
case BOTTOMRIGHT:
|
||||
m_tab_container.setOrientation(FbTk::ROT0);
|
||||
tabx = x() + width() - m_tab_container.width();
|
||||
taby = y() + height() + m_window.borderWidth();
|
||||
break;
|
||||
|
@ -899,7 +982,21 @@ void FbWinFrame::reconfigure() {
|
|||
m_titlebar.lower();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -1112,23 +1209,23 @@ void FbWinFrame::renderTabContainer() {
|
|||
|
||||
render(m_theme.labelFocusTexture(), m_tabcontainer_focused_color,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
unsigned int w, unsigned int h) {
|
||||
unsigned int w, unsigned int h, FbTk::Orientation orient) {
|
||||
|
||||
Pixmap tmp = pm;
|
||||
if (!tex.usePixmap()) {
|
||||
pm = None;
|
||||
col = tex.color();
|
||||
} else {
|
||||
pm = m_imagectrl.renderImage(w, h, tex);
|
||||
pm = m_imagectrl.renderImage(w, h, tex, orient);
|
||||
}
|
||||
|
||||
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)
|
||||
return 0;
|
||||
|
||||
// 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 {
|
||||
|
@ -1627,10 +1760,7 @@ int FbWinFrame::yOffset() const {
|
|||
case TOPRIGHT:
|
||||
return m_tab_container.height() + m_window.borderWidth();
|
||||
break;
|
||||
case BOTTOMLEFT:
|
||||
case BOTTOMRIGHT:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,10 +63,10 @@ public:
|
|||
enum TabPlacement{
|
||||
// top and bottom placement
|
||||
TOPLEFT = 1, BOTTOMLEFT,
|
||||
TOPRIGHT, BOTTOMRIGHT
|
||||
TOPRIGHT, BOTTOMRIGHT,
|
||||
// left and right placement
|
||||
// LEFTBOTTOM, LEFTTOP,
|
||||
// RIGHTBOTTOM, RIGHTTOP
|
||||
LEFTBOTTOM, LEFTTOP,
|
||||
RIGHTBOTTOM, RIGHTTOP
|
||||
};
|
||||
|
||||
|
||||
|
@ -200,9 +200,9 @@ public:
|
|||
inline unsigned int height() const { return m_window.height(); }
|
||||
|
||||
// extra bits for tabs
|
||||
inline int xOffset() const { return 0; }
|
||||
int xOffset() const;
|
||||
int yOffset() const;
|
||||
inline int widthOffset() const { return 0; }
|
||||
int widthOffset() const;
|
||||
int heightOffset() const;
|
||||
|
||||
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 bool focused() const { return m_focused; }
|
||||
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
|
||||
unsigned int titlebarHeight() const { return m_titlebar.height(); }
|
||||
/// @return size of button
|
||||
|
@ -259,7 +259,7 @@ private:
|
|||
|
||||
/// renders to pixmap or sets color
|
||||
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 &buttonUnfocuscolor() const { return *m_button_unfocus_color; }
|
||||
//@}
|
||||
const FbTk::Font &font() const { return *m_font; }
|
||||
FbTk::Font &font() { return *m_font; }
|
||||
|
||||
FbTk::Justify justify() const { return *m_textjustify; }
|
||||
|
|
|
@ -134,7 +134,7 @@ private:
|
|||
|
||||
|
||||
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()),
|
||||
m_win(win),
|
||||
m_icon_window(*this, 1, 1, 1, 1,
|
||||
|
|
|
@ -35,7 +35,7 @@ class IconbarTool;
|
|||
class IconButton: public FbTk::TextButton, public FbTk::Observer {
|
||||
public:
|
||||
IconButton(const IconbarTool& tool, const FbTk::FbWindow &parent,
|
||||
const FbTk::Font &font, FluxboxWindow &window);
|
||||
FbTk::Font &font, FluxboxWindow &window);
|
||||
virtual ~IconButton();
|
||||
|
||||
void exposeEvent(XExposeEvent &event);
|
||||
|
|
|
@ -41,8 +41,8 @@ public:
|
|||
|
||||
void setAntialias(bool antialias);
|
||||
|
||||
const TextTheme &focusedText() const { return m_focused_text; }
|
||||
const TextTheme &unfocusedText() const { return m_unfocused_text; }
|
||||
TextTheme &focusedText() { return m_focused_text; }
|
||||
TextTheme &unfocusedText() { return m_unfocused_text; }
|
||||
|
||||
const BorderTheme &focusedBorder() const { return m_focused_border; }
|
||||
const BorderTheme &unfocusedBorder() const { return m_unfocused_border; }
|
||||
|
|
|
@ -128,7 +128,7 @@ private:
|
|||
|
||||
BScreen &m_screen;
|
||||
Container m_icon_container;
|
||||
const IconbarTheme &m_theme;
|
||||
IconbarTheme &m_theme;
|
||||
// cached pixmaps
|
||||
Pixmap m_focused_pm, m_unfocused_pm;
|
||||
// some are a fraction bigger due to rounding
|
||||
|
|
|
@ -192,7 +192,6 @@ setFromString(const char *strval) {
|
|||
m_value = FbWinFrame::TOPRIGHT;
|
||||
else if (strcasecmp(strval, "BottomRight")==0)
|
||||
m_value = FbWinFrame::BOTTOMRIGHT;
|
||||
/*
|
||||
else if (strcasecmp(strval, "LeftTop") == 0)
|
||||
m_value = FbWinFrame::LEFTTOP;
|
||||
else if (strcasecmp(strval, "LeftBottom") == 0)
|
||||
|
@ -201,7 +200,6 @@ setFromString(const char *strval) {
|
|||
m_value = FbWinFrame::RIGHTTOP;
|
||||
else if (strcasecmp(strval, "RightBottom") == 0)
|
||||
m_value = FbWinFrame::RIGHTBOTTOM;
|
||||
*/
|
||||
else
|
||||
setDefaultValue();
|
||||
}
|
||||
|
@ -222,7 +220,6 @@ getString() const {
|
|||
case FbWinFrame::BOTTOMRIGHT:
|
||||
return string("BottomRight");
|
||||
break;
|
||||
/*
|
||||
case FbWinFrame::LEFTTOP:
|
||||
return string("LeftTop");
|
||||
break;
|
||||
|
@ -235,7 +232,6 @@ getString() const {
|
|||
case FbWinFrame::RIGHTBOTTOM:
|
||||
return string("RightBottom");
|
||||
break;
|
||||
*/
|
||||
}
|
||||
//default string
|
||||
return string("TopLeft");
|
||||
|
@ -1659,16 +1655,13 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
|
|||
|
||||
// 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, 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, 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, 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);
|
||||
// create items in sub menu
|
||||
|
|
|
@ -159,7 +159,7 @@ void ToolFactory::updateThemes() {
|
|||
}
|
||||
|
||||
|
||||
int ToolFactory::maxFontHeight() const {
|
||||
int ToolFactory::maxFontHeight() {
|
||||
unsigned int max_height = 0;
|
||||
if (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);
|
||||
void updateThemes();
|
||||
int maxFontHeight() const;
|
||||
int maxFontHeight();
|
||||
inline const BScreen &screen() const { return m_screen; }
|
||||
inline BScreen &screen() { return m_screen; }
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "FbWinFrameTheme.hh"
|
||||
|
||||
WinButtonTheme::WinButtonTheme(int screen_num, const FbWinFrameTheme &frame_theme):
|
||||
WinButtonTheme::WinButtonTheme(int screen_num, FbWinFrameTheme &frame_theme):
|
||||
FbTk::Theme(screen_num),
|
||||
m_close_pm(*this, "window.close.pixmap", "Window.Close.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 {
|
||||
public:
|
||||
WinButtonTheme(int screen_num, const FbWinFrameTheme &frame_theme);
|
||||
WinButtonTheme(int screen_num, FbWinFrameTheme &frame_theme);
|
||||
~WinButtonTheme();
|
||||
|
||||
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_stuck_pm, m_stuck_unfocus_pm;
|
||||
|
||||
const FbWinFrameTheme &m_frame_theme;
|
||||
FbWinFrameTheme &m_frame_theme;
|
||||
};
|
||||
|
||||
#endif // WINBUTTONTHEME_HH
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
0, 0, 640, 480, KeyPressMask | ExposureMask) {
|
||||
m_background = background;
|
||||
m_foreground = foreground;
|
||||
m_orient = FbTk::ROT0;
|
||||
m_win.show();
|
||||
m_win.setBackgroundColor(FbTk::Color(background.c_str(), m_win.screenNumber()));
|
||||
FbTk::EventManager::instance()->add(*this, m_win);
|
||||
|
@ -70,43 +71,70 @@ public:
|
|||
|
||||
void redraw() {
|
||||
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();
|
||||
int x = 640/2 - text_w/2;
|
||||
int y = 480/2 - text_h/2;
|
||||
int x = 640/2 - mult* text_w/2;
|
||||
int y = 480/2 - mult*text_h/2;
|
||||
m_win.clear();
|
||||
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(),
|
||||
x, y + m_font.descent(),
|
||||
x + text_w, y + m_font.descent());
|
||||
m_win.drawLine(wingc.gc(),
|
||||
x, y - text_h,
|
||||
x + text_w, y - text_h);
|
||||
*/
|
||||
// draw the baseline in red
|
||||
wingc.setForeground(FbTk::Color("red", m_win.screenNumber()));
|
||||
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()));
|
||||
//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,
|
||||
0, wingc.gc(),
|
||||
m_text.c_str(), m_text.size(),
|
||||
x, y);
|
||||
x, y, m_orient);
|
||||
|
||||
}
|
||||
|
||||
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:
|
||||
string m_foreground, m_background;
|
||||
FbTk::FbWindow m_win;
|
||||
FbTk::Font m_font;
|
||||
FbTk::Orientation m_orient;
|
||||
string m_text;
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
//bool antialias = false;
|
||||
bool rotate = false;
|
||||
FbTk::Orientation orient = FbTk::ROT0;
|
||||
bool xft = false;
|
||||
string fontname("");
|
||||
string displayname("");
|
||||
|
@ -122,8 +150,8 @@ int main(int argc, char **argv) {
|
|||
displayname = argv[++a];
|
||||
} else if (strcmp("-text", argv[a]) == 0 && a + 1 < argc) {
|
||||
text = argv[++a];
|
||||
} else if (strcmp("-rotate", argv[a]) == 0) {
|
||||
rotate = true;
|
||||
} else if (strcmp("-orient", argv[a]) == 0) {
|
||||
orient = (FbTk::Orientation) (atoi(argv[++a]) % 4);
|
||||
} else if (strcmp("-bg", argv[a]) == 0 && a + 1 < argc) {
|
||||
background = argv[++a];
|
||||
} else if (strcmp("-fg", argv[a]) == 0 && a + 1 < argc) {
|
||||
|
@ -134,7 +162,7 @@ int main(int argc, char **argv) {
|
|||
// cerr<<"-antialias"<<endl;
|
||||
cerr<<"-display <display>"<<endl;
|
||||
cerr<<"-text <text>"<<endl;
|
||||
cerr<<"-rotate"<<endl;
|
||||
cerr<<"-orient"<<endl;
|
||||
cerr<<"-fg <foreground color>"<<endl;
|
||||
cerr<<"-bg <background color>"<<endl;
|
||||
cerr<<"-h"<<endl;
|
||||
|
@ -148,10 +176,12 @@ int main(int argc, char **argv) {
|
|||
//app.font().setAntialias(antialias);
|
||||
if (!app.font().load(fontname.c_str()))
|
||||
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;
|
||||
app.setText(text);
|
||||
if (rotate)
|
||||
app.font().rotate(90);
|
||||
app.setText(text, orient);
|
||||
|
||||
app.redraw();
|
||||
app.eventLoop();
|
||||
|
|
Loading…
Reference in a new issue