2012-01-06 04:12:57 +00:00
|
|
|
// ASEPRITE gui library
|
2013-01-27 15:13:13 +00:00
|
|
|
// Copyright (C) 2001-2013 David Capello
|
2010-09-27 22:18:17 +00:00
|
|
|
//
|
2012-09-24 02:24:07 +00:00
|
|
|
// This source file is distributed under a BSD-like license, please
|
2010-09-27 22:18:17 +00:00
|
|
|
// read LICENSE.txt for more information.
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2013-08-06 00:20:19 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2009-07-12 20:29:16 +00:00
|
|
|
#include "config.h"
|
2013-08-06 00:20:19 +00:00
|
|
|
#endif
|
2009-07-12 20:29:16 +00:00
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
#include <allegro.h>
|
|
|
|
#include <allegro/internal/aintern.h>
|
|
|
|
|
2011-02-20 21:35:21 +00:00
|
|
|
#include "gfx/point.h"
|
|
|
|
#include "gfx/size.h"
|
2012-06-18 01:49:58 +00:00
|
|
|
#include "ui/draw.h"
|
|
|
|
#include "ui/font.h"
|
|
|
|
#include "ui/intern.h"
|
|
|
|
#include "ui/manager.h"
|
|
|
|
#include "ui/rect.h"
|
|
|
|
#include "ui/system.h"
|
|
|
|
#include "ui/theme.h"
|
|
|
|
#include "ui/view.h"
|
|
|
|
#include "ui/widget.h"
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2012-06-18 01:02:54 +00:00
|
|
|
namespace ui {
|
|
|
|
|
2011-01-21 20:50:04 +00:00
|
|
|
static Theme* current_theme = NULL;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2013-01-06 17:45:43 +00:00
|
|
|
static void draw_text(BITMAP *bmp, FONT *f, const char* text, int x, int y,
|
2013-05-20 23:40:18 +00:00
|
|
|
Color fg_color, Color bg_color, bool fill_bg);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2011-01-21 20:50:04 +00:00
|
|
|
Theme::Theme()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2009-11-19 02:59:20 +00:00
|
|
|
this->name = "Theme";
|
2012-01-05 22:45:03 +00:00
|
|
|
this->default_font = font; // Default Allegro font
|
2009-11-19 02:59:20 +00:00
|
|
|
this->scrollbar_size = 0;
|
2010-03-08 02:42:41 +00:00
|
|
|
this->guiscale = 1;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2011-01-21 20:50:04 +00:00
|
|
|
Theme::~Theme()
|
|
|
|
{
|
2011-04-02 14:45:43 +00:00
|
|
|
if (default_font && default_font != font)
|
|
|
|
destroy_font(default_font);
|
|
|
|
|
2011-01-21 20:50:04 +00:00
|
|
|
if (current_theme == this)
|
|
|
|
CurrentTheme::set(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Theme::regenerate()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2012-08-11 02:14:54 +00:00
|
|
|
CursorType type = jmouse_get_cursor();
|
|
|
|
jmouse_set_cursor(kNoCursor);
|
2011-01-21 20:50:04 +00:00
|
|
|
|
|
|
|
onRegenerate();
|
|
|
|
|
|
|
|
jmouse_set_cursor(type);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2011-01-21 20:50:04 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2011-01-21 20:50:04 +00:00
|
|
|
void CurrentTheme::set(Theme* theme)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2011-01-21 20:50:04 +00:00
|
|
|
current_theme = theme;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2011-01-21 20:50:04 +00:00
|
|
|
if (current_theme) {
|
|
|
|
current_theme->regenerate();
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2012-06-18 01:02:54 +00:00
|
|
|
Manager* manager = Manager::getDefault();
|
2011-01-21 21:08:25 +00:00
|
|
|
if (manager && !manager->getTheme())
|
|
|
|
manager->setTheme(theme);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-21 20:50:04 +00:00
|
|
|
Theme* CurrentTheme::get()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2011-01-21 20:50:04 +00:00
|
|
|
return current_theme;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-03-09 00:58:10 +00:00
|
|
|
BITMAP* ji_apply_guiscale(BITMAP* original)
|
|
|
|
{
|
|
|
|
int scale = jguiscale();
|
|
|
|
if (scale > 1) {
|
|
|
|
BITMAP* scaled = create_bitmap_ex(bitmap_color_depth(original),
|
2012-01-05 22:45:03 +00:00
|
|
|
original->w*scale,
|
|
|
|
original->h*scale);
|
2010-03-09 00:58:10 +00:00
|
|
|
|
|
|
|
for (int y=0; y<scaled->h; ++y)
|
|
|
|
for (int x=0; x<scaled->w; ++x)
|
2012-01-05 22:45:03 +00:00
|
|
|
putpixel(scaled, x, y, getpixel(original, x/scale, y/scale));
|
2010-03-09 00:58:10 +00:00
|
|
|
|
|
|
|
destroy_bitmap(original);
|
|
|
|
return scaled;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return original;
|
|
|
|
}
|
|
|
|
|
2013-03-30 16:38:24 +00:00
|
|
|
void drawTextBox(BITMAP* bmp, Widget* widget,
|
2013-05-20 23:40:18 +00:00
|
|
|
int* w, int* h, Color bg, Color fg)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2011-02-20 21:35:21 +00:00
|
|
|
View* view = View::getView(widget);
|
2010-01-26 00:38:05 +00:00
|
|
|
char *text = (char*)widget->getText(); // TODO warning: removing const modifier
|
2009-05-30 21:22:52 +00:00
|
|
|
char *beg, *end;
|
2007-09-18 23:57:02 +00:00
|
|
|
int x1, y1, x2, y2;
|
|
|
|
int x, y, chr, len;
|
2011-02-20 21:35:21 +00:00
|
|
|
gfx::Point scroll;
|
2007-09-18 23:57:02 +00:00
|
|
|
int viewport_w, viewport_h;
|
|
|
|
int textheight = jwidget_get_text_height(widget);
|
2010-01-26 00:38:05 +00:00
|
|
|
FONT *font = widget->getFont();
|
2007-09-18 23:57:02 +00:00
|
|
|
char *beg_end, *old_end;
|
|
|
|
int width;
|
|
|
|
|
|
|
|
if (view) {
|
2011-02-20 21:35:21 +00:00
|
|
|
gfx::Rect vp = view->getViewportBounds();
|
|
|
|
x1 = vp.x;
|
|
|
|
y1 = vp.y;
|
|
|
|
viewport_w = vp.w;
|
|
|
|
viewport_h = vp.h;
|
|
|
|
scroll = view->getViewScroll();
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-02-10 18:52:42 +00:00
|
|
|
x1 = widget->rc->x1 + widget->border_width.l;
|
|
|
|
y1 = widget->rc->y1 + widget->border_width.t;
|
|
|
|
viewport_w = jrect_w(widget->rc) - widget->border_width.l - widget->border_width.r;
|
|
|
|
viewport_h = jrect_h(widget->rc) - widget->border_width.t - widget->border_width.b;
|
2011-02-20 21:35:21 +00:00
|
|
|
scroll.x = scroll.y = 0;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
x2 = x1+viewport_w-1;
|
|
|
|
y2 = y1+viewport_h-1;
|
|
|
|
|
|
|
|
chr = 0;
|
|
|
|
|
|
|
|
/* without word-wrap */
|
2010-01-26 00:38:05 +00:00
|
|
|
if (!(widget->getAlign() & JI_WORDWRAP)) {
|
2007-09-18 23:57:02 +00:00
|
|
|
width = jrect_w(widget->rc);
|
|
|
|
}
|
|
|
|
/* with word-wrap */
|
|
|
|
else {
|
|
|
|
if (w) {
|
|
|
|
width = *w;
|
|
|
|
*w = 0;
|
|
|
|
}
|
|
|
|
else {
|
2007-12-04 21:50:31 +00:00
|
|
|
/* TODO modificable option? I don't think so, this is very internal stuff */
|
2007-09-18 23:57:02 +00:00
|
|
|
#if 0
|
|
|
|
/* shows more information in x-scroll 0 */
|
|
|
|
width = viewport_w;
|
|
|
|
#else
|
|
|
|
/* make good use of the complete text-box */
|
|
|
|
if (view) {
|
2012-01-05 22:45:03 +00:00
|
|
|
gfx::Size maxSize = view->getScrollableSize();
|
|
|
|
width = MAX(viewport_w, maxSize.w);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-01-05 22:45:03 +00:00
|
|
|
width = viewport_w;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw line-by-line */
|
2011-02-20 21:35:21 +00:00
|
|
|
y = y1 - scroll.y;
|
2007-09-18 23:57:02 +00:00
|
|
|
for (beg=end=text; end; ) {
|
2011-02-20 21:35:21 +00:00
|
|
|
x = x1 - scroll.x;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
/* without word-wrap */
|
2010-01-26 00:38:05 +00:00
|
|
|
if (!(widget->getAlign() & JI_WORDWRAP)) {
|
2008-01-07 15:10:17 +00:00
|
|
|
end = ustrchr(beg, '\n');
|
2007-09-18 23:57:02 +00:00
|
|
|
if (end) {
|
2012-01-05 22:45:03 +00:00
|
|
|
chr = *end;
|
|
|
|
*end = 0;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/* with word-wrap */
|
|
|
|
else {
|
|
|
|
old_end = NULL;
|
|
|
|
for (beg_end=beg;;) {
|
2012-01-05 22:45:03 +00:00
|
|
|
end = ustrpbrk(beg_end, " \n");
|
|
|
|
if (end) {
|
|
|
|
chr = *end;
|
|
|
|
*end = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* to here we can print */
|
|
|
|
if ((old_end) && (x+text_length(font, beg) > x1-scroll.x+width)) {
|
|
|
|
if (end)
|
|
|
|
*end = chr;
|
|
|
|
|
|
|
|
end = old_end;
|
|
|
|
chr = *end;
|
|
|
|
*end = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* we can print one word more */
|
|
|
|
else if (end) {
|
|
|
|
/* force break */
|
|
|
|
if (chr == '\n')
|
|
|
|
break;
|
|
|
|
|
|
|
|
*end = chr;
|
|
|
|
beg_end = end+1;
|
|
|
|
}
|
|
|
|
/* we are in the end of text */
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
|
|
|
|
old_end = end;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
len = text_length(font, beg);
|
|
|
|
|
|
|
|
/* render the text in the "bmp" */
|
|
|
|
if (bmp) {
|
|
|
|
int xout;
|
|
|
|
|
2010-01-26 00:38:05 +00:00
|
|
|
if (widget->getAlign() & JI_CENTER)
|
2012-01-05 22:45:03 +00:00
|
|
|
xout = x + width/2 - len/2;
|
2010-01-26 00:38:05 +00:00
|
|
|
else if (widget->getAlign() & JI_RIGHT)
|
2012-01-05 22:45:03 +00:00
|
|
|
xout = x + width - len;
|
|
|
|
else /* left */
|
|
|
|
xout = x;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2009-08-17 18:00:38 +00:00
|
|
|
draw_text(bmp, font, beg, xout, y, fg, bg, true);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2008-02-29 19:29:49 +00:00
|
|
|
jrectexclude(bmp,
|
2012-01-05 22:45:03 +00:00
|
|
|
x1, y, x2, y+textheight-1,
|
|
|
|
xout, y, xout+len-1, y+textheight-1, bg);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* width */
|
|
|
|
if (w)
|
2008-01-07 15:10:17 +00:00
|
|
|
*w = MAX(*w, len);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
y += textheight;
|
|
|
|
|
|
|
|
if (end) {
|
|
|
|
*end = chr;
|
|
|
|
beg = end+1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* height */
|
|
|
|
if (h)
|
2011-02-20 21:35:21 +00:00
|
|
|
*h = (y-y1+scroll.y);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2008-02-10 18:52:42 +00:00
|
|
|
if (w) *w += widget->border_width.l + widget->border_width.r;
|
|
|
|
if (h) *h += widget->border_width.t + widget->border_width.b;
|
|
|
|
|
2013-01-06 17:45:43 +00:00
|
|
|
// Fill bottom area
|
2007-09-18 23:57:02 +00:00
|
|
|
if (bmp) {
|
|
|
|
if (y <= y2)
|
2013-01-06 17:45:43 +00:00
|
|
|
rectfill(bmp, x1, y, x2, y2, to_system(bg));
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void draw_text(BITMAP *bmp, FONT *f, const char *text, int x, int y,
|
2013-05-20 23:40:18 +00:00
|
|
|
Color fg_color, Color bg_color, bool fill_bg)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2013-01-06 17:45:43 +00:00
|
|
|
// TODO Optional anti-aliased textout
|
|
|
|
ji_font_set_aa_mode(f, to_system(bg_color));
|
|
|
|
textout_ex(bmp, f, text, x, y, to_system(fg_color), (fill_bg ? to_system(bg_color): -1));
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
2012-06-18 01:02:54 +00:00
|
|
|
|
|
|
|
} // namespace ui
|