322 lines
6.3 KiB
C++
Raw Normal View History

/***************************************************************************
glabel.cpp
(c) 2004-2006 - Daniel Campos Fernández <dcamposf@gmail.com>
Gtkmae "GTK+ made easy" classes
Realizado para la Junta de Extremadura.
Consejería de Educación Ciencia y Tecnología.
Proyecto gnuLinEx
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************************/
#include "widgets.h"
#include "widgets_private.h"
#include "glabel.h"
static gboolean cb_expose(GtkWidget *draw, GdkEventExpose *e, gLabel *d)
{
GtkStyle *style = gtk_widget_get_style(draw);
GdkGC *gc;
int vw,vh,lw,lh;
int fw = d->getFrameWidth();
/* int width;
if (d->markup)
{
width = d->width() - fw * 2;
if (width < 0)
return false;
width *= PANGO_SCALE;
}
else
width = -1;
pango_layout_set_width(d->layout, width);*/
gc = gdk_gc_new(draw->window);
if (style)
gdk_gc_set_foreground(gc, &style->fg[GTK_STATE_NORMAL]);
switch (d->lay_x)
{
case 0: pango_layout_set_alignment(d->layout, PANGO_ALIGN_LEFT); break;
case 1: pango_layout_set_alignment(d->layout, PANGO_ALIGN_CENTER); break;
case 2: pango_layout_set_alignment(d->layout, PANGO_ALIGN_RIGHT); break;
case 3: pango_layout_set_alignment(d->layout, PANGO_ALIGN_LEFT); break;
}
gdk_drawable_get_size (draw->window, &vw, &vh);
pango_layout_get_pixel_size(d->layout, &lw, &lh);
if (!d->markup)
{
switch (d->lay_x)
{
case 0: vw=0; break;
case 1: vw=(vw/2)-(lw/2); break;
case 2: vw=vw-lw; break;
case 3: if (gtk_widget_get_default_direction()==GTK_TEXT_DIR_RTL ) vw=vw-lw;
else vw=0;
break;
}
}
else
vw=0;
switch (d->lay_y)
{
case 0: vh=0; break;
case 1: vh=(vh/2)-(lh/2); break;
case 2: vh=vh-lh; break;
}
if (vh<0) vh=0;
if (d->_transparent && d->_mask_dirty)
{
GdkBitmap *mask = gt_make_text_mask(draw->window, d->width(), d->height(), d->layout, vw + fw, vh + fw);
if (fw)
{
int i;
GdkGC *gcm = gdk_gc_new(mask);
GdkColor white;
white.pixel = 1;
gdk_gc_set_foreground(gcm, &white);
for (i = 0; i < fw; i++)
gdk_draw_rectangle(mask, gcm, false, i, i, d->width() - i * 2 - 1, d->height() - i * 2 - 1);
g_object_unref(gcm);
}
gtk_widget_shape_combine_mask(d->border, mask, 0, 0);
g_object_unref(mask);
d->_mask_dirty = false;
}
gdk_draw_layout(draw->window, gc, vw, vh, d->layout);
g_object_unref(G_OBJECT(gc));
return false;
}
gLabel::gLabel(gContainer *parent) : gControl(parent)
{
textdata = NULL;
g_typ = Type_gLabel;
markup = false;
autoresize = false;
_mask_dirty = false;
_transparent = false;
_locked = false;
border = gtk_event_box_new();
widget = gtk_event_box_new();
layout = gtk_widget_create_pango_layout(widget, "");
realize(true);
[DEVELOPMENT ENVIRONMENT] * NEW: Store the component version inside the .component files for component projects. * NEW: Package dependencies on component use the previous version stored in the .component file if it is available. Otherwise the current Gambas interpreter version is used. * BUG: Do not increment version release if the packager wizard is cancelled. * NEW: Package dependencies on component use the previous version stored in the .component file if it is available. Otherwise the current Gambas interpreter version is used. * NEW: The package wizard remembers the last directory used for storing packages. * BUG: The default directory where packages are stored is the home directory now. * BUG: Fix the signature display routine that sometimes underlined incorrectly. * BUG: Use version program at each project configuration write. * NEW: A "paste special" function in the code editor, that allows to insert plain text or HTML text from the clipboard, and can comment it, quote it as a Gambas string, or transform it into PRINT instructions. * BUG: Some fix related to the now immediate invalidity of deleted forms. [SCRIPTER] * NEW: Support for gambas server pages! * NEW: Server page are now run by a program named 'gbw2', which is just a symbolic link to 'gbs2'. [GB.GTK] * BUG: Window.Picture property now works correctly when the window is embedded inside a container. * BUG: Embedded windows having a background picture are now correctly updated when they are resized. * BUG: Correctly handle a form close or destroy during an event handler. * BUG: The combo-box behaves now like the qt one. Its first item is always selected at startup. * NEW: Now deleted forms become immediately invalid. [GB.QT] * BUG: Clipboard.Paste() now returns an UTF-8 string. * BUG: Correctly handle a form close or destroy during an event handler. * BUG: Checking if the application must quit is deferred, so that closing a form and opeing another one keeps the application running. * NEW: Now deleted forms become immediately invalid. [GB.QT.EXT] * BUG: Fix the Editor drawing while scrolling. * BUG: Fix conversion from cursor position to text column in Editor. * BUG: Fix the Editor drawing when it has been scrolled to the right. * BUG: Don't paste in Editor if there is nothing to paste. git-svn-id: svn://localhost/gambas/trunk@1605 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2008-09-26 02:25:29 +00:00
g_signal_connect_after(G_OBJECT(widget), "expose-event", G_CALLBACK(cb_expose), (gpointer)this);
[DEVELOPMENT ENVIRONMENT] * NEW: Store the component version inside the .component files for component projects. * NEW: Package dependencies on component use the previous version stored in the .component file if it is available. Otherwise the current Gambas interpreter version is used. * BUG: Do not increment version release if the packager wizard is cancelled. * NEW: Package dependencies on component use the previous version stored in the .component file if it is available. Otherwise the current Gambas interpreter version is used. * NEW: The package wizard remembers the last directory used for storing packages. * BUG: The default directory where packages are stored is the home directory now. * BUG: Fix the signature display routine that sometimes underlined incorrectly. * BUG: Use version program at each project configuration write. * NEW: A "paste special" function in the code editor, that allows to insert plain text or HTML text from the clipboard, and can comment it, quote it as a Gambas string, or transform it into PRINT instructions. * BUG: Some fix related to the now immediate invalidity of deleted forms. [SCRIPTER] * NEW: Support for gambas server pages! * NEW: Server page are now run by a program named 'gbw2', which is just a symbolic link to 'gbs2'. [GB.GTK] * BUG: Window.Picture property now works correctly when the window is embedded inside a container. * BUG: Embedded windows having a background picture are now correctly updated when they are resized. * BUG: Correctly handle a form close or destroy during an event handler. * BUG: The combo-box behaves now like the qt one. Its first item is always selected at startup. * NEW: Now deleted forms become immediately invalid. [GB.QT] * BUG: Clipboard.Paste() now returns an UTF-8 string. * BUG: Correctly handle a form close or destroy during an event handler. * BUG: Checking if the application must quit is deferred, so that closing a form and opeing another one keeps the application running. * NEW: Now deleted forms become immediately invalid. [GB.QT.EXT] * BUG: Fix the Editor drawing while scrolling. * BUG: Fix conversion from cursor position to text column in Editor. * BUG: Fix the Editor drawing when it has been scrolled to the right. * BUG: Don't paste in Editor if there is nothing to paste. git-svn-id: svn://localhost/gambas/trunk@1605 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2008-09-26 02:25:29 +00:00
updateLayout();
setAlignment(ALIGN_NORMAL);
}
gLabel::~gLabel()
{
if (textdata) g_free(textdata);
g_object_unref(G_OBJECT(layout));
}
void gLabel::updateLayout()
{
char *bpango;
if (!textdata)
pango_layout_set_text(layout,"",-1);
else
{
if (markup)
{
bpango = gt_html_to_pango_string(textdata, -1, false);
if (!bpango)
pango_layout_set_text(layout,"",-1);
else
{
pango_layout_set_markup(layout,bpango,-1);
g_free(bpango);
}
}
else
pango_layout_set_text(layout,textdata,-1);
}
gt_add_layout_from_font(layout, font());
}
void gLabel::updateSize(bool noresize)
{
gint w, h;
int fw;
if (_locked)
return;
fw = getFrameWidth();
if (markup)
{
w = width() - fw * 2;
if (w < 0)
return;
w *= PANGO_SCALE;
}
else
w = -1;
pango_layout_set_width(layout, w);
if (!autoresize || noresize)
return;
pango_layout_get_pixel_size(layout, &w, &h);
//fprintf(stderr, "gLabel::updateSize: %s (%d %d) -> (%d %d)\n", name(), width(), height(), w + fw * 2, h + fw * 2);
_locked = true;
resize(width(), h + fw * 2);
_locked = false;
}
void gLabel::adjust()
{
updateSize();
}
void gLabel::setAutoResize(bool vl)
{
autoresize = vl;
updateSize();
}
bool gLabel::autoResize()
{
return autoresize;
}
void gLabel::afterRefresh()
{
if (!_transparent)
{
gtk_widget_shape_combine_mask(border, NULL, 0, 0);
_mask_dirty = false;
}
else
_mask_dirty = true;
}
void gLabel::setTransparent(bool vl)
{
if (_transparent == vl)
return;
_transparent = vl;
refresh();
}
char *gLabel::text()
{
return textdata;
}
void gLabel::setText(char *vl)
{
g_free(textdata);
if (vl)
textdata = g_strdup(vl);
else
textdata = 0;
updateLayout();
updateSize();
refresh();
}
void gLabel::enableMarkup(bool vl)
{
if (markup != vl)
{
markup=vl;
updateSize();
refresh();
}
}
int gLabel::alignment()
{
return align;
}
void gLabel::setAlignment(int al)
{
switch (al)
{
case ALIGN_BOTTOM: lay_y=2; lay_x=1; break;
case ALIGN_BOTTOM_LEFT: lay_y=2; lay_x=0; break;
case ALIGN_BOTTOM_NORMAL: lay_y=2; lay_x=3; break;
case ALIGN_BOTTOM_RIGHT: lay_y=2; lay_x=2; break;
case ALIGN_CENTER: lay_y=1; lay_x=1; break;
case ALIGN_LEFT: lay_y=1; lay_x=0; break;
case ALIGN_NORMAL: lay_y=1; lay_x=3; break;
case ALIGN_RIGHT: lay_y=1; lay_x=2; break;
case ALIGN_TOP: lay_y=0; lay_x=1; break;
case ALIGN_TOP_LEFT: lay_y=0; lay_x=0; break;
case ALIGN_TOP_NORMAL: lay_y=0; lay_x=3; break;
case ALIGN_TOP_RIGHT: lay_y=0; lay_x=2; break;
default: return;
}
align=al;
refresh();
}
void gLabel::setFont(gFont *ft)
{
gControl::setFont(ft);
updateLayout();
updateSize();
refresh();
}
void gLabel::resize(int w, int h)
{
bool update = markup && width() != w;
gControl::resize(w, h);
if (update)
updateSize(true);
}